From a55304a6fd31bb558967776c7a16d6c9e226b35a Mon Sep 17 00:00:00 2001 From: Tu Truong Date: Fri, 18 May 2012 18:24:46 -0700 Subject: [PATCH] "Initial commit to Gerrit" --- AUTHORS | 9 + COPYING | 38 + INSTALL | 222 + Makefile.am | 939 + Makefile.in | 2396 +++ NEWS | 588 + README | 120 + TODO | 224 + Tachometer.h | 52 + TachometerP.h | 44 + aclocal.m4 | 9309 ++++++++++ ais_json.c | 154 + autogen.sh | 140 + bits.c | 90 + bits.h | 91 + bsd-base64.c | 315 + bsd-base64.h | 18 + cgps.c | 932 + config.guess | 1533 ++ config.sub | 1693 ++ configure | 21078 +++++++++++++++++++++++ configure.ac | 1120 ++ crc24q.c | 177 + crc24q.h | 15 + debian/changelog | 65 + debian/compat | 1 + debian/control | 59 + debian/gpsd.install | 1 + debian/gpsd.postinst | 21 + debian/gpsd.preinst | 38 + debian/libgps-dev.install | 4 + debian/libgps19.install | 1 + debian/rules | 122 + depcomp | 630 + dgpsip-servers | 10 + do-tests | 3 + driver_aivdm.c | 842 + driver_evermore.c | 645 + driver_garmin.c | 1469 ++ driver_garmin_txt.c | 474 + driver_italk.c | 525 + driver_italk.h | 544 + driver_navcom.c | 1342 ++ driver_nmea.c | 1158 ++ driver_oncore.c | 547 + driver_proto.c | 560 + driver_rtcm2.c | 356 + driver_rtcm2.h | 499 + driver_rtcm3.c | 928 + driver_sirf.c | 1380 ++ driver_superstar2.c | 617 + driver_superstar2.h | 62 + driver_tsip.c | 1183 ++ driver_ubx.c | 789 + driver_ubx.h | 120 + driver_zodiac.c | 507 + drivers.c | 1218 ++ geoid.c | 151 + gps.h | 1118 ++ gps.xml | 312 + gps/__init__.py | 13 + gps/client.py | 202 + gps/fake.py | 593 + gps/gps.py | 374 + gps/misc.py | 101 + gps_json.h | 43 + gpscap.ini | 2031 +++ gpscap.py | 151 + gpscat | 132 + gpscat.xml | 135 + gpsclient.c | 84 + gpsctl.c | 673 + gpsctl.xml | 261 + gpsd.c | 2070 +++ gpsd.h-head | 14 + gpsd.h-tail | 665 + gpsd.hotplug | 123 + gpsd.hotplug.wrapper | 47 + gpsd.php | 582 + gpsd.rules | 44 + gpsd.usermap | 19 + gpsd.xml | 1923 +++ gpsd_config.h | 396 + gpsd_config.h.in | 395 + gpsd_dbus.c | 77 + gpsd_dbus.h | 19 + gpsd_json.c | 1437 ++ gpsd_report.c | 24 + gpsdclient.c | 188 + gpsdclient.h | 30 + gpsdecode.c | 509 + gpsdecode.xml | 204 + gpsfake | 207 + gpsfake.xml | 192 + gpsmon.c | 989 ++ gpsmon.h | 38 + gpsmon.xml | 369 + gpspacket.c | 270 + gpspipe.c | 408 + gpspipe.xml | 151 + gpsprof | 494 + gpsprof.xml | 181 + gpsutils.c | 577 + gpxlogger.c | 417 + hex.c | 272 + install-sh | 520 + isgps.c | 319 + json.c | 593 + json.h | 123 + jsongen.py.in | 534 + lcdgps.c | 547 + libQgpsmm/gpsutils.cpp | 3 + libQgpsmm/libQgpsmm.pro | 98 + libQgpsmm/libQgpsmm_global.h | 12 + libQgpsmm/libgps_core.cpp | 3 + libQgpsmm/mingw/ais_json.i | 503 + libQgpsmm/mingw/gpsd_config.h | 260 + libQgpsmm/mingw/test_qgpsmm.pro | 18 + libQgpsmm/mingw/version.h | 1 + libQgpsmm/mingw/version.pri | 1 + libgps.pc.in | 9 + libgps.xml | 343 + libgps_core.c | 851 + libgps_json.c | 411 + libgpsd.pc.in | 9 + libgpsd.xml | 167 + libgpsd_core.c | 850 + libgpsmm.cpp | 81 + libgpsmm.h | 38 + libgpsmm.xml | 87 + ltmain.sh | 8413 +++++++++ maskaudit.py.in | 124 + missing | 376 + monitor_italk.c | 264 + monitor_nmea.c | 460 + monitor_oncore.c | 478 + monitor_proto.c | 163 + monitor_sirf.c | 743 + monitor_superstar2.c | 124 + monitor_tnt.c | 147 + monitor_ubx.c | 265 + net_dgpsip.c | 173 + net_gnss_dispatch.c | 120 + net_ntrip.c | 519 + netlib.c | 204 + ntpshm.c | 343 + packaging/X11/gpsd-logo.png | Bin 0 -> 16518 bytes packaging/X11/xgps.desktop | 10 + packaging/X11/xgpsspeed.desktop | 10 + packaging/deb/etc_default_gpsd | 8 + packaging/deb/etc_init.d_gpsd | 160 + packaging/gpsd.changes | 2 + packaging/gpsd.spec | 91 + packaging/rpm/gpsd.init | 93 + packaging/rpm/gpsd.spec | 370 + packaging/rpm/gpsd.spec.in | 370 + packaging/rpm/gpsd.sysconfig | 3 + packet.c | 1805 ++ packet_states.h | 170 + pseudonmea.c | 270 + py-compile | 146 + regress-driver | 155 + rtcm-104.xml | 509 + rtcm2_json.c | 225 + serial.c | 518 + setup.py | 82 + shared_json.c | 100 + sockaddr.h | 9 + srec.xml | 310 + srecord.c | 138 + strl.c | 118 + subframe.c | 222 + test/README | 13 + test/clientlib/multipacket.log | 2 + test/clientlib/multipacket.log.chk | 4 + test/clientlib/oldstyle.log | 2 + test/clientlib/oldstyle.log.chk | 9 + test/daemon/ac12.log | 60 + test/daemon/ac12.log.chk | 67 + test/daemon/ac12_binary.log | Bin 0 -> 25807 bytes test/daemon/ac12_binary.log.chk | Bin 0 -> 53017 bytes test/daemon/ait250.log | 155 + test/daemon/ait250.log.chk | 215 + test/daemon/blumax-gps009.log | 83 + test/daemon/blumax-gps009.log.chk | 83 + test/daemon/bn-9015.log | 534 + test/daemon/bn-9015.log.chk | 676 + test/daemon/bt-q818.log | 178 + test/daemon/bt-q818.log.chk | 226 + test/daemon/bt451.log | 1045 ++ test/daemon/bt451.log.chk | 1355 ++ test/daemon/bu303-climbing.log | Bin 0 -> 12942 bytes test/daemon/bu303-climbing.log.chk | 199 + test/daemon/bu303-moving.log | Bin 0 -> 13882 bytes test/daemon/bu303-moving.log.chk | 217 + test/daemon/bu303-nofix.log | Bin 0 -> 3490 bytes test/daemon/bu303-nofix.log.chk | 28 + test/daemon/bu303-stillfix.log | Bin 0 -> 5198 bytes test/daemon/bu303-stillfix.log.chk | 77 + test/daemon/bu303b-nofix.log | Bin 0 -> 3205 bytes test/daemon/bu303b-nofix.log.chk | 25 + test/daemon/ch-4701.log | 1101 ++ test/daemon/ch-4701.log.chk | 1372 ++ test/daemon/ch-4711.log | 234 + test/daemon/ch-4711.log.chk | 268 + test/daemon/com-1289.log | 416 + test/daemon/com-1289.log.chk | 522 + test/daemon/eXplorist210.log | 61 + test/daemon/eXplorist210.log.chk | 54 + test/daemon/et-332.log | 368 + test/daemon/et-332.log.chk | 341 + test/daemon/firefly-II.log | 248 + test/daemon/firefly-II.log.chk | 243 + test/daemon/garmin-geko201.log | 223 + test/daemon/garmin-geko201.log.chk | 232 + test/daemon/garmin17n.log | 31 + test/daemon/garmin17n.log.chk | 28 + test/daemon/garmin25lp.log | 114 + test/daemon/garmin25lp.log.chk | 146 + test/daemon/garmin38.log | 70 + test/daemon/garmin38.log.chk | 74 + test/daemon/garmin48.log | 106 + test/daemon/garmin48.log.chk | 113 + test/daemon/gps-360.log | 259 + test/daemon/gps-360.log.chk | 316 + test/daemon/gpslim236.log | 176 + test/daemon/gpslim236.log.chk | 223 + test/daemon/haicom-305N.log | 335 + test/daemon/haicom-305N.log.chk | 423 + test/daemon/holux-gm-210.log | 48 + test/daemon/holux-gm-210.log.chk | 53 + test/daemon/humminbird-M37.log | 1044 ++ test/daemon/humminbird-M37.log.chk | 1378 ++ test/daemon/iTrek.log | 117 + test/daemon/iTrek.log.chk | 153 + test/daemon/italk-binary.log | Bin 0 -> 31844 bytes test/daemon/italk-binary.log.chk | 201 + test/daemon/magellan-ec10.log | 87 + test/daemon/magellan-ec10.log.chk | 97 + test/daemon/magellan315.log | 28 + test/daemon/magellan315.log.chk | 30 + test/daemon/mkt-3301.log | 76 + test/daemon/mkt-3301.log.chk | 67 + test/daemon/motorola-t805.log | 65 + test/daemon/motorola-t805.log.chk | 67 + test/daemon/navcom.log | Bin 0 -> 15167 bytes test/daemon/navcom.log.chk | 197 + test/daemon/nl402u.log | 264 + test/daemon/nl402u.log.chk | 320 + test/daemon/nokia-ld-4w.log | 189 + test/daemon/nokia-ld-4w.log.chk | 238 + test/daemon/oncore.log | 53 + test/daemon/oncore.log.chk | 60 + test/daemon/pharos-360.log | 259 + test/daemon/pharos-360.log.chk | 316 + test/daemon/rgm3800.log | 46 + test/daemon/rgm3800.log.chk | 31 + test/daemon/rtcm2.log | 10 + test/daemon/rtcm2.log.chk | 5 + test/daemon/superstar2.log | Bin 0 -> 24044 bytes test/daemon/superstar2.log.chk | 756 + test/daemon/tn200-all.log | 419 + test/daemon/tn200-all.log.chk | 409 + test/daemon/tn200.log | 227 + test/daemon/tn200.log.chk | 277 + test/daemon/tn204.log | 58 + test/daemon/tn204.log.chk | 59 + test/daemon/tnt-revolution.log | 71 + test/daemon/tnt-revolution.log.chk | 100 + test/daemon/tomtom-mkII.log | 72 + test/daemon/tomtom-mkII.log.chk | 73 + test/daemon/trimble-lassen_iq-3dfix.log | Bin 0 -> 7562 bytes test/daemon/trimble-lassen_iq-3dfix.log.chk | 212 + test/daemon/trimble-lassen_iq-playacar.log | Bin 0 -> 4483 bytes test/daemon/trimble-lassen_iq-playacar.log.chk | 80 + test/daemon/trimble-lassen_iq.log | Bin 0 -> 10333 bytes test/daemon/trimble-lassen_iq.log.chk | 260 + test/daemon/uBlox-aek-4t.log | Bin 0 -> 14729 bytes test/daemon/uBlox-aek-4t.log.chk | 70 + test/daemon/uBlox-lea-4h.log | 380 + test/daemon/uBlox-lea-4h.log.chk | 449 + test/daemon/uBlox-lea-4s.log | 36 + test/daemon/uBlox-lea-4s.log.chk | 36 + test/daemon/uBlox-lea-4t.log | Bin 0 -> 32600 bytes test/daemon/uBlox-lea-4t.log.chk | 225 + test/daemon/uBlox-sirf1.log | Bin 0 -> 17490 bytes test/daemon/uBlox-sirf1.log.chk | 316 + test/daemon/venus634lp.log | 727 + test/daemon/venus634lp.log.chk | 902 + test/daemon/zodiac.log | Bin 0 -> 5686 bytes test/daemon/zodiac.log.chk | 126 + test/earthmate | Bin 0 -> 1596 bytes test/geoid.test.chk | 1 + test/packet.test.chk | 24 + test/sample.aivdm | 693 + test/sample.aivdm.chk | 45 + test/sample.rtcm2 | 9 + test/sample.rtcm2.chk | 611 + test/synthetic-ais.json | 48 + test/synthetic-rtcm2.json | 14 + test_bits.c | 206 + test_float.c | 259 + test_geoid.c | 40 + test_gpsmm.cpp | 77 + test_json.c | 295 + test_mkgmtime.c | 114 + test_packet.c | 350 + test_trig.c | 55 + timebase.h | 51 + valgrind-audit | 101 + valgrind-audit.in | 101 + valgrind-suppressions | 22 + xgps | 682 + xgpsspeed | 455 + 314 files changed, 132355 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100644 Tachometer.h create mode 100644 TachometerP.h create mode 100644 aclocal.m4 create mode 100644 ais_json.c create mode 100755 autogen.sh create mode 100644 bits.c create mode 100644 bits.h create mode 100644 bsd-base64.c create mode 100644 bsd-base64.h create mode 100644 cgps.c create mode 100755 config.guess create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.ac create mode 100644 crc24q.c create mode 100644 crc24q.h create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/gpsd.install create mode 100644 debian/gpsd.postinst create mode 100644 debian/gpsd.preinst create mode 100644 debian/libgps-dev.install create mode 100644 debian/libgps19.install create mode 100755 debian/rules create mode 100755 depcomp create mode 100644 dgpsip-servers create mode 100755 do-tests create mode 100644 driver_aivdm.c create mode 100644 driver_evermore.c create mode 100644 driver_garmin.c create mode 100644 driver_garmin_txt.c create mode 100644 driver_italk.c create mode 100644 driver_italk.h create mode 100644 driver_navcom.c create mode 100644 driver_nmea.c create mode 100644 driver_oncore.c create mode 100644 driver_proto.c create mode 100644 driver_rtcm2.c create mode 100644 driver_rtcm2.h create mode 100644 driver_rtcm3.c create mode 100644 driver_sirf.c create mode 100644 driver_superstar2.c create mode 100644 driver_superstar2.h create mode 100644 driver_tsip.c create mode 100644 driver_ubx.c create mode 100644 driver_ubx.h create mode 100644 driver_zodiac.c create mode 100644 drivers.c create mode 100644 geoid.c create mode 100644 gps.h create mode 100644 gps.xml create mode 100644 gps/__init__.py create mode 100644 gps/client.py create mode 100644 gps/fake.py create mode 100755 gps/gps.py create mode 100644 gps/misc.py create mode 100644 gps_json.h create mode 100644 gpscap.ini create mode 100644 gpscap.py create mode 100755 gpscat create mode 100644 gpscat.xml create mode 100644 gpsclient.c create mode 100644 gpsctl.c create mode 100644 gpsctl.xml create mode 100644 gpsd.c create mode 100644 gpsd.h-head create mode 100644 gpsd.h-tail create mode 100755 gpsd.hotplug create mode 100644 gpsd.hotplug.wrapper create mode 100644 gpsd.php create mode 100644 gpsd.rules create mode 100644 gpsd.usermap create mode 100644 gpsd.xml create mode 100644 gpsd_config.h create mode 100644 gpsd_config.h.in create mode 100644 gpsd_dbus.c create mode 100644 gpsd_dbus.h create mode 100644 gpsd_json.c create mode 100644 gpsd_report.c create mode 100644 gpsdclient.c create mode 100644 gpsdclient.h create mode 100644 gpsdecode.c create mode 100644 gpsdecode.xml create mode 100755 gpsfake create mode 100644 gpsfake.xml create mode 100644 gpsmon.c create mode 100644 gpsmon.h create mode 100644 gpsmon.xml create mode 100644 gpspacket.c create mode 100644 gpspipe.c create mode 100644 gpspipe.xml create mode 100755 gpsprof create mode 100644 gpsprof.xml create mode 100644 gpsutils.c create mode 100644 gpxlogger.c create mode 100644 hex.c create mode 100755 install-sh create mode 100644 isgps.c create mode 100644 json.c create mode 100644 json.h create mode 100644 jsongen.py.in create mode 100644 lcdgps.c create mode 100644 libQgpsmm/gpsutils.cpp create mode 100644 libQgpsmm/libQgpsmm.pro create mode 100644 libQgpsmm/libQgpsmm_global.h create mode 100644 libQgpsmm/libgps_core.cpp create mode 100644 libQgpsmm/mingw/ais_json.i create mode 100644 libQgpsmm/mingw/gpsd_config.h create mode 100644 libQgpsmm/mingw/test_qgpsmm.pro create mode 100644 libQgpsmm/mingw/version.h create mode 100644 libQgpsmm/mingw/version.pri create mode 100644 libgps.pc.in create mode 100644 libgps.xml create mode 100644 libgps_core.c create mode 100644 libgps_json.c create mode 100644 libgpsd.pc.in create mode 100644 libgpsd.xml create mode 100644 libgpsd_core.c create mode 100644 libgpsmm.cpp create mode 100644 libgpsmm.h create mode 100644 libgpsmm.xml create mode 100755 ltmain.sh create mode 100644 maskaudit.py.in create mode 100755 missing create mode 100644 monitor_italk.c create mode 100644 monitor_nmea.c create mode 100644 monitor_oncore.c create mode 100644 monitor_proto.c create mode 100644 monitor_sirf.c create mode 100644 monitor_superstar2.c create mode 100644 monitor_tnt.c create mode 100644 monitor_ubx.c create mode 100644 net_dgpsip.c create mode 100644 net_gnss_dispatch.c create mode 100644 net_ntrip.c create mode 100644 netlib.c create mode 100644 ntpshm.c create mode 100644 packaging/X11/gpsd-logo.png create mode 100644 packaging/X11/xgps.desktop create mode 100644 packaging/X11/xgpsspeed.desktop create mode 100644 packaging/deb/etc_default_gpsd create mode 100644 packaging/deb/etc_init.d_gpsd create mode 100644 packaging/gpsd.changes create mode 100644 packaging/gpsd.spec create mode 100644 packaging/rpm/gpsd.init create mode 100644 packaging/rpm/gpsd.spec create mode 100644 packaging/rpm/gpsd.spec.in create mode 100644 packaging/rpm/gpsd.sysconfig create mode 100644 packet.c create mode 100644 packet_states.h create mode 100644 pseudonmea.c create mode 100755 py-compile create mode 100755 regress-driver create mode 100644 rtcm-104.xml create mode 100644 rtcm2_json.c create mode 100644 serial.c create mode 100644 setup.py create mode 100644 shared_json.c create mode 100644 sockaddr.h create mode 100644 srec.xml create mode 100644 srecord.c create mode 100644 strl.c create mode 100644 subframe.c create mode 100644 test/README create mode 100644 test/clientlib/multipacket.log create mode 100644 test/clientlib/multipacket.log.chk create mode 100644 test/clientlib/oldstyle.log create mode 100644 test/clientlib/oldstyle.log.chk create mode 100644 test/daemon/ac12.log create mode 100644 test/daemon/ac12.log.chk create mode 100644 test/daemon/ac12_binary.log create mode 100644 test/daemon/ac12_binary.log.chk create mode 100644 test/daemon/ait250.log create mode 100644 test/daemon/ait250.log.chk create mode 100644 test/daemon/blumax-gps009.log create mode 100644 test/daemon/blumax-gps009.log.chk create mode 100644 test/daemon/bn-9015.log create mode 100644 test/daemon/bn-9015.log.chk create mode 100644 test/daemon/bt-q818.log create mode 100644 test/daemon/bt-q818.log.chk create mode 100644 test/daemon/bt451.log create mode 100644 test/daemon/bt451.log.chk create mode 100644 test/daemon/bu303-climbing.log create mode 100644 test/daemon/bu303-climbing.log.chk create mode 100644 test/daemon/bu303-moving.log create mode 100644 test/daemon/bu303-moving.log.chk create mode 100644 test/daemon/bu303-nofix.log create mode 100644 test/daemon/bu303-nofix.log.chk create mode 100644 test/daemon/bu303-stillfix.log create mode 100644 test/daemon/bu303-stillfix.log.chk create mode 100644 test/daemon/bu303b-nofix.log create mode 100644 test/daemon/bu303b-nofix.log.chk create mode 100644 test/daemon/ch-4701.log create mode 100644 test/daemon/ch-4701.log.chk create mode 100644 test/daemon/ch-4711.log create mode 100644 test/daemon/ch-4711.log.chk create mode 100644 test/daemon/com-1289.log create mode 100644 test/daemon/com-1289.log.chk create mode 100644 test/daemon/eXplorist210.log create mode 100644 test/daemon/eXplorist210.log.chk create mode 100644 test/daemon/et-332.log create mode 100644 test/daemon/et-332.log.chk create mode 100644 test/daemon/firefly-II.log create mode 100644 test/daemon/firefly-II.log.chk create mode 100644 test/daemon/garmin-geko201.log create mode 100644 test/daemon/garmin-geko201.log.chk create mode 100644 test/daemon/garmin17n.log create mode 100644 test/daemon/garmin17n.log.chk create mode 100644 test/daemon/garmin25lp.log create mode 100644 test/daemon/garmin25lp.log.chk create mode 100644 test/daemon/garmin38.log create mode 100644 test/daemon/garmin38.log.chk create mode 100644 test/daemon/garmin48.log create mode 100644 test/daemon/garmin48.log.chk create mode 100644 test/daemon/gps-360.log create mode 100644 test/daemon/gps-360.log.chk create mode 100644 test/daemon/gpslim236.log create mode 100644 test/daemon/gpslim236.log.chk create mode 100644 test/daemon/haicom-305N.log create mode 100644 test/daemon/haicom-305N.log.chk create mode 100644 test/daemon/holux-gm-210.log create mode 100644 test/daemon/holux-gm-210.log.chk create mode 100644 test/daemon/humminbird-M37.log create mode 100644 test/daemon/humminbird-M37.log.chk create mode 100644 test/daemon/iTrek.log create mode 100644 test/daemon/iTrek.log.chk create mode 100644 test/daemon/italk-binary.log create mode 100644 test/daemon/italk-binary.log.chk create mode 100644 test/daemon/magellan-ec10.log create mode 100644 test/daemon/magellan-ec10.log.chk create mode 100644 test/daemon/magellan315.log create mode 100644 test/daemon/magellan315.log.chk create mode 100644 test/daemon/mkt-3301.log create mode 100644 test/daemon/mkt-3301.log.chk create mode 100644 test/daemon/motorola-t805.log create mode 100644 test/daemon/motorola-t805.log.chk create mode 100644 test/daemon/navcom.log create mode 100644 test/daemon/navcom.log.chk create mode 100644 test/daemon/nl402u.log create mode 100644 test/daemon/nl402u.log.chk create mode 100644 test/daemon/nokia-ld-4w.log create mode 100644 test/daemon/nokia-ld-4w.log.chk create mode 100644 test/daemon/oncore.log create mode 100644 test/daemon/oncore.log.chk create mode 100644 test/daemon/pharos-360.log create mode 100644 test/daemon/pharos-360.log.chk create mode 100644 test/daemon/rgm3800.log create mode 100644 test/daemon/rgm3800.log.chk create mode 100644 test/daemon/rtcm2.log create mode 100644 test/daemon/rtcm2.log.chk create mode 100644 test/daemon/superstar2.log create mode 100644 test/daemon/superstar2.log.chk create mode 100644 test/daemon/tn200-all.log create mode 100644 test/daemon/tn200-all.log.chk create mode 100644 test/daemon/tn200.log create mode 100644 test/daemon/tn200.log.chk create mode 100644 test/daemon/tn204.log create mode 100644 test/daemon/tn204.log.chk create mode 100644 test/daemon/tnt-revolution.log create mode 100644 test/daemon/tnt-revolution.log.chk create mode 100644 test/daemon/tomtom-mkII.log create mode 100644 test/daemon/tomtom-mkII.log.chk create mode 100644 test/daemon/trimble-lassen_iq-3dfix.log create mode 100644 test/daemon/trimble-lassen_iq-3dfix.log.chk create mode 100644 test/daemon/trimble-lassen_iq-playacar.log create mode 100644 test/daemon/trimble-lassen_iq-playacar.log.chk create mode 100644 test/daemon/trimble-lassen_iq.log create mode 100644 test/daemon/trimble-lassen_iq.log.chk create mode 100644 test/daemon/uBlox-aek-4t.log create mode 100644 test/daemon/uBlox-aek-4t.log.chk create mode 100644 test/daemon/uBlox-lea-4h.log create mode 100644 test/daemon/uBlox-lea-4h.log.chk create mode 100644 test/daemon/uBlox-lea-4s.log create mode 100644 test/daemon/uBlox-lea-4s.log.chk create mode 100644 test/daemon/uBlox-lea-4t.log create mode 100644 test/daemon/uBlox-lea-4t.log.chk create mode 100644 test/daemon/uBlox-sirf1.log create mode 100644 test/daemon/uBlox-sirf1.log.chk create mode 100644 test/daemon/venus634lp.log create mode 100644 test/daemon/venus634lp.log.chk create mode 100644 test/daemon/zodiac.log create mode 100644 test/daemon/zodiac.log.chk create mode 100644 test/earthmate create mode 100644 test/geoid.test.chk create mode 100644 test/packet.test.chk create mode 100644 test/sample.aivdm create mode 100644 test/sample.aivdm.chk create mode 100644 test/sample.rtcm2 create mode 100644 test/sample.rtcm2.chk create mode 100644 test/synthetic-ais.json create mode 100644 test/synthetic-rtcm2.json create mode 100644 test_bits.c create mode 100644 test_float.c create mode 100644 test_geoid.c create mode 100644 test_gpsmm.cpp create mode 100644 test_json.c create mode 100644 test_mkgmtime.c create mode 100644 test_packet.c create mode 100644 test_trig.c create mode 100644 timebase.h create mode 100755 valgrind-audit create mode 100644 valgrind-audit.in create mode 100644 valgrind-suppressions create mode 100755 xgps create mode 100755 xgpsspeed diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..ed577fa --- /dev/null +++ b/AUTHORS @@ -0,0 +1,9 @@ +Remco Treffkorn +Derrick J. Brashear +Russ Nelson +Eric S. Raymond +Gary E. Miller +Jeff Francis +Amaury Jacquot +Chris Kuethe +Ville Nuorvala diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..0765386 --- /dev/null +++ b/COPYING @@ -0,0 +1,38 @@ + COPYRIGHTS + +Compilation copyright is held by the GPSD project. All rights reserved. + +GPSD project copyrights are assigned to the project lead, currently +Eric S. Raymond. Other portions of the GPSD code are Copyright (c) +1997, 1998, 1999, 2000, 2001, 2002 by Remco Treffkorn, and others +Copyright (c) 2005 by Eric S. Raymond. For other copyrights, see +individual files. + + BSD LICENSE + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met:

+ +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer.

+ +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution.

+ +Neither name of the GPSD project nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..6554fed --- /dev/null +++ b/INSTALL @@ -0,0 +1,222 @@ +Here are the steps for installing gpsd and verifying its performance: + +0. gpsd has a core set of prerequisites that are required for any +configuration of the package, and then additional features and tests +have additional prerequisites. + +Necessary components for any build: + +C compiler -> gpsd and client library are written in C +Python -> some code is generated from python scripts +Python GTK-2 binding -> the main test client, xgps, needs this + +The C code depends on one non-C99 feature: anonymous unions. We could +eliminate these, but the cost would be source-level interface breakage +if we have to move structure members in and out of unions. + +You will need Python 2.6 or 2.4+ & simplejson. The Python code in +GPSD is 2.4-compatible except that you need either the json library +module from 2.6 or the functionally equivalent simplejson backport. +Note that while Python is required to *build* GPSD (the build uses +some code generators in Python), it is not required to run the service +daemon. In particular, you can cross-compile onto an embeddeed system +without having to take Python with you. + +Having the following optional components on your system will enable +various additional capabilities and extensions: + +C++ compiler -> libgpsmm C++ wrapper for the library +pthreads library -> support for PPS timekeeping on serial GPSes +DBUS -> gpsd will issue DBUS notifications +ncurses -> a test client and the GPS monitor depend on this +libusb-1.0.x or later -> better USB device discovery +Qt + qmake -> libQgpsmm depends on this + +If you have libusb-1.0.0 or later, the GPSD build will autodetect +this and use it to discover Garmin USB GPSes, rather than groveling +through /proc/bus/usb/devices (which has been deprecated by the +Linux kernel team). + +For working with DBUS, you'll need the DBUS development +headers and libraries installed. Under Debian/Ubuntu these +are the packages ibdbus-1-dev and libdbus-glib-1-dev. + +For building from the source tree, or if you change the man page +source, xslt and docbook xsl style files are used to generate nroff +-man source from docbook xml. The following packages are used in this +process: + +libxslt -> xsltproc is used to build man pages from xml +docbook-xsl -> style file for xml to man translation + +The build degrades gracefully in the absence of any of these. You should +be able to tell from configure messages which extensions you will get. + +Under Ubuntu and most other Debian-derived, an easy way to pick up +the prerequisites is: "apt-get build-dep gpsd" + +If you are going to modify the build, you will need these: + +autoconf 2.61 or later +automake 1.10 or later +libtool 2.26 or later +pkg-config + +Once you have fetched the software prerequisites: + +1. Start by making sure you can get data from your GPS, otherwise the later +steps will be very frustrating. In this command + + stty -F /dev/ttyXXX ispeed 4800 && cat ". Default value is +"/usr/local". + +Please refer to Qt's documentation at +http://qt.nokia.com/doc/4.6/platform-specific.html for platform specific +building documentation + +16. There are regression tests to verify proper operation of gpsd, and +it can be useful to run these to verify that all is well. To run the +regression tests, first build gpsd from sources, and then run "make +check". It is not necessary to install first, but you do need +to have "." in your $PATH to run regressions uninstalled. Python is +required for regression tests. + +17. If you installed from a .deb under Debian or a Debian-derived +system, you may need to `dpkg-reconfigure -plow gpsd' to enable the +hotplug magic ("Start gpsd automatically"). + +18. Note for people using gpsd as time source for ntpd: In case you're +using dhcp3-client to configure your system, make sure you disable +/etc/dhcp3/dhclient-exit-hooks.d/ntp as dhclient would restart +ntpd with an automatically created ntp.conf otherwise - and gpsd +would not be ablt to talk with ntpd anymore. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..842082c --- /dev/null +++ b/Makefile.am @@ -0,0 +1,939 @@ +# Automake description for gpsd +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# + +CLEANFILES = + +# For a detailed explanation of what this ugly code is doing, see +# http://www.gnu.org/software/automake/manual/automake.html#Multiple-Outputs +MULTIOUT_RECOVER_DELETED = \ + if test -f '$@'; then :; else \ + trap "rm -rf '$$WITNESS.lock' '$$WITNESS'" HUP INT PIPE TERM; \ + if mkdir "$$WITNESS.lock" 2>/dev/null; then \ + rm -f "$$WITNESS"; \ + $(MAKE) $(AM_MAKEFLAGS) "$$WITNESS"; \ + result=$$?; rm -rf "$$WITNESS.lock"; exit $$result; \ + else \ + while test -d "$$WITNESS.lock"; do sleep 1; done; \ + test -f "$$WITNESS"; \ + fi; \ + fi + +#SUBDIRS = contrib + +XMLTO = xmlto + +# +# Conditionally add programs depending on libraries that may or may not be present. +# +if HAVE_NCURSES +CURSESPROGS = cgps gpsmon +endif + +# Conditional includes. +INCLUDES = $(LIBUSB_CFLAGS) +if HAVE_DBUS +INCLUDES += $(DBUS_CFLAGS) $(DBUS_GLIB_CFLAGS) -DDBUS_API_SUBJECT_TO_CHANGE=1 +endif +if HAVE_BLUEZ +INCLUDES += $(BLUEZ_CFLAGS) +endif + +RTCM104PAGES_DIST = gpsdecode.1 +if HAVE_RTCM104V2 +if HAVE_RTCM104V3 +if HAVE_AIVDM +RTCM104PROGS = gpsdecode +RTCM104PAGES = $(RTCM104PAGES_DIST) +endif +endif +endif + +bin_PROGRAMS = $(XAW_PROGS) $(RTCM104PROGS) $(CURSESPROGS) gpsctl gpspipe gpxlogger lcdgps +sbin_PROGRAMS = gpsd + +# \todo Add programs to TESTS if not already. used. +check_PROGRAMS = test_float test_trig test_bits test_packet test_mkgmtime test_geoid test_json +if LIBGPSMM_ENABLE +check_PROGRAMS += test_gpsmm +endif +if LIB_Q_GPSMM_ENABLE +check_PROGRAMS += test_qgpsmm +endif + +# List of Python scripts and modules, which are handled by setup.py. +# Required to ensure that the extensions/modules/scripts are rebuilt via +# setup.py in case they changed. +# Also used to specify which files to include during make dist. +PYTHONSCRIPTS_DIST = gpscat gpsfake gpsprof xgps xgpsspeed +PYTHONMODULES_DIST = gps/__init__.py gps/misc.py gps/fake.py gps/gps.py gps/client.py + +PYTHONPAGES_DIST = gpsprof.1 gpsfake.1 gpscat.1 xgpsspeed.1 xgps.1 +if HAVE_PYTHON +python_PYTHON = gpscap.py +PYTHONPAGES = $(PYTHONPAGES_DIST) +endif + + +# +# Build cgps +# +cgps_SOURCES = cgps.c +cgps_LDADD = $(LIBM) $(LIBC) $(LIBNSL) $(LIBSOCKET) $(NCURSES_LIBS) libgps.la -lm $(LIBPTHREAD) + +# +# Build gpxlogger +# +gpxlogger_SOURCES = gpxlogger.c +gpxlogger_LDADD = $(DBUS_GLIB_LIBS) libgps.la -lm + +# +# Build gpsd +# +gpsd_c_sources = gpsd_dbus.c gpsd.c +gpsd_SOURCES = $(gpsd_c_sources) gpsd_dbus.h +gpsd_LDADD = $(DBUS_LIBS) $(LIBM) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS) + +# +# Build gpsctl +# +gpsctl_SOURCES = gpsctl.c +gpsctl_LDADD = $(LIBM) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS) + +# +# Build gpspipe +# +gpspipe_SOURCES = gpspipe.c +gpspipe_LDADD = $(DBUS_LIBS) $(LIBM) libgps.la -lm + +# +# Build lcdgps +# +lcdgps_SOURCES = lcdgps.c +lcdgps_LDADD = $(LIBM) libgps.la -lm + +# +# Build gpsmon +# +gpsmon_SOURCES = gpsmon.c monitor_nmea.c monitor_sirf.c \ + monitor_italk.c monitor_ubx.c monitor_superstar2.c \ + monitor_oncore.c monitor_tnt.c +gpsmon_LDADD = $(LIBM) $(NCURSES_LIBS) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS) + +# +# Build gpsdecode +# +gpsdecode_SOURCES = gpsdecode.c +gpsdecode_LDADD = $(LIBM) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS) + +# +# Build shared libraries +# +# As we need to retrieve the version from qmake to build the Qt library, +# we provide targets to print the necessary informations. +libgps_VERSION_CURRENT = 19 +libgps_VERSION__REVISION = 0 +libgps_VERSION_AGE = 0 +libgps_VERSION_NUMBER = $(libgps_VERSION_AGE):$(libgps_VERSION__REVISION):$(libgps_VERSION_AGE) +libgps_la_LDFLAGS = -version-number $(libgps_VERSION_CURRENT):$(libgps_VERSION__REVISION):$(libgps_VERSION_AGE) +lib_LTLIBRARIES = libgps.la libgpsd.la + +libgps_SONAME = $(shell expr $(libgps_VERSION_CURRENT) - $(libgps_VERSION_AGE)) +libgps_VERSION = $(libgps_SONAME).$(libgps_VERSION_AGE).$(libgps_VERSION__REVISION) +print_libgps_VERSION_CURRENT: + echo $(libgps_VERSION_CURRENT) +print_libgps_VERSION__REVISION: + echo $(libgps_VERSION__REVISION) +print_libgps_VERSION_AGE: + echo $(libgps_VERSION_AGE) +print_libgps_SONAME: + echo $(libgps_SONAME) +print_libgps_VERSION: + echo $(libgps_VERSION) + +libgps_c_sources = \ + ais_json.c \ + gpsd_report.c \ + gpsutils.c \ + geoid.c \ + gpsdclient.c \ + gps_maskdump.c \ + hex.c \ + json.c \ + libgps_core.c \ + libgps_json.c \ + netlib.c \ + rtcm2_json.c \ + shared_json.c \ + strl.c + +libgpsd_c_sources = \ + bits.c \ + bsd-base64.c \ + crc24q.c \ + gpsd_json.c \ + isgps.c \ + gpsd_maskdump.c \ + libgpsd_core.c \ + net_dgpsip.c \ + net_gnss_dispatch.c \ + net_ntrip.c \ + ntpshm.c \ + packet.c \ + pseudonmea.c \ + serial.c \ + srecord.c \ + subframe.c \ + drivers.c \ + driver_aivdm.c \ + driver_evermore.c \ + driver_garmin.c \ + driver_garmin_txt.c \ + driver_italk.c \ + driver_navcom.c \ + driver_nmea.c \ + driver_oncore.c \ + driver_rtcm2.c \ + driver_rtcm3.c \ + driver_sirf.c \ + driver_superstar2.c \ + driver_tsip.c \ + driver_ubx.c \ + driver_zodiac.c + +libgpsd_h_sources = \ + sockaddr.h \ + bsd-base64.h \ + timebase.h \ + bits.h \ + crc24q.h + +BUILT_SOURCES = packet_names.h gpsd.h revision.h ais_json.i gps_maskdump.c gpsd_maskdump.c + +packet_names.h: packet_states.h + rm -f packet_names.h && \ + sed -e '/^ *\([A-Z][A-Z0-9_]*\),/s// "\1",/' -e '/_states/s//_names/' < `test -f 'packet_states.h' || echo '$(srcdir)/'`packet_states.h > packet_names.h && \ + chmod a-w packet_names.h + +gpsd.h: gpsd.h-head gpsd.h-tail gpsd_config.h + rm -f gpsd.h && \ + echo "/* This file is generated. Do not hand-hack it! */" >gpsd.h && \ + cat $(srcdir)/gpsd.h-head >>gpsd.h && \ + cat $(srcdir)/gpsd_config.h >>gpsd.h && \ + cat $(srcdir)/gpsd.h-tail >>gpsd.h && \ + chmod a-w gpsd.h + +ais_json.i: jsongen.py + rm -f ais_json.i && \ + $(PYTHON) jsongen.py --ais --target=parser >ais_json.i && \ + chmod a-w ais_json.i + +revision.h: Makefile + @rm -f revision.h && \ + echo '#define' REVISION '"'`date -u +%Y-%m-%dT%H:%M:%S`'"' >revision.h && \ + chmod a-w revision.h + +gps_maskdump.c: gps.h maskaudit.py + rm -f gps_maskdump.c && \ + $(PYTHON) maskaudit.py -c >gps_maskdump.c && \ + chmod a-w gps_maskdump.c + +gpsd_maskdump.c: gpsd.h maskaudit.py + rm -f gpsd_maskdump.c && \ + $(PYTHON) maskaudit.py -d >gpsd_maskdump.c && \ + chmod a-w gpsd_maskdump.c + +libgps_la_SOURCES = $(libgps_c_sources) + +libgpsd_la_SOURCES = $(libgpsd_c_sources) $(libgpsd_h_sources) \ + driver_rtcm2.h packet_states.h + +# Warning: This overrides autoconf's normal link-line generation process +if LIBGPSMM_ENABLE +libgps_la_SOURCES += libgpsmm.cpp +libgps_la_LINK = /bin/sh ./libtool --tag=CXX --mode=link g++ $(libgps_la_LDFLAGS) -o $@ +else +libgps_la_LINK = /bin/sh ./libtool --tag=CC --mode=link gcc $(libgps_la_LDFLAGS) -o $@ +endif + +nodist_libgpsd_la_SOURCES = packet_names.h ais_json.i +libgps_la_LIBADD = $(LIBM) $(LIBC) $(LIBNSL) $(LIBSOCKET) $(LIBPTHREAD) +libgpsd_la_LIBADD = $(LIBM) $(LIBC) $(LIBNSL) $(LIBSOCKET) $(LIBPTHREAD) $(BLUEZ_LIBS) libgps.la + +noinst_SCRIPTS = + +# Build Python binding +# +if HAVE_PYTHON +PYEXTENSIONS = gpspacket.so gpslib.so +noinst_SCRIPTS += stamp-python setup.py + +# Multiple-outputs hack. See +# http://www.gnu.org/software/automake/manual/automake.html#Multiple-Outputs +$(PYEXTENSIONS): stamp-python + +@WITNESS=stamp-python; $(MULTIOUT_RECOVER_DELETED) +# TODO: Should the dependency on libgps.la be enforced inside +# setup.py? (See the variable 'needed_files' in setup.py.) +stamp-python: gpspacket.c gpsclient.c libgps.la setup.py $(PYTHONMODULES_DIST) $(PYTHONSCRIPTS_DIST) +# Build Python modules and scripts using distutils via setup.py. +# We define build-lib and build-scripts as distutils might have been +# configured to use different directories, but we want to use the +# produced files within the regress-driver script - therefore we +# need to build them in directories we know about. +# See configure.ac for the definition of PYTHON_DISTUTILS_LIBDIR +# and PYTHON_DISTUTILS_SCRIPTDIR. + @rm -f '$@' '$@.tmp' + @echo 'timestamp for $@' > '$@.tmp' + (cd '$(srcdir)' && \ + env abs_builddir='$(abs_builddir)' \ + MAKE='$(MAKE)' \ + $(PYTHON) setup.py build \ + --build-lib '$(srcdir)/$(PYTHON_DISTUTILS_LIBDIR)' \ + --build-scripts '$(srcdir)/$(PYTHON_DISTUTILS_SCRIPTDIR)' \ + --mangenerator '$(XMLPROC)') && \ + (cd '$(srcdir)/gps' && \ + rm -f *.so && \ + ln -s ../$(PYTHON_DISTUTILS_LIBDIR)/gps/*.so . ) && \ + mv -f '$@.tmp' '$@' +CLEANFILES += stamp-python stamp-python.tmp +endif + +QTLIB_DIST = libQgpsmm/libQgpsmm.pro \ + libQgpsmm/gpsutils.cpp \ + libQgpsmm/libgps_core.cpp \ + libQgpsmm/libQgpsmm_global.h + +QTLIB_DIST_MINGW = libQgpsmm/mingw/gpsd_config.h \ + libQgpsmm/mingw/test_qgpsmm.pro + +if LIB_Q_GPSMM_ENABLE +noinst_SCRIPTS += stamp-qt +QTLIBS = libQgpsmm/binaries/libQgpsmm.so \ + libQgpsmm/binaries/libQgpsmm.so.$(libgps_SONAME) \ + libQgpsmm/binaries/libQgpsmm.so.$(libgps_SONAME).$(libgps_VERSION_AGE) \ + libQgpsmm/binaries/libQgpsmm.so.$(libgps_VERSION) + +QTLIB_sources = gpsutils.c \ + libgps_core.c \ + libgpsmm.cpp \ + libgps_json.c \ + hex.c \ + gpsd_report.c \ + strl.c \ + shared_json.c \ + rtcm2_json.c \ + ais_json.c \ + json.c \ + gps.h \ + libgpsmm.h \ + gps_json.h \ + json.h \ + ais_json.i \ + gpsd.h \ + $(QTLIB_DIST) + +QMAKE_OPTS = "PREFIX=${prefix}" \ + "MAKE=$(MAKE)" \ + "QMAKE_CXX=$(CXX)" \ + "QMAKE_CC=$(CC)" \ + "QMAKE_CFLAGS+=$(CFLAGS)" \ + "QMAKE_LFLAGS+=$(LDFLAGS)" \ + "VERSION=$(libgps_VERSION)" \ + "TARGET_LIBDIR=${libdir}" \ + "TARGET_INCLUDEDIR=${includedir}" + +libQgpsmm/Makefile: libQgpsmm/libQgpsmm.pro gpsd.h ais_json.i + cd $(srcdir)/libQgpsmm && $(QMAKE) $(QMAKE_OPTS) +# Yet another multiple-outputs hack: +$(QTLIBS): stamp-qt + +@WITNESS=stamp-qt; $(MULTIOUT_RECOVER_DELETED) +stamp-qt: $(QTLIB_sources) libQgpsmm/Makefile + $(MAKE) -C $(srcdir)/libQgpsmm + touch $@ +CLEANFILES += stamp-qt +endif + +# Clean up after Python and QT +clean-local: +if HAVE_PYTHON + rm -rf build gps/*.so +endif +if LIB_Q_GPSMM_ENABLE + if test -r $(srcdir)/libQgpsmm/Makefile; then \ + $(MAKE) -C $(srcdir)/libQgpsmm distclean || true; \ + fi + rm -rf $(srcdir)/libQgpsmm/binaries + rm -f $(srcdir)/libQgpsmm/*.o $(srcdir)/libQgpsmm/Makefile +endif + +# Install Python modules and QT library +install-exec-local: +if HAVE_PYTHON +# Make sure we do not use --root as option to setup.py install +# when DESTDIR is not defined as distutils would use the current +# working directory as root directory and not install to ${prefix}. + if test -z "$(DESTDIR)"; then \ + $(PYTHON) setup.py install --prefix=${prefix} ;\ + else \ + $(PYTHON) setup.py install --prefix=${prefix} --root=$(DESTDIR) ;\ + fi +endif +if LIB_Q_GPSMM_ENABLE + $(MAKE) -C libQgpsmm install INSTALL_ROOT=$(DESTDIR) +endif + +# +# Build test_float +# +test_float_SOURCES = test_float.c +test_float_LDADD = $(LIBC) -lm + +# +# Build test_trig +# +test_trig_SOURCES = test_trig.c +test_trig_LDADD = $(LIBC) -lm + +if LIBGPSMM_ENABLE +# +# Build test_gpsmm +# +test_gpsmm_SOURCES = test_gpsmm.cpp +test_gpsmm_LDADD = $(LIBC) libgps.la -lm $(LIBUSB_LIBS) +endif + +if LIB_Q_GPSMM_ENABLE +# +# Build test_qgpsmm +# +test_qgpsmm_SOURCES = test_gpsmm.cpp +test_qgpsmm_LDFLAGS = -Wl,-rpath,$(srcdir)/libQgpsmm/binaries +test_qgpsmm_LDADD = $(LIBC) $(LIBUSB) $(QtNetwork_LIBS) -LlibQgpsmm/binaries -lQgpsmm +test_qgpsmm_DEPENDENCIES = libQgpsmm/binaries/libQgpsmm.so +endif + +# +# Build test_bits tester +# +test_bits_SOURCES = test_bits.c +test_bits_LDADD = $(LIBC) libgpsd.la libgps.la $(LIBUSB_LIBS) + +# +# Build packets tester +# +test_packet_SOURCES = test_packet.c +test_packet_LDADD = $(LIBC) libgpsd.la libgps.la -lm $(LIBUSB_LIBS) + +# +# Build geoid model tester +# +test_geoid_SOURCES = test_geoid.c +test_geoid_LDADD = $(LIBC) libgps.la -lm + +# +# Build time functions tester +# +test_mkgmtime_SOURCES = test_mkgmtime.c +test_mkgmtime_LDADD = $(LIBC) libgps.la -lm + +# +# Build JSON parse tester +test_json_SOURCES = test_json.c +test_json_LDADD = $(LIBC) libgps.la -lm + +MANPAGES_BASE = \ + gpsd.8 \ + gps.1 \ + cgps.1 \ + lcdgps.1 \ + libgps.3 \ + libgpsmm.3 \ + libgpsd.3 \ + gpsmon.1 \ + gpsctl.1 \ + gpspipe.1 \ + rtcm-104.5 \ + srec.5 + +if HAVE_XSLT_PROCESSOR +MANPAGES_DIST = \ + $(MANPAGES_BASE) \ + $(RTCM104PAGES_DIST) \ + $(PYTHONPAGES_DIST) + +man_MANS = \ + $(MANPAGES_BASE) \ + $(RTCM104PAGES) \ + $(PYTHONPAGES) + +# +# Create Manpages +# +BUILT_MANPAGES = $(MANPAGES_DIST) + +.xml.1: + $(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $< + +.xml.3: + $(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $< + +.xml.5: + $(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $< + +.xml.8: + $(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $< + +# Another instance of the multiple-outputs hack. +gps.1 xgps.1 xgpsspeed.1 cgps.1 lcdgps.1: stamp-gps-manpages + +@WITNESS=stamp-gps-manpages; $(MULTIOUT_RECOVER_DELETED) +stamp-gps-manpages: gps.xml + @rm -f '$@' '$@.tmp' + echo 'timestamp for $@' > '$@.tmp' && \ + $(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) '$(srcdir)/gps.xml' && \ + mv -f '$@.tmp' '$@' +CLEANFILES += stamp-gps-manpages stamp-gps-manpages.tmp +endif + +noinst_HEADERS = gpsd_config.h \ + driver_italk.h driver_rtcm2.h driver_superstar2.h \ + driver_ubx.h gpsmon.h gpsdclient.h json.h gps_json.h \ + revision.h TachometerP.h Tachometer.h +nodist_include_HEADERS = gpsd.h + +if LIBGPSMM_ENABLE +include_HEADERS = gps.h libgpsmm.h +else +include_HEADERS = gps.h +endif + +XML = \ + gpsd.xml \ + gps.xml \ + libgps.xml \ + libgpsmm.xml \ + libgpsd.xml \ + gpsmon.xml \ + gpsdecode.xml \ + gpsprof.xml \ + gpsfake.xml \ + gpsctl.xml \ + gpscat.xml \ + gpspipe.xml \ + rtcm-104.xml \ + srec.xml + +# Note: packaging/rpm/gpsd.spec is generated, but it needs to be in the +# tarball in order for 'make dist-rpm' to work. The BUILT_SOURCES +# files are here in order to minimize build dependencies for package +# builders who never alter anything, especially the Python dependency. +# Also note that the test and gps directories are here rather than +# being the contents of a SUBDIRS variable so that autconf won't +# go looking for makefiles in them. +EXTRA_DIST = \ + revision.h \ + autogen.sh \ + README \ + INSTALL \ + COPYING \ + TODO \ + NEWS \ + AUTHORS \ + jsongen.py.in \ + maskaudit.py.in \ + dgpsip-servers \ + test_float.c \ + test_trig.c \ + gpsd.php \ + gpsd.xml \ + gpsd.h-head \ + gpsd.h-tail \ + $(XML) \ + $(BUILT_SOURCES) \ + $(MANPAGES_DIST) \ + gpsd.rules \ + gpsd.hotplug \ + gpsd.hotplug.wrapper \ + gpsd.usermap \ + valgrind-audit \ + valgrind-suppressions \ + gpspacket.c \ + gpsclient.c \ + driver_proto.c \ + monitor_proto.c \ + setup.py \ + packet_states.h \ + libgps.pc.in \ + libgpsd.pc.in \ + gpscap.ini \ + packaging/deb/etc_default_gpsd \ + packaging/deb/etc_init.d_gpsd \ + packaging/rpm/gpsd.spec \ + packaging/rpm/gpsd.init \ + packaging/rpm/gpsd.sysconfig \ + packaging/X11/xgps.desktop \ + packaging/X11/xgpsspeed.desktop \ + packaging/X11/gpsd-logo.png \ + do-tests \ + regress-driver \ + $(PYTHONSCRIPTS_DIST) \ + $(PYTHONMODULES_DIST) \ + $(QTLIB_DIST) \ + $(QTLIB_DIST_MINGW) \ + test + + +# Prepare necessary files to build the mingw-port of libQgpsmm +# while creating the dist tarball. +dist-hook: ais_json.i gpsd_config.h + $(MKDIR_P) '$(distdir)/libQgpsmm/mingw' + cp -p ais_json.i $(distdir)/libQgpsmm/mingw + grep "#define VERSION" gpsd_config.h > $(distdir)/libQgpsmm/mingw/version.h + echo "VERSION=$(libgps_VERSION)" > $(distdir)/libQgpsmm/mingw/version.pri +distclean-local: + rm -f $(distdir)/libQgpsmm/mingw/version.* $(distdir)/libQgpsmm/mingw/ais_json.i + + +CLEANFILES += $(BUILT_SOURCES) *.core $(PYEXTENSIONS) $(BUILT_MANPAGES) + +pkgconfig_DATA = libgps.pc libgpsd.pc +pkgconfigdir = $(libdir)/pkgconfig + +# These are not distributed +libgps: libgps_core.c gps.h .libs/libgps.a + $(CC) $(CFLAGS) -o libgps -lm -DTESTMAIN $(LIBPTHREAD) -g libgps_core.c .libs/libgps.a + +# Report splint warnings +SPLINTOPTS = -I/usr/include/dbus-1.0/ $(LIBUSB_CFLAGS) +quiet +splint: gpsd.h packet_names.h + @echo "Running splint on daemon and libraries..." + -splint $(SPLINTOPTS) -exportlocal -redef $(gpsd_c_sources) $(libgpsd_c_sources) $(libgps_c_sources) + @echo "Running splint on cgps..." + -splint $(SPLINTOPTS) -exportlocal $(cgps_SOURCES) + @echo "Running splint on gpsctl..." + -splint $(SPLINTOPTS) $(gpsctl_SOURCES) + @echo "Running splint on gpsmon..." + -splint $(SPLINTOPTS) -exportlocal $(gpsmon_SOURCES) + @echo "Running splint on gpspipe..." + -splint $(SPLINTOPTS) $(gpspipe_SOURCES) + @echo "Running splint on gpsdecode..." + -splint $(SPLINTOPTS) $(gpsdecode_SOURCES) + @echo "Running splint on gpxlogger..." + -splint $(SPLINTOPTS) $(gpxlogger_SOURCES) + @echo "Running splint on test_bits test harness..." + -splint $(SPLINTOPTS) $(test_bits_SOURCES) + @echo "Running splint on test_packet test harness..." + -splint $(SPLINTOPTS) $(test_packet_SOURCES) + @echo "Running splint on test_mkgmtime test harness..." + -splint $(SPLINTOPTS) $(test_mkgmtime_SOURCES) + @echo "Running splint on test_geoid test harness..." + -splint $(SPLINTOPTS) $(test_geoid_SOURCES) + @echo "Running splint on test_json test harness..." + -splint $(SPLINTOPTS) $(test_json_SOURCES) + +# Report cppcheck warnings. Requires 1.40 or later. +cppcheck: gpsd.h packet_names.h + cppcheck --template gcc --all --force . + +# Check the documentation for bogons, too +xmllint: $(XML) + for xml in $(XML); do xmllint --nonet --noout --valid $$xml; done + +# Re-indent the codebase in a uniform style for readability. +INDENT_FILES = $(gpsd_c_sources) $(libgpsd_c_sources) $(libgps_c_sources) \ + $(cgps_SOURCES) $(gpsmon_SOURCES) $(gpspipe_SOURCES) \ + $(gpxlogger_SOURCES) $(gpsdecode_SOURCES) \ + $(test_bits_SOURCES) $(test_packet_SOURCES) \ + $(test_mkgmtime_SOURCES) $(test_geoid_SOURCES) $(test_json_SOURCES) +INDENT_OPTIONS = --indent-level4 \ + --honour-newlines \ + --dont-break-procedure-type \ + --cuddle-else \ + --braces-on-if-line \ + --case-brace-indentation0 \ + --brace-indent0 \ + --no-space-after-casts \ + --no-space-after-function-call-names \ + --start-left-side-of-comments \ + --dont-format-comments +indent: + chmod u+w *maskdump.c + indent $(INDENT_OPTIONS) $(INDENT_FILES) + for f in $(INDENT_FILES); \ + do \ + sed <$${f} >/tmp/reindent$$$$ -e 's/@ \*/@*/' ; \ + mv /tmp/reindent$$$$ $${f} ; \ + done + chmod u-w *maskdump.c + @echo "Diff lines:" `git diff | wc -l` + +version: + @echo $(VERSION) + +# +# Regression tests begin here +# +# Note that the *-makeregress targets re-create the *.log.chk source +# files from the *.log source files. +# +# These require gcc4; use of the math coprocessor's on-board trig functions +# apparently increases the accuracy of computation in a way that affects +# the low-order digits of the track field in the O response. + +# Our regression tests are make targets, while automake expects +# programs. Thus, our approach is to construct the test +# infrastructure our way, with make targets, and to have one TEST from +# automake's viewpoint: a trivial shell script to invoke make with our +# top-level regression target. + +# One might think that using TESTS_ENVIRONMENT=$(MAKE) would work +# around this, but because the generated rule (check-TESTS) both +# depends on each TEST as well as invokes it (with TESTS_ENVIRONMENT) +# the entire list of tests is run twice. + +# Use make REGRESSOPTS=-u to force running with UDP rather than pty devices + +run_regress_driver = PYTHON=$(PYTHON) $(srcdir)/regress-driver $(REGRESSOPTS) + +# Regression-test the daemon +gps-regress: gpsd stamp-python + $(run_regress_driver) $(srcdir)/test/daemon/*.log + +# Test that super-raw mode works. Compare each logfile against itself +# dumped through the daemon running in R=2 mode. (This test is not +# included in the normal regressions.) +raw-regress: stamp-python + $(run_regress_driver) -r $(srcdir)/test/daemon/*.log + +# Build the regression tests for the daemon. +gps-makeregress: gpsd stamp-python + $(run_regress_driver) -b $(srcdir)/test/daemon/*.log + +# To build an individual test for a load named foo.log, put it in +# test/daemon and do this: +# regress-driver -b test/daemon/foo.log + +# Regression-test the RTCM decoder. +rtcm-regress: gpsdecode + @echo "Testing RTCM decoding..." + @mkdir -p test + @for f in $(srcdir)/test/*.rtcm2; do \ + echo "Testing $${f}..."; \ + $(srcdir)/gpsdecode <$${f} >/tmp/test-$$$$.chk; \ + diff -ub $${f}.chk /tmp/test-$$$$.chk; \ + done; + @echo "Testing idempotency of JSON dump/decode for RTCM2" + @$(srcdir)/gpsdecode -e -j /tmp/test-$$$$.chk; \ + grep -v '^#' test/synthetic-rtcm2.json | diff -ub - /tmp/test-$$$$.chk; \ + rm /tmp/test-$$$$.chk + +# Rebuild the RTCM regression tests. +rtcm-makeregress: gpsdecode + @for f in $(srcdir)/test/*.rtcm2; do \ + $(srcdir)/gpsdecode -j < $${f} > $${f}.chk; \ + done + +# Regression-test the AIVDM decoder. +aivdm-regress: gpsdecode + echo "Testing AIVDM decoding..." + @mkdir -p $(srcdir)/test + @for f in $(srcdir)/test/*.aivdm; do \ + echo "Testing $${f}..."; \ + $(srcdir)/gpsdecode -u -c <$${f} >/tmp/test-$$$$.chk; \ + diff -ub $${f}.chk /tmp/test-$$$$.chk; \ + done; + @echo "Testing idempotency of JSON dump/decode for AIS" + @$(srcdir)/gpsdecode -e -j <$(srcdir)/test/synthetic-ais.json >/tmp/test-$$$$.chk; \ + grep -v '^#' $(srcdir)/test/synthetic-ais.json | diff -ub - /tmp/test-$$$$.chk; \ + rm /tmp/test-$$$$.chk + +# Rebuild the AIVDM regression tests. +aivdm-makeregress: gpsdecode + @for f in $(srcdir)/test/*.aivdm; do \ + $(srcdir)/gpsdecode -u -c <$${f} > $${f}.chk; \ + done + +# Regression-test the packet getter. +packet-regress: test_packet + @echo "Testing detection of invalid packets..." + @$(srcdir)/test_packet | diff -u $(srcdir)/test/packet.test.chk - + +# Rebuild the packet-getter regression test +packet-makeregress: test_packet + @mkdir -p $(srcdir)/test + $(srcdir)/test_packet >$(srcdir)/test/packet.test.chk + +# Regression-test the geoid tester. +geoid-regress: test_geoid + @echo "Testing the geoid model..." + @$(srcdir)/test_geoid 37.371192 122.014965 | diff -u $(srcdir)/test/geoid.test.chk - + +# Rebuild the packet-getter regression test +geoid-makeregress: test_geoid + @mkdir -p $(srcdir)/test + $(srcdir)/test_geoid 37.371192 122.014965 >$(srcdir)/test/geoid.test.chk + +# Regression-test the calendar functions +time-regress: test_mkgmtime + $(srcdir)/test_mkgmtime + +# Regression test the unpacking code in libgps +unpack-regress: libgps + @echo "Testing the client-library sentence decoder..." + $(run_regress_driver) -c $(srcdir)/test/clientlib/*.log + +# Build the regression test for the sentence unpacker +unpack-makeregress: libgps + @echo "Rebuilding the client sentence-unpacker tests..." + $(run_regress_driver) -c -b $(srcdir)/test/clientlib/*.log + +# Unit-test the JSON parsing +json-regress: test_json + $(srcdir)/test_json + +# Unit-test the bitfield extractor - not in normal tests +bits-regress: test_bits + $(srcdir)/test_bits + +# Do all normal regression tests. +testregress: gps-regress rtcm-regress aivdm-regress packet-regress time-regress unpack-regress json-regress + @echo "Regressions complete." + +# do-tests is a shell script that invokes make with target testregress. +# This works around automake's lack of support for make targets as tests. +TESTS_ENVIRONMENT = MAKE=$(MAKE) PYTHON=$(PYTHON) +TESTS = do-tests + +# The website directory +# +# None of these productions are fired by 'make all'. + +if XMLTOSTDOUT +www/%.html: %.xml + $(XMLPROC) $(XMLPROCFLAGS) $(HTMLTARGET) $< >$(<:.xml=.html) ; cp $(<:.xml=.html) $@ +else +www/%.html: %.xml + $(XMLPROC) $(XMLPROCFLAGS) $(HTMLTARGET) $<; cp $(<:.xml=.html) $@ +endif + +website: www/gpscat.html www/gpsctl.html www/gpsdecode.html \ + www/gpsd.html www/gpsfake.html www/gpsmon.html \ + www/gpspipe.html www/gpsprof.html www/gps.html \ + www/libgpsd.html www/libgpsmm.html www/libgps.html \ + www/rtcm-104.html www/srec.html \ + www/AIVDM.html www/NMEA.html \ + www/protocol-evolution.html www/protocol-transition.html \ + www/client-howto.html www/writing-a-driver.html \ + www/index.html www/hardware.html \ + www/performance/performance.html \ + www/internals.html + +www/AIVDM.html: www/AIVDM.txt + asciidoc -a toc -o www/AIVDM.html www/AIVDM.txt + +www/NMEA.html: www/NMEA.txt + asciidoc -a toc -o www/NMEA.html www/NMEA.txt + +www/protocol-evolution.html: www/protocol-evolution.txt + asciidoc -a toc -o www/protocol-evolution.html www/protocol-evolution.txt + +www/protocol-transition.html: www/protocol-transition.txt + asciidoc -a toc -o www/protocol-transition.html www/protocol-transition.txt + +www/client-howto.html: www/client-howto.txt + asciidoc -a toc -o www/client-howto.html www/client-howto.txt + +www/writing-a-driver.html: www/writing-a-driver.xml + xmlto xhtml-nochunks www/writing-a-driver.xml; mv writing-a-driver.html www + +www/index.html: www/index.html.in + sed -e "/@DATE@/s//`date '+%B %d, %Y'`/" www/index.html + +www/hardware.html: www/hardware-head.html gpscap.ini www/hardware-tail.html + (cat www/hardware-head.html; python gpscap.py; cat www/hardware-tail.html) >www/hardware.html + +www/performance/performance.html: www/performance/performance.xml + (cd www/performance; xmlto xhtml-nochunks performance.xml) + +www/internals.html: $(shell ls doc/*.xml) + cd doc; xmlto xhtml-nochunks explanation.xml; cp explanation.html ../www/internals.html + +if HAVE_PYTHON +# Experimenting with pydoc. Not yet fired by any other productions. + +pydoc: www/pydoc/index.html + +# We need to run epydoc with the Python version we built the modules for. +# So we define our on epydoc instead of using /usr/bin/epydoc +EPYDOC = $(PYTHON) -c 'from epydoc.cli import cli; cli()' + +# We have pre-compiled python scripts in the script directory, so we exclude +# all files ending on c here. Needs a better solution as soon as we have a +# script ending with c. +EPYDOCSCRIPTS = $(shell find $(PYTHON_DISTUTILS_SCRIPTDIR) -name '*c' -o -type f -print) +EPYDOCMODULES = $(PYTHON_DISTUTILS_LIBDIR)/gps + +www/pydoc/index.html: gps gpsfake gpscat gpsprof stamp-python + mkdir -p www/pydoc + $(EPYDOC) -v --html --graph all -n GPSD $(EPYDOCSCRIPTS) $(EPYDOCMODULES) -o www/pydoc + +endif + +# Productions for setting up and performing udev tests. +# +# Requires root. Do "udev-install", then "tail -f /var/run/syslog" in +# another window, then run 'make udev-test', then plug and unplug the +# GPS ad libitum. All is well when you get fix reports each time a GPS +# is plugged in. + +udev-install: + cp $(srcdir)/gpsd.rules /lib/udev/rules.d/025_gpsd.rules + cp $(srcdir)/gpsd.hotplug $(srcdir)/gpsd.hotplug.wrapper /lib/udev/ + chmod a+x /lib/udev/gpsd.hotplug /lib/udev/gpsd.hotplug.wrapper + +udev-uninstall: + rm -f /lib/udev/{gpsd.hotplug,gpsd.hotplug.wrapper} + rm -f /lib/udev/rules.d/025_gpsd.rules + +udev-test: + $(srcdir)/gpsd -N -F /var/run/gpsd.sock -D 4 + +# Release machinery begins here +# + +# Make RPM from the specfile in packaging +dist-rpm: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + rpmbuild -ta $(distdir).tar.gz + $(am__remove_distdir) + +# This is how to ship a release to Berlios incoming. +# It requires developer access verified via ssh. +# +upload-ftp: dist + shasum gpsd-$(VERSION).tar.gz >gpsd.sum + lftp -c "open ftp://ftp.berlios.de/incoming; mput gpsd-$(VERSION).tar.gz gpsd.sum" + +# +# This is how to tag a release. +# It requires developer access verified via ssh. +# +release-tag: + git tag -s -m "Tagged for external release $(VERSION)" release-$(VERSION) + git push --tags + +# +# Ship a release, providing all regression tests pass. +# The clean is necessary so that dist will remake revision.h +# with the current revision level in it. +# +ship: testregress clean dist upload-ftp release-tag + + +.PHONY: print_libgps_VERSION_CURRENT \ + print_libgps_VERSION__REVISION \ + print_libgps_VERSION_AGE \ + print_libgps_SONAME \ + print_libgps_VERSION \ + pydoc diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..bb803fd --- /dev/null +++ b/Makefile.in @@ -0,0 +1,2396 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Automake description for gpsd +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# + + + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@HAVE_DBUS_TRUE@am__append_1 = $(DBUS_CFLAGS) $(DBUS_GLIB_CFLAGS) -DDBUS_API_SUBJECT_TO_CHANGE=1 +@HAVE_BLUEZ_TRUE@am__append_2 = $(BLUEZ_CFLAGS) +bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) gpsctl$(EXEEXT) \ + gpspipe$(EXEEXT) gpxlogger$(EXEEXT) lcdgps$(EXEEXT) +sbin_PROGRAMS = gpsd$(EXEEXT) +check_PROGRAMS = test_float$(EXEEXT) test_trig$(EXEEXT) \ + test_bits$(EXEEXT) test_packet$(EXEEXT) test_mkgmtime$(EXEEXT) \ + test_geoid$(EXEEXT) test_json$(EXEEXT) $(am__EXEEXT_3) \ + $(am__EXEEXT_4) +@LIBGPSMM_ENABLE_TRUE@am__append_3 = test_gpsmm +@LIB_Q_GPSMM_ENABLE_TRUE@am__append_4 = test_qgpsmm + +# Warning: This overrides autoconf's normal link-line generation process +@LIBGPSMM_ENABLE_TRUE@am__append_5 = libgpsmm.cpp +@HAVE_PYTHON_TRUE@am__append_6 = stamp-python setup.py +@HAVE_PYTHON_TRUE@am__append_7 = stamp-python stamp-python.tmp +@LIB_Q_GPSMM_ENABLE_TRUE@am__append_8 = stamp-qt +@LIB_Q_GPSMM_ENABLE_TRUE@am__append_9 = stamp-qt +@HAVE_XSLT_PROCESSOR_TRUE@am__append_10 = stamp-gps-manpages stamp-gps-manpages.tmp +subdir = . +DIST_COMMON = README $(am__configure_deps) $(am__include_HEADERS_DIST) \ + $(am__python_PYTHON_DIST) $(noinst_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/gpsd_config.h.in $(srcdir)/jsongen.py.in \ + $(srcdir)/libgps.pc.in $(srcdir)/libgpsd.pc.in \ + $(srcdir)/maskaudit.py.in $(srcdir)/valgrind-audit.in \ + $(top_srcdir)/configure \ + $(top_srcdir)/packaging/rpm/gpsd.spec.in AUTHORS COPYING \ + INSTALL NEWS TODO config.guess config.sub depcomp install-sh \ + ltmain.sh missing py-compile +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = gpsd_config.h +CONFIG_CLEAN_FILES = packaging/rpm/gpsd.spec libgps.pc libgpsd.pc \ + jsongen.py maskaudit.py valgrind-audit +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(pythondir)" \ + "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" \ + "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \ + "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" \ + "$(DESTDIR)$(includedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libgps_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__libgps_la_SOURCES_DIST = ais_json.c gpsd_report.c gpsutils.c \ + geoid.c gpsdclient.c gps_maskdump.c hex.c json.c libgps_core.c \ + libgps_json.c netlib.c rtcm2_json.c shared_json.c strl.c \ + libgpsmm.cpp +am__objects_1 = ais_json.lo gpsd_report.lo gpsutils.lo geoid.lo \ + gpsdclient.lo gps_maskdump.lo hex.lo json.lo libgps_core.lo \ + libgps_json.lo netlib.lo rtcm2_json.lo shared_json.lo strl.lo +@LIBGPSMM_ENABLE_TRUE@am__objects_2 = libgpsmm.lo +am_libgps_la_OBJECTS = $(am__objects_1) $(am__objects_2) +libgps_la_OBJECTS = $(am_libgps_la_OBJECTS) +libgpsd_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) libgps.la +am__objects_3 = bits.lo bsd-base64.lo crc24q.lo gpsd_json.lo isgps.lo \ + gpsd_maskdump.lo libgpsd_core.lo net_dgpsip.lo \ + net_gnss_dispatch.lo net_ntrip.lo ntpshm.lo packet.lo \ + pseudonmea.lo serial.lo srecord.lo subframe.lo drivers.lo \ + driver_aivdm.lo driver_evermore.lo driver_garmin.lo \ + driver_garmin_txt.lo driver_italk.lo driver_navcom.lo \ + driver_nmea.lo driver_oncore.lo driver_rtcm2.lo \ + driver_rtcm3.lo driver_sirf.lo driver_superstar2.lo \ + driver_tsip.lo driver_ubx.lo driver_zodiac.lo +am__objects_4 = +am_libgpsd_la_OBJECTS = $(am__objects_3) $(am__objects_4) +nodist_libgpsd_la_OBJECTS = +libgpsd_la_OBJECTS = $(am_libgpsd_la_OBJECTS) \ + $(nodist_libgpsd_la_OBJECTS) +@HAVE_AIVDM_TRUE@@HAVE_RTCM104V2_TRUE@@HAVE_RTCM104V3_TRUE@am__EXEEXT_1 = gpsdecode$(EXEEXT) +@HAVE_NCURSES_TRUE@am__EXEEXT_2 = cgps$(EXEEXT) gpsmon$(EXEEXT) +@LIBGPSMM_ENABLE_TRUE@am__EXEEXT_3 = test_gpsmm$(EXEEXT) +@LIB_Q_GPSMM_ENABLE_TRUE@am__EXEEXT_4 = test_qgpsmm$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) +am_cgps_OBJECTS = cgps.$(OBJEXT) +cgps_OBJECTS = $(am_cgps_OBJECTS) +cgps_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) libgps.la $(am__DEPENDENCIES_1) +am_gpsctl_OBJECTS = gpsctl.$(OBJEXT) +gpsctl_OBJECTS = $(am_gpsctl_OBJECTS) +gpsctl_DEPENDENCIES = $(am__DEPENDENCIES_1) libgpsd.la libgps.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__objects_5 = gpsd_dbus.$(OBJEXT) gpsd.$(OBJEXT) +am_gpsd_OBJECTS = $(am__objects_5) +gpsd_OBJECTS = $(am_gpsd_OBJECTS) +gpsd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + libgpsd.la libgps.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_gpsdecode_OBJECTS = gpsdecode.$(OBJEXT) +gpsdecode_OBJECTS = $(am_gpsdecode_OBJECTS) +gpsdecode_DEPENDENCIES = $(am__DEPENDENCIES_1) libgpsd.la libgps.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_gpsmon_OBJECTS = gpsmon.$(OBJEXT) monitor_nmea.$(OBJEXT) \ + monitor_sirf.$(OBJEXT) monitor_italk.$(OBJEXT) \ + monitor_ubx.$(OBJEXT) monitor_superstar2.$(OBJEXT) \ + monitor_oncore.$(OBJEXT) monitor_tnt.$(OBJEXT) +gpsmon_OBJECTS = $(am_gpsmon_OBJECTS) +gpsmon_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + libgpsd.la libgps.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_gpspipe_OBJECTS = gpspipe.$(OBJEXT) +gpspipe_OBJECTS = $(am_gpspipe_OBJECTS) +gpspipe_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + libgps.la +am_gpxlogger_OBJECTS = gpxlogger.$(OBJEXT) +gpxlogger_OBJECTS = $(am_gpxlogger_OBJECTS) +gpxlogger_DEPENDENCIES = $(am__DEPENDENCIES_1) libgps.la +am_lcdgps_OBJECTS = lcdgps.$(OBJEXT) +lcdgps_OBJECTS = $(am_lcdgps_OBJECTS) +lcdgps_DEPENDENCIES = $(am__DEPENDENCIES_1) libgps.la +am_test_bits_OBJECTS = test_bits.$(OBJEXT) +test_bits_OBJECTS = $(am_test_bits_OBJECTS) +test_bits_DEPENDENCIES = $(am__DEPENDENCIES_1) libgpsd.la libgps.la \ + $(am__DEPENDENCIES_1) +am_test_float_OBJECTS = test_float.$(OBJEXT) +test_float_OBJECTS = $(am_test_float_OBJECTS) +test_float_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_test_geoid_OBJECTS = test_geoid.$(OBJEXT) +test_geoid_OBJECTS = $(am_test_geoid_OBJECTS) +test_geoid_DEPENDENCIES = $(am__DEPENDENCIES_1) libgps.la +am__test_gpsmm_SOURCES_DIST = test_gpsmm.cpp +@LIBGPSMM_ENABLE_TRUE@am_test_gpsmm_OBJECTS = test_gpsmm.$(OBJEXT) +test_gpsmm_OBJECTS = $(am_test_gpsmm_OBJECTS) +@LIBGPSMM_ENABLE_TRUE@test_gpsmm_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@LIBGPSMM_ENABLE_TRUE@ libgps.la $(am__DEPENDENCIES_1) +am_test_json_OBJECTS = test_json.$(OBJEXT) +test_json_OBJECTS = $(am_test_json_OBJECTS) +test_json_DEPENDENCIES = $(am__DEPENDENCIES_1) libgps.la +am_test_mkgmtime_OBJECTS = test_mkgmtime.$(OBJEXT) +test_mkgmtime_OBJECTS = $(am_test_mkgmtime_OBJECTS) +test_mkgmtime_DEPENDENCIES = $(am__DEPENDENCIES_1) libgps.la +am_test_packet_OBJECTS = test_packet.$(OBJEXT) +test_packet_OBJECTS = $(am_test_packet_OBJECTS) +test_packet_DEPENDENCIES = $(am__DEPENDENCIES_1) libgpsd.la libgps.la \ + $(am__DEPENDENCIES_1) +am__test_qgpsmm_SOURCES_DIST = test_gpsmm.cpp +@LIB_Q_GPSMM_ENABLE_TRUE@am_test_qgpsmm_OBJECTS = \ +@LIB_Q_GPSMM_ENABLE_TRUE@ test_gpsmm.$(OBJEXT) +test_qgpsmm_OBJECTS = $(am_test_qgpsmm_OBJECTS) +test_qgpsmm_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(test_qgpsmm_LDFLAGS) $(LDFLAGS) -o $@ +am_test_trig_OBJECTS = test_trig.$(OBJEXT) +test_trig_OBJECTS = $(am_test_trig_OBJECTS) +test_trig_DEPENDENCIES = $(am__DEPENDENCIES_1) +SCRIPTS = $(noinst_SCRIPTS) +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libgps_la_SOURCES) $(libgpsd_la_SOURCES) \ + $(nodist_libgpsd_la_SOURCES) $(cgps_SOURCES) $(gpsctl_SOURCES) \ + $(gpsd_SOURCES) $(gpsdecode_SOURCES) $(gpsmon_SOURCES) \ + $(gpspipe_SOURCES) $(gpxlogger_SOURCES) $(lcdgps_SOURCES) \ + $(test_bits_SOURCES) $(test_float_SOURCES) \ + $(test_geoid_SOURCES) $(test_gpsmm_SOURCES) \ + $(test_json_SOURCES) $(test_mkgmtime_SOURCES) \ + $(test_packet_SOURCES) $(test_qgpsmm_SOURCES) \ + $(test_trig_SOURCES) +DIST_SOURCES = $(am__libgps_la_SOURCES_DIST) $(libgpsd_la_SOURCES) \ + $(cgps_SOURCES) $(gpsctl_SOURCES) $(gpsd_SOURCES) \ + $(gpsdecode_SOURCES) $(gpsmon_SOURCES) $(gpspipe_SOURCES) \ + $(gpxlogger_SOURCES) $(lcdgps_SOURCES) $(test_bits_SOURCES) \ + $(test_float_SOURCES) $(test_geoid_SOURCES) \ + $(am__test_gpsmm_SOURCES_DIST) $(test_json_SOURCES) \ + $(test_mkgmtime_SOURCES) $(test_packet_SOURCES) \ + $(am__test_qgpsmm_SOURCES_DIST) $(test_trig_SOURCES) +am__python_PYTHON_DIST = gpscap.py +py_compile = $(top_srcdir)/py-compile +man1dir = $(mandir)/man1 +man3dir = $(mandir)/man3 +man5dir = $(mandir)/man5 +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(man_MANS) +DATA = $(pkgconfig_DATA) +am__include_HEADERS_DIST = gps.h libgpsmm.h +HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) \ + $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLUEZ_CFLAGS = @BLUEZ_CFLAGS@ +BLUEZ_LIBS = @BLUEZ_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_CFLAGS = @DBUS_GLIB_CFLAGS@ +DBUS_GLIB_LIBS = @DBUS_GLIB_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HTMLTARGET = @HTMLTARGET@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBC = @LIBC@ +LIBM = @LIBM@ +LIBNSL = @LIBNSL@ +LIBOBJS = @LIBOBJS@ +LIBPTHREAD = @LIBPTHREAD@ +LIBS = @LIBS@ +LIBSOCKET = @LIBSOCKET@ +LIBTOOL = @LIBTOOL@ +LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ +LIBUSB_LIBS = @LIBUSB_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANTARGET = @MANTARGET@ +MKDIR_P = @MKDIR_P@ +NCURSES_LIBS = @NCURSES_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PYTHON = @PYTHON@ +PYTHON_CFLAGS = @PYTHON_CFLAGS@ +PYTHON_DISTUTILS_LIBDIR = @PYTHON_DISTUTILS_LIBDIR@ +PYTHON_DISTUTILS_SCRIPTDIR = @PYTHON_DISTUTILS_SCRIPTDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_LIBS = @PYTHON_LIBS@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +QMAKE = @QMAKE@ +QtNetwork_CFLAGS = @QtNetwork_CFLAGS@ +QtNetwork_LIBS = @QtNetwork_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WITH_XMLTO = @WITH_XMLTO@ +WITH_XSLTPROC = @WITH_XSLTPROC@ +XMLPROC = @XMLPROC@ +XMLPROCFLAGS = @XMLPROCFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +CLEANFILES = $(am__append_7) $(am__append_9) $(am__append_10) \ + $(BUILT_SOURCES) *.core $(PYEXTENSIONS) $(BUILT_MANPAGES) + +# For a detailed explanation of what this ugly code is doing, see +# http://www.gnu.org/software/automake/manual/automake.html#Multiple-Outputs +MULTIOUT_RECOVER_DELETED = \ + if test -f '$@'; then :; else \ + trap "rm -rf '$$WITNESS.lock' '$$WITNESS'" HUP INT PIPE TERM; \ + if mkdir "$$WITNESS.lock" 2>/dev/null; then \ + rm -f "$$WITNESS"; \ + $(MAKE) $(AM_MAKEFLAGS) "$$WITNESS"; \ + result=$$?; rm -rf "$$WITNESS.lock"; exit $$result; \ + else \ + while test -d "$$WITNESS.lock"; do sleep 1; done; \ + test -f "$$WITNESS"; \ + fi; \ + fi + + +#SUBDIRS = contrib +XMLTO = xmlto + +# +# Conditionally add programs depending on libraries that may or may not be present. +# +@HAVE_NCURSES_TRUE@CURSESPROGS = cgps gpsmon + +# Conditional includes. +INCLUDES = $(LIBUSB_CFLAGS) $(am__append_1) $(am__append_2) +RTCM104PAGES_DIST = gpsdecode.1 +@HAVE_AIVDM_TRUE@@HAVE_RTCM104V2_TRUE@@HAVE_RTCM104V3_TRUE@RTCM104PROGS = gpsdecode +@HAVE_AIVDM_TRUE@@HAVE_RTCM104V2_TRUE@@HAVE_RTCM104V3_TRUE@RTCM104PAGES = $(RTCM104PAGES_DIST) + +# List of Python scripts and modules, which are handled by setup.py. +# Required to ensure that the extensions/modules/scripts are rebuilt via +# setup.py in case they changed. +# Also used to specify which files to include during make dist. +PYTHONSCRIPTS_DIST = gpscat gpsfake gpsprof xgps xgpsspeed +PYTHONMODULES_DIST = gps/__init__.py gps/misc.py gps/fake.py gps/gps.py gps/client.py +PYTHONPAGES_DIST = gpsprof.1 gpsfake.1 gpscat.1 xgpsspeed.1 xgps.1 +@HAVE_PYTHON_TRUE@python_PYTHON = gpscap.py +@HAVE_PYTHON_TRUE@PYTHONPAGES = $(PYTHONPAGES_DIST) + +# +# Build cgps +# +cgps_SOURCES = cgps.c +cgps_LDADD = $(LIBM) $(LIBC) $(LIBNSL) $(LIBSOCKET) $(NCURSES_LIBS) libgps.la -lm $(LIBPTHREAD) + +# +# Build gpxlogger +# +gpxlogger_SOURCES = gpxlogger.c +gpxlogger_LDADD = $(DBUS_GLIB_LIBS) libgps.la -lm + +# +# Build gpsd +# +gpsd_c_sources = gpsd_dbus.c gpsd.c +gpsd_SOURCES = $(gpsd_c_sources) gpsd_dbus.h +gpsd_LDADD = $(DBUS_LIBS) $(LIBM) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS) + +# +# Build gpsctl +# +gpsctl_SOURCES = gpsctl.c +gpsctl_LDADD = $(LIBM) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS) + +# +# Build gpspipe +# +gpspipe_SOURCES = gpspipe.c +gpspipe_LDADD = $(DBUS_LIBS) $(LIBM) libgps.la -lm + +# +# Build lcdgps +# +lcdgps_SOURCES = lcdgps.c +lcdgps_LDADD = $(LIBM) libgps.la -lm + +# +# Build gpsmon +# +gpsmon_SOURCES = gpsmon.c monitor_nmea.c monitor_sirf.c \ + monitor_italk.c monitor_ubx.c monitor_superstar2.c \ + monitor_oncore.c monitor_tnt.c + +gpsmon_LDADD = $(LIBM) $(NCURSES_LIBS) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS) + +# +# Build gpsdecode +# +gpsdecode_SOURCES = gpsdecode.c +gpsdecode_LDADD = $(LIBM) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS) + +# +# Build shared libraries +# +# As we need to retrieve the version from qmake to build the Qt library, +# we provide targets to print the necessary informations. +libgps_VERSION_CURRENT = 19 +libgps_VERSION__REVISION = 0 +libgps_VERSION_AGE = 0 +libgps_VERSION_NUMBER = $(libgps_VERSION_AGE):$(libgps_VERSION__REVISION):$(libgps_VERSION_AGE) +libgps_la_LDFLAGS = -version-number $(libgps_VERSION_CURRENT):$(libgps_VERSION__REVISION):$(libgps_VERSION_AGE) +lib_LTLIBRARIES = libgps.la libgpsd.la +libgps_SONAME = $(shell expr $(libgps_VERSION_CURRENT) - $(libgps_VERSION_AGE)) +libgps_VERSION = $(libgps_SONAME).$(libgps_VERSION_AGE).$(libgps_VERSION__REVISION) +libgps_c_sources = \ + ais_json.c \ + gpsd_report.c \ + gpsutils.c \ + geoid.c \ + gpsdclient.c \ + gps_maskdump.c \ + hex.c \ + json.c \ + libgps_core.c \ + libgps_json.c \ + netlib.c \ + rtcm2_json.c \ + shared_json.c \ + strl.c + +libgpsd_c_sources = \ + bits.c \ + bsd-base64.c \ + crc24q.c \ + gpsd_json.c \ + isgps.c \ + gpsd_maskdump.c \ + libgpsd_core.c \ + net_dgpsip.c \ + net_gnss_dispatch.c \ + net_ntrip.c \ + ntpshm.c \ + packet.c \ + pseudonmea.c \ + serial.c \ + srecord.c \ + subframe.c \ + drivers.c \ + driver_aivdm.c \ + driver_evermore.c \ + driver_garmin.c \ + driver_garmin_txt.c \ + driver_italk.c \ + driver_navcom.c \ + driver_nmea.c \ + driver_oncore.c \ + driver_rtcm2.c \ + driver_rtcm3.c \ + driver_sirf.c \ + driver_superstar2.c \ + driver_tsip.c \ + driver_ubx.c \ + driver_zodiac.c + +libgpsd_h_sources = \ + sockaddr.h \ + bsd-base64.h \ + timebase.h \ + bits.h \ + crc24q.h + +BUILT_SOURCES = packet_names.h gpsd.h revision.h ais_json.i gps_maskdump.c gpsd_maskdump.c +libgps_la_SOURCES = $(libgps_c_sources) $(am__append_5) +libgpsd_la_SOURCES = $(libgpsd_c_sources) $(libgpsd_h_sources) \ + driver_rtcm2.h packet_states.h + +@LIBGPSMM_ENABLE_FALSE@libgps_la_LINK = /bin/sh ./libtool --tag=CC --mode=link gcc $(libgps_la_LDFLAGS) -o $@ +@LIBGPSMM_ENABLE_TRUE@libgps_la_LINK = /bin/sh ./libtool --tag=CXX --mode=link g++ $(libgps_la_LDFLAGS) -o $@ +nodist_libgpsd_la_SOURCES = packet_names.h ais_json.i +libgps_la_LIBADD = $(LIBM) $(LIBC) $(LIBNSL) $(LIBSOCKET) $(LIBPTHREAD) +libgpsd_la_LIBADD = $(LIBM) $(LIBC) $(LIBNSL) $(LIBSOCKET) $(LIBPTHREAD) $(BLUEZ_LIBS) libgps.la +noinst_SCRIPTS = $(am__append_6) $(am__append_8) + +# Build Python binding +# +@HAVE_PYTHON_TRUE@PYEXTENSIONS = gpspacket.so gpslib.so +QTLIB_DIST = libQgpsmm/libQgpsmm.pro \ + libQgpsmm/gpsutils.cpp \ + libQgpsmm/libgps_core.cpp \ + libQgpsmm/libQgpsmm_global.h + +QTLIB_DIST_MINGW = libQgpsmm/mingw/gpsd_config.h \ + libQgpsmm/mingw/test_qgpsmm.pro + +@LIB_Q_GPSMM_ENABLE_TRUE@QTLIBS = libQgpsmm/binaries/libQgpsmm.so \ +@LIB_Q_GPSMM_ENABLE_TRUE@ libQgpsmm/binaries/libQgpsmm.so.$(libgps_SONAME) \ +@LIB_Q_GPSMM_ENABLE_TRUE@ libQgpsmm/binaries/libQgpsmm.so.$(libgps_SONAME).$(libgps_VERSION_AGE) \ +@LIB_Q_GPSMM_ENABLE_TRUE@ libQgpsmm/binaries/libQgpsmm.so.$(libgps_VERSION) + +@LIB_Q_GPSMM_ENABLE_TRUE@QTLIB_sources = gpsutils.c \ +@LIB_Q_GPSMM_ENABLE_TRUE@ libgps_core.c \ +@LIB_Q_GPSMM_ENABLE_TRUE@ libgpsmm.cpp \ +@LIB_Q_GPSMM_ENABLE_TRUE@ libgps_json.c \ +@LIB_Q_GPSMM_ENABLE_TRUE@ hex.c \ +@LIB_Q_GPSMM_ENABLE_TRUE@ gpsd_report.c \ +@LIB_Q_GPSMM_ENABLE_TRUE@ strl.c \ +@LIB_Q_GPSMM_ENABLE_TRUE@ shared_json.c \ +@LIB_Q_GPSMM_ENABLE_TRUE@ rtcm2_json.c \ +@LIB_Q_GPSMM_ENABLE_TRUE@ ais_json.c \ +@LIB_Q_GPSMM_ENABLE_TRUE@ json.c \ +@LIB_Q_GPSMM_ENABLE_TRUE@ gps.h \ +@LIB_Q_GPSMM_ENABLE_TRUE@ libgpsmm.h \ +@LIB_Q_GPSMM_ENABLE_TRUE@ gps_json.h \ +@LIB_Q_GPSMM_ENABLE_TRUE@ json.h \ +@LIB_Q_GPSMM_ENABLE_TRUE@ ais_json.i \ +@LIB_Q_GPSMM_ENABLE_TRUE@ gpsd.h \ +@LIB_Q_GPSMM_ENABLE_TRUE@ $(QTLIB_DIST) + +@LIB_Q_GPSMM_ENABLE_TRUE@QMAKE_OPTS = "PREFIX=${prefix}" \ +@LIB_Q_GPSMM_ENABLE_TRUE@ "MAKE=$(MAKE)" \ +@LIB_Q_GPSMM_ENABLE_TRUE@ "QMAKE_CXX=$(CXX)" \ +@LIB_Q_GPSMM_ENABLE_TRUE@ "QMAKE_CC=$(CC)" \ +@LIB_Q_GPSMM_ENABLE_TRUE@ "QMAKE_CFLAGS+=$(CFLAGS)" \ +@LIB_Q_GPSMM_ENABLE_TRUE@ "QMAKE_LFLAGS+=$(LDFLAGS)" \ +@LIB_Q_GPSMM_ENABLE_TRUE@ "VERSION=$(libgps_VERSION)" \ +@LIB_Q_GPSMM_ENABLE_TRUE@ "TARGET_LIBDIR=${libdir}" \ +@LIB_Q_GPSMM_ENABLE_TRUE@ "TARGET_INCLUDEDIR=${includedir}" + + +# +# Build test_float +# +test_float_SOURCES = test_float.c +test_float_LDADD = $(LIBC) -lm + +# +# Build test_trig +# +test_trig_SOURCES = test_trig.c +test_trig_LDADD = $(LIBC) -lm + +# +# Build test_gpsmm +# +@LIBGPSMM_ENABLE_TRUE@test_gpsmm_SOURCES = test_gpsmm.cpp +@LIBGPSMM_ENABLE_TRUE@test_gpsmm_LDADD = $(LIBC) libgps.la -lm $(LIBUSB_LIBS) + +# +# Build test_qgpsmm +# +@LIB_Q_GPSMM_ENABLE_TRUE@test_qgpsmm_SOURCES = test_gpsmm.cpp +@LIB_Q_GPSMM_ENABLE_TRUE@test_qgpsmm_LDFLAGS = -Wl,-rpath,$(srcdir)/libQgpsmm/binaries +@LIB_Q_GPSMM_ENABLE_TRUE@test_qgpsmm_LDADD = $(LIBC) $(LIBUSB) $(QtNetwork_LIBS) -LlibQgpsmm/binaries -lQgpsmm +@LIB_Q_GPSMM_ENABLE_TRUE@test_qgpsmm_DEPENDENCIES = libQgpsmm/binaries/libQgpsmm.so + +# +# Build test_bits tester +# +test_bits_SOURCES = test_bits.c +test_bits_LDADD = $(LIBC) libgpsd.la libgps.la $(LIBUSB_LIBS) + +# +# Build packets tester +# +test_packet_SOURCES = test_packet.c +test_packet_LDADD = $(LIBC) libgpsd.la libgps.la -lm $(LIBUSB_LIBS) + +# +# Build geoid model tester +# +test_geoid_SOURCES = test_geoid.c +test_geoid_LDADD = $(LIBC) libgps.la -lm + +# +# Build time functions tester +# +test_mkgmtime_SOURCES = test_mkgmtime.c +test_mkgmtime_LDADD = $(LIBC) libgps.la -lm + +# +# Build JSON parse tester +test_json_SOURCES = test_json.c +test_json_LDADD = $(LIBC) libgps.la -lm +MANPAGES_BASE = \ + gpsd.8 \ + gps.1 \ + cgps.1 \ + lcdgps.1 \ + libgps.3 \ + libgpsmm.3 \ + libgpsd.3 \ + gpsmon.1 \ + gpsctl.1 \ + gpspipe.1 \ + rtcm-104.5 \ + srec.5 + +@HAVE_XSLT_PROCESSOR_TRUE@MANPAGES_DIST = \ +@HAVE_XSLT_PROCESSOR_TRUE@ $(MANPAGES_BASE) \ +@HAVE_XSLT_PROCESSOR_TRUE@ $(RTCM104PAGES_DIST) \ +@HAVE_XSLT_PROCESSOR_TRUE@ $(PYTHONPAGES_DIST) + +@HAVE_XSLT_PROCESSOR_TRUE@man_MANS = \ +@HAVE_XSLT_PROCESSOR_TRUE@ $(MANPAGES_BASE) \ +@HAVE_XSLT_PROCESSOR_TRUE@ $(RTCM104PAGES) \ +@HAVE_XSLT_PROCESSOR_TRUE@ $(PYTHONPAGES) + + +# +# Create Manpages +# +@HAVE_XSLT_PROCESSOR_TRUE@BUILT_MANPAGES = $(MANPAGES_DIST) +noinst_HEADERS = gpsd_config.h \ + driver_italk.h driver_rtcm2.h driver_superstar2.h \ + driver_ubx.h gpsmon.h gpsdclient.h json.h gps_json.h \ + revision.h TachometerP.h Tachometer.h + +nodist_include_HEADERS = gpsd.h +@LIBGPSMM_ENABLE_FALSE@include_HEADERS = gps.h +@LIBGPSMM_ENABLE_TRUE@include_HEADERS = gps.h libgpsmm.h +XML = \ + gpsd.xml \ + gps.xml \ + libgps.xml \ + libgpsmm.xml \ + libgpsd.xml \ + gpsmon.xml \ + gpsdecode.xml \ + gpsprof.xml \ + gpsfake.xml \ + gpsctl.xml \ + gpscat.xml \ + gpspipe.xml \ + rtcm-104.xml \ + srec.xml + + +# Note: packaging/rpm/gpsd.spec is generated, but it needs to be in the +# tarball in order for 'make dist-rpm' to work. The BUILT_SOURCES +# files are here in order to minimize build dependencies for package +# builders who never alter anything, especially the Python dependency. +# Also note that the test and gps directories are here rather than +# being the contents of a SUBDIRS variable so that autconf won't +# go looking for makefiles in them. +EXTRA_DIST = \ + revision.h \ + autogen.sh \ + README \ + INSTALL \ + COPYING \ + TODO \ + NEWS \ + AUTHORS \ + jsongen.py.in \ + maskaudit.py.in \ + dgpsip-servers \ + test_float.c \ + test_trig.c \ + gpsd.php \ + gpsd.xml \ + gpsd.h-head \ + gpsd.h-tail \ + $(XML) \ + $(BUILT_SOURCES) \ + $(MANPAGES_DIST) \ + gpsd.rules \ + gpsd.hotplug \ + gpsd.hotplug.wrapper \ + gpsd.usermap \ + valgrind-audit \ + valgrind-suppressions \ + gpspacket.c \ + gpsclient.c \ + driver_proto.c \ + monitor_proto.c \ + setup.py \ + packet_states.h \ + libgps.pc.in \ + libgpsd.pc.in \ + gpscap.ini \ + packaging/deb/etc_default_gpsd \ + packaging/deb/etc_init.d_gpsd \ + packaging/rpm/gpsd.spec \ + packaging/rpm/gpsd.init \ + packaging/rpm/gpsd.sysconfig \ + packaging/X11/xgps.desktop \ + packaging/X11/xgpsspeed.desktop \ + packaging/X11/gpsd-logo.png \ + do-tests \ + regress-driver \ + $(PYTHONSCRIPTS_DIST) \ + $(PYTHONMODULES_DIST) \ + $(QTLIB_DIST) \ + $(QTLIB_DIST_MINGW) \ + test + +pkgconfig_DATA = libgps.pc libgpsd.pc +pkgconfigdir = $(libdir)/pkgconfig + +# Report splint warnings +SPLINTOPTS = -I/usr/include/dbus-1.0/ $(LIBUSB_CFLAGS) +quiet + +# Re-indent the codebase in a uniform style for readability. +INDENT_FILES = $(gpsd_c_sources) $(libgpsd_c_sources) $(libgps_c_sources) \ + $(cgps_SOURCES) $(gpsmon_SOURCES) $(gpspipe_SOURCES) \ + $(gpxlogger_SOURCES) $(gpsdecode_SOURCES) \ + $(test_bits_SOURCES) $(test_packet_SOURCES) \ + $(test_mkgmtime_SOURCES) $(test_geoid_SOURCES) $(test_json_SOURCES) + +INDENT_OPTIONS = --indent-level4 \ + --honour-newlines \ + --dont-break-procedure-type \ + --cuddle-else \ + --braces-on-if-line \ + --case-brace-indentation0 \ + --brace-indent0 \ + --no-space-after-casts \ + --no-space-after-function-call-names \ + --start-left-side-of-comments \ + --dont-format-comments + + +# +# Regression tests begin here +# +# Note that the *-makeregress targets re-create the *.log.chk source +# files from the *.log source files. +# +# These require gcc4; use of the math coprocessor's on-board trig functions +# apparently increases the accuracy of computation in a way that affects +# the low-order digits of the track field in the O response. + +# Our regression tests are make targets, while automake expects +# programs. Thus, our approach is to construct the test +# infrastructure our way, with make targets, and to have one TEST from +# automake's viewpoint: a trivial shell script to invoke make with our +# top-level regression target. + +# One might think that using TESTS_ENVIRONMENT=$(MAKE) would work +# around this, but because the generated rule (check-TESTS) both +# depends on each TEST as well as invokes it (with TESTS_ENVIRONMENT) +# the entire list of tests is run twice. + +# Use make REGRESSOPTS=-u to force running with UDP rather than pty devices +run_regress_driver = PYTHON=$(PYTHON) $(srcdir)/regress-driver $(REGRESSOPTS) + +# do-tests is a shell script that invokes make with target testregress. +# This works around automake's lack of support for make targets as tests. +TESTS_ENVIRONMENT = MAKE=$(MAKE) PYTHON=$(PYTHON) +TESTS = do-tests + +# We need to run epydoc with the Python version we built the modules for. +# So we define our on epydoc instead of using /usr/bin/epydoc +@HAVE_PYTHON_TRUE@EPYDOC = $(PYTHON) -c 'from epydoc.cli import cli; cli()' + +# We have pre-compiled python scripts in the script directory, so we exclude +# all files ending on c here. Needs a better solution as soon as we have a +# script ending with c. +@HAVE_PYTHON_TRUE@EPYDOCSCRIPTS = $(shell find $(PYTHON_DISTUTILS_SCRIPTDIR) -name '*c' -o -type f -print) +@HAVE_PYTHON_TRUE@EPYDOCMODULES = $(PYTHON_DISTUTILS_LIBDIR)/gps +all: $(BUILT_SOURCES) gpsd_config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .1 .3 .5 .8 .c .cpp .lo .o .obj .xml +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +gpsd_config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/gpsd_config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status gpsd_config.h +$(srcdir)/gpsd_config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f gpsd_config.h stamp-h1 +packaging/rpm/gpsd.spec: $(top_builddir)/config.status $(top_srcdir)/packaging/rpm/gpsd.spec.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +libgps.pc: $(top_builddir)/config.status $(srcdir)/libgps.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +libgpsd.pc: $(top_builddir)/config.status $(srcdir)/libgpsd.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +jsongen.py: $(top_builddir)/config.status $(srcdir)/jsongen.py.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +maskaudit.py: $(top_builddir)/config.status $(srcdir)/maskaudit.py.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +valgrind-audit: $(top_builddir)/config.status $(srcdir)/valgrind-audit.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgps.la: $(libgps_la_OBJECTS) $(libgps_la_DEPENDENCIES) + $(libgps_la_LINK) -rpath $(libdir) $(libgps_la_OBJECTS) $(libgps_la_LIBADD) $(LIBS) +libgpsd.la: $(libgpsd_la_OBJECTS) $(libgpsd_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libgpsd_la_OBJECTS) $(libgpsd_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +cgps$(EXEEXT): $(cgps_OBJECTS) $(cgps_DEPENDENCIES) + @rm -f cgps$(EXEEXT) + $(LINK) $(cgps_OBJECTS) $(cgps_LDADD) $(LIBS) +gpsctl$(EXEEXT): $(gpsctl_OBJECTS) $(gpsctl_DEPENDENCIES) + @rm -f gpsctl$(EXEEXT) + $(LINK) $(gpsctl_OBJECTS) $(gpsctl_LDADD) $(LIBS) +gpsd$(EXEEXT): $(gpsd_OBJECTS) $(gpsd_DEPENDENCIES) + @rm -f gpsd$(EXEEXT) + $(LINK) $(gpsd_OBJECTS) $(gpsd_LDADD) $(LIBS) +gpsdecode$(EXEEXT): $(gpsdecode_OBJECTS) $(gpsdecode_DEPENDENCIES) + @rm -f gpsdecode$(EXEEXT) + $(LINK) $(gpsdecode_OBJECTS) $(gpsdecode_LDADD) $(LIBS) +gpsmon$(EXEEXT): $(gpsmon_OBJECTS) $(gpsmon_DEPENDENCIES) + @rm -f gpsmon$(EXEEXT) + $(LINK) $(gpsmon_OBJECTS) $(gpsmon_LDADD) $(LIBS) +gpspipe$(EXEEXT): $(gpspipe_OBJECTS) $(gpspipe_DEPENDENCIES) + @rm -f gpspipe$(EXEEXT) + $(LINK) $(gpspipe_OBJECTS) $(gpspipe_LDADD) $(LIBS) +gpxlogger$(EXEEXT): $(gpxlogger_OBJECTS) $(gpxlogger_DEPENDENCIES) + @rm -f gpxlogger$(EXEEXT) + $(LINK) $(gpxlogger_OBJECTS) $(gpxlogger_LDADD) $(LIBS) +lcdgps$(EXEEXT): $(lcdgps_OBJECTS) $(lcdgps_DEPENDENCIES) + @rm -f lcdgps$(EXEEXT) + $(LINK) $(lcdgps_OBJECTS) $(lcdgps_LDADD) $(LIBS) +test_bits$(EXEEXT): $(test_bits_OBJECTS) $(test_bits_DEPENDENCIES) + @rm -f test_bits$(EXEEXT) + $(LINK) $(test_bits_OBJECTS) $(test_bits_LDADD) $(LIBS) +test_float$(EXEEXT): $(test_float_OBJECTS) $(test_float_DEPENDENCIES) + @rm -f test_float$(EXEEXT) + $(LINK) $(test_float_OBJECTS) $(test_float_LDADD) $(LIBS) +test_geoid$(EXEEXT): $(test_geoid_OBJECTS) $(test_geoid_DEPENDENCIES) + @rm -f test_geoid$(EXEEXT) + $(LINK) $(test_geoid_OBJECTS) $(test_geoid_LDADD) $(LIBS) +test_gpsmm$(EXEEXT): $(test_gpsmm_OBJECTS) $(test_gpsmm_DEPENDENCIES) + @rm -f test_gpsmm$(EXEEXT) + $(CXXLINK) $(test_gpsmm_OBJECTS) $(test_gpsmm_LDADD) $(LIBS) +test_json$(EXEEXT): $(test_json_OBJECTS) $(test_json_DEPENDENCIES) + @rm -f test_json$(EXEEXT) + $(LINK) $(test_json_OBJECTS) $(test_json_LDADD) $(LIBS) +test_mkgmtime$(EXEEXT): $(test_mkgmtime_OBJECTS) $(test_mkgmtime_DEPENDENCIES) + @rm -f test_mkgmtime$(EXEEXT) + $(LINK) $(test_mkgmtime_OBJECTS) $(test_mkgmtime_LDADD) $(LIBS) +test_packet$(EXEEXT): $(test_packet_OBJECTS) $(test_packet_DEPENDENCIES) + @rm -f test_packet$(EXEEXT) + $(LINK) $(test_packet_OBJECTS) $(test_packet_LDADD) $(LIBS) +test_qgpsmm$(EXEEXT): $(test_qgpsmm_OBJECTS) $(test_qgpsmm_DEPENDENCIES) + @rm -f test_qgpsmm$(EXEEXT) + $(test_qgpsmm_LINK) $(test_qgpsmm_OBJECTS) $(test_qgpsmm_LDADD) $(LIBS) +test_trig$(EXEEXT): $(test_trig_OBJECTS) $(test_trig_DEPENDENCIES) + @rm -f test_trig$(EXEEXT) + $(LINK) $(test_trig_OBJECTS) $(test_trig_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ais_json.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bits.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd-base64.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cgps.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc24q.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_aivdm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_evermore.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_garmin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_garmin_txt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_italk.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_navcom.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_nmea.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_oncore.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_rtcm2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_rtcm3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_sirf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_superstar2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_tsip.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_ubx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_zodiac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drivers.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoid.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gps_maskdump.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsd_dbus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsd_json.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsd_maskdump.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsd_report.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsdclient.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsdecode.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsmon.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpspipe.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsutils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpxlogger.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hex.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isgps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lcdgps.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgps_core.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgps_json.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgpsd_core.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgpsmm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor_italk.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor_nmea.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor_oncore.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor_sirf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor_superstar2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor_tnt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor_ubx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_dgpsip.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_gnss_dispatch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_ntrip.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netlib.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntpshm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pseudonmea.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rtcm2_json.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serial.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shared_json.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/srecord.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subframe.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_bits.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_float.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_geoid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gpsmm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_json.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_mkgmtime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_packet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_trig.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pythonPYTHON: $(python_PYTHON) + @$(NORMAL_INSTALL) + test -z "$(pythondir)" || $(MKDIR_P) "$(DESTDIR)$(pythondir)" + @list='$(python_PYTHON)'; dlist=; list2=; test -n "$(pythondir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \ + if test -f $$b$$p; then \ + $(am__strip_dir) \ + dlist="$$dlist $$f"; \ + list2="$$list2 $$b$$p"; \ + else :; fi; \ + done; \ + for file in $$list2; do echo $$file; done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pythondir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pythondir)" || exit $$?; \ + done || exit $$?; \ + if test -n "$$dlist"; then \ + if test -z "$(DESTDIR)"; then \ + PYTHON=$(PYTHON) $(py_compile) --basedir "$(pythondir)" $$dlist; \ + else \ + PYTHON=$(PYTHON) $(py_compile) --destdir "$(DESTDIR)" --basedir "$(pythondir)" $$dlist; \ + fi; \ + else :; fi + +uninstall-pythonPYTHON: + @$(NORMAL_UNINSTALL) + @list='$(python_PYTHON)'; test -n "$(pythondir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + filesc=`echo "$$files" | sed 's|$$|c|'`; \ + fileso=`echo "$$files" | sed 's|$$|o|'`; \ + echo " ( cd '$(DESTDIR)$(pythondir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pythondir)" && rm -f $$files || exit $$?; \ + echo " ( cd '$(DESTDIR)$(pythondir)' && rm -f" $$filesc ")"; \ + cd "$(DESTDIR)$(pythondir)" && rm -f $$filesc || exit $$?; \ + echo " ( cd '$(DESTDIR)$(pythondir)' && rm -f" $$fileso ")"; \ + cd "$(DESTDIR)$(pythondir)" && rm -f $$fileso +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" + @list=''; test -n "$(man1dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } +install-man3: $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)" + @list=''; test -n "$(man3dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.3[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.3[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man3dir)" && rm -f $$files; } +install-man5: $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" + @list=''; test -n "$(man5dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.5[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ + done; } + +uninstall-man5: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man5dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.5[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man5dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man5dir)" && rm -f $$files; } +install-man8: $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" + @list=''; test -n "$(man8dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man8dir)" && rm -f $$files; } +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(includedir)" && rm -f $$files +install-nodist_includeHEADERS: $(nodist_include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-nodist_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(includedir)" && rm -f $$files + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) gpsd_config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) gpsd_config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) gpsd_config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) gpsd_config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @$(am__cd) '$(distuninstallcheck_dir)' \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \ + $(HEADERS) gpsd_config.h +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(pythondir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-local \ + clean-sbinPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-local distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS install-man \ + install-nodist_includeHEADERS install-pkgconfigDATA \ + install-pythonPYTHON + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-exec-local \ + install-libLTLIBRARIES install-sbinPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 install-man3 install-man5 install-man8 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \ + uninstall-libLTLIBRARIES uninstall-man \ + uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA \ + uninstall-pythonPYTHON uninstall-sbinPROGRAMS + +uninstall-man: uninstall-man1 uninstall-man3 uninstall-man5 \ + uninstall-man8 + +.MAKE: all check check-am install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \ + clean clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-local \ + clean-sbinPROGRAMS ctags dist dist-all dist-bzip2 dist-gzip \ + dist-hook dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-local distclean-tags \ + distcleancheck distdir distuninstallcheck dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-exec-local install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-libLTLIBRARIES install-man \ + install-man1 install-man3 install-man5 install-man8 \ + install-nodist_includeHEADERS install-pdf install-pdf-am \ + install-pkgconfigDATA install-ps install-ps-am \ + install-pythonPYTHON install-sbinPROGRAMS install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-includeHEADERS uninstall-libLTLIBRARIES \ + uninstall-man uninstall-man1 uninstall-man3 uninstall-man5 \ + uninstall-man8 uninstall-nodist_includeHEADERS \ + uninstall-pkgconfigDATA uninstall-pythonPYTHON \ + uninstall-sbinPROGRAMS + +print_libgps_VERSION_CURRENT: + echo $(libgps_VERSION_CURRENT) +print_libgps_VERSION__REVISION: + echo $(libgps_VERSION__REVISION) +print_libgps_VERSION_AGE: + echo $(libgps_VERSION_AGE) +print_libgps_SONAME: + echo $(libgps_SONAME) +print_libgps_VERSION: + echo $(libgps_VERSION) + +packet_names.h: packet_states.h + rm -f packet_names.h && \ + sed -e '/^ *\([A-Z][A-Z0-9_]*\),/s// "\1",/' -e '/_states/s//_names/' < `test -f 'packet_states.h' || echo '$(srcdir)/'`packet_states.h > packet_names.h && \ + chmod a-w packet_names.h + +gpsd.h: gpsd.h-head gpsd.h-tail gpsd_config.h + rm -f gpsd.h && \ + echo "/* This file is generated. Do not hand-hack it! */" >gpsd.h && \ + cat $(srcdir)/gpsd.h-head >>gpsd.h && \ + cat $(srcdir)/gpsd_config.h >>gpsd.h && \ + cat $(srcdir)/gpsd.h-tail >>gpsd.h && \ + chmod a-w gpsd.h + +ais_json.i: jsongen.py + rm -f ais_json.i && \ + $(PYTHON) jsongen.py --ais --target=parser >ais_json.i && \ + chmod a-w ais_json.i + +revision.h: Makefile + @rm -f revision.h && \ + echo '#define' REVISION '"'`date -u +%Y-%m-%dT%H:%M:%S`'"' >revision.h && \ + chmod a-w revision.h + +gps_maskdump.c: gps.h maskaudit.py + rm -f gps_maskdump.c && \ + $(PYTHON) maskaudit.py -c >gps_maskdump.c && \ + chmod a-w gps_maskdump.c + +gpsd_maskdump.c: gpsd.h maskaudit.py + rm -f gpsd_maskdump.c && \ + $(PYTHON) maskaudit.py -d >gpsd_maskdump.c && \ + chmod a-w gpsd_maskdump.c + +# Multiple-outputs hack. See +# http://www.gnu.org/software/automake/manual/automake.html#Multiple-Outputs +@HAVE_PYTHON_TRUE@$(PYEXTENSIONS): stamp-python +@HAVE_PYTHON_TRUE@ +@WITNESS=stamp-python; $(MULTIOUT_RECOVER_DELETED) +# TODO: Should the dependency on libgps.la be enforced inside +# setup.py? (See the variable 'needed_files' in setup.py.) +@HAVE_PYTHON_TRUE@stamp-python: gpspacket.c gpsclient.c libgps.la setup.py $(PYTHONMODULES_DIST) $(PYTHONSCRIPTS_DIST) +# Build Python modules and scripts using distutils via setup.py. +# We define build-lib and build-scripts as distutils might have been +# configured to use different directories, but we want to use the +# produced files within the regress-driver script - therefore we +# need to build them in directories we know about. +# See configure.ac for the definition of PYTHON_DISTUTILS_LIBDIR +# and PYTHON_DISTUTILS_SCRIPTDIR. +@HAVE_PYTHON_TRUE@ @rm -f '$@' '$@.tmp' +@HAVE_PYTHON_TRUE@ @echo 'timestamp for $@' > '$@.tmp' +@HAVE_PYTHON_TRUE@ (cd '$(srcdir)' && \ +@HAVE_PYTHON_TRUE@ env abs_builddir='$(abs_builddir)' \ +@HAVE_PYTHON_TRUE@ MAKE='$(MAKE)' \ +@HAVE_PYTHON_TRUE@ $(PYTHON) setup.py build \ +@HAVE_PYTHON_TRUE@ --build-lib '$(srcdir)/$(PYTHON_DISTUTILS_LIBDIR)' \ +@HAVE_PYTHON_TRUE@ --build-scripts '$(srcdir)/$(PYTHON_DISTUTILS_SCRIPTDIR)' \ +@HAVE_PYTHON_TRUE@ --mangenerator '$(XMLPROC)') && \ +@HAVE_PYTHON_TRUE@ (cd '$(srcdir)/gps' && \ +@HAVE_PYTHON_TRUE@ rm -f *.so && \ +@HAVE_PYTHON_TRUE@ ln -s ../$(PYTHON_DISTUTILS_LIBDIR)/gps/*.so . ) && \ +@HAVE_PYTHON_TRUE@ mv -f '$@.tmp' '$@' + +@LIB_Q_GPSMM_ENABLE_TRUE@libQgpsmm/Makefile: libQgpsmm/libQgpsmm.pro gpsd.h ais_json.i +@LIB_Q_GPSMM_ENABLE_TRUE@ cd $(srcdir)/libQgpsmm && $(QMAKE) $(QMAKE_OPTS) +# Yet another multiple-outputs hack: +@LIB_Q_GPSMM_ENABLE_TRUE@$(QTLIBS): stamp-qt +@LIB_Q_GPSMM_ENABLE_TRUE@ +@WITNESS=stamp-qt; $(MULTIOUT_RECOVER_DELETED) +@LIB_Q_GPSMM_ENABLE_TRUE@stamp-qt: $(QTLIB_sources) libQgpsmm/Makefile +@LIB_Q_GPSMM_ENABLE_TRUE@ $(MAKE) -C $(srcdir)/libQgpsmm +@LIB_Q_GPSMM_ENABLE_TRUE@ touch $@ + +# Clean up after Python and QT +clean-local: +@HAVE_PYTHON_TRUE@ rm -rf build gps/*.so +@LIB_Q_GPSMM_ENABLE_TRUE@ if test -r $(srcdir)/libQgpsmm/Makefile; then \ +@LIB_Q_GPSMM_ENABLE_TRUE@ $(MAKE) -C $(srcdir)/libQgpsmm distclean || true; \ +@LIB_Q_GPSMM_ENABLE_TRUE@ fi +@LIB_Q_GPSMM_ENABLE_TRUE@ rm -rf $(srcdir)/libQgpsmm/binaries +@LIB_Q_GPSMM_ENABLE_TRUE@ rm -f $(srcdir)/libQgpsmm/*.o $(srcdir)/libQgpsmm/Makefile + +# Install Python modules and QT library +install-exec-local: +# Make sure we do not use --root as option to setup.py install +# when DESTDIR is not defined as distutils would use the current +# working directory as root directory and not install to ${prefix}. +@HAVE_PYTHON_TRUE@ if test -z "$(DESTDIR)"; then \ +@HAVE_PYTHON_TRUE@ $(PYTHON) setup.py install --prefix=${prefix} ;\ +@HAVE_PYTHON_TRUE@ else \ +@HAVE_PYTHON_TRUE@ $(PYTHON) setup.py install --prefix=${prefix} --root=$(DESTDIR) ;\ +@HAVE_PYTHON_TRUE@ fi +@LIB_Q_GPSMM_ENABLE_TRUE@ $(MAKE) -C libQgpsmm install INSTALL_ROOT=$(DESTDIR) + +@HAVE_XSLT_PROCESSOR_TRUE@.xml.1: +@HAVE_XSLT_PROCESSOR_TRUE@ $(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $< + +@HAVE_XSLT_PROCESSOR_TRUE@.xml.3: +@HAVE_XSLT_PROCESSOR_TRUE@ $(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $< + +@HAVE_XSLT_PROCESSOR_TRUE@.xml.5: +@HAVE_XSLT_PROCESSOR_TRUE@ $(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $< + +@HAVE_XSLT_PROCESSOR_TRUE@.xml.8: +@HAVE_XSLT_PROCESSOR_TRUE@ $(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $< + +# Another instance of the multiple-outputs hack. +@HAVE_XSLT_PROCESSOR_TRUE@gps.1 xgps.1 xgpsspeed.1 cgps.1 lcdgps.1: stamp-gps-manpages +@HAVE_XSLT_PROCESSOR_TRUE@ +@WITNESS=stamp-gps-manpages; $(MULTIOUT_RECOVER_DELETED) +@HAVE_XSLT_PROCESSOR_TRUE@stamp-gps-manpages: gps.xml +@HAVE_XSLT_PROCESSOR_TRUE@ @rm -f '$@' '$@.tmp' +@HAVE_XSLT_PROCESSOR_TRUE@ echo 'timestamp for $@' > '$@.tmp' && \ +@HAVE_XSLT_PROCESSOR_TRUE@ $(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) '$(srcdir)/gps.xml' && \ +@HAVE_XSLT_PROCESSOR_TRUE@ mv -f '$@.tmp' '$@' + +# Prepare necessary files to build the mingw-port of libQgpsmm +# while creating the dist tarball. +dist-hook: ais_json.i gpsd_config.h + $(MKDIR_P) '$(distdir)/libQgpsmm/mingw' + cp -p ais_json.i $(distdir)/libQgpsmm/mingw + grep "#define VERSION" gpsd_config.h > $(distdir)/libQgpsmm/mingw/version.h + echo "VERSION=$(libgps_VERSION)" > $(distdir)/libQgpsmm/mingw/version.pri +distclean-local: + rm -f $(distdir)/libQgpsmm/mingw/version.* $(distdir)/libQgpsmm/mingw/ais_json.i + +# These are not distributed +libgps: libgps_core.c gps.h .libs/libgps.a + $(CC) $(CFLAGS) -o libgps -lm -DTESTMAIN $(LIBPTHREAD) -g libgps_core.c .libs/libgps.a +splint: gpsd.h packet_names.h + @echo "Running splint on daemon and libraries..." + -splint $(SPLINTOPTS) -exportlocal -redef $(gpsd_c_sources) $(libgpsd_c_sources) $(libgps_c_sources) + @echo "Running splint on cgps..." + -splint $(SPLINTOPTS) -exportlocal $(cgps_SOURCES) + @echo "Running splint on gpsctl..." + -splint $(SPLINTOPTS) $(gpsctl_SOURCES) + @echo "Running splint on gpsmon..." + -splint $(SPLINTOPTS) -exportlocal $(gpsmon_SOURCES) + @echo "Running splint on gpspipe..." + -splint $(SPLINTOPTS) $(gpspipe_SOURCES) + @echo "Running splint on gpsdecode..." + -splint $(SPLINTOPTS) $(gpsdecode_SOURCES) + @echo "Running splint on gpxlogger..." + -splint $(SPLINTOPTS) $(gpxlogger_SOURCES) + @echo "Running splint on test_bits test harness..." + -splint $(SPLINTOPTS) $(test_bits_SOURCES) + @echo "Running splint on test_packet test harness..." + -splint $(SPLINTOPTS) $(test_packet_SOURCES) + @echo "Running splint on test_mkgmtime test harness..." + -splint $(SPLINTOPTS) $(test_mkgmtime_SOURCES) + @echo "Running splint on test_geoid test harness..." + -splint $(SPLINTOPTS) $(test_geoid_SOURCES) + @echo "Running splint on test_json test harness..." + -splint $(SPLINTOPTS) $(test_json_SOURCES) + +# Report cppcheck warnings. Requires 1.40 or later. +cppcheck: gpsd.h packet_names.h + cppcheck --template gcc --all --force . + +# Check the documentation for bogons, too +xmllint: $(XML) + for xml in $(XML); do xmllint --nonet --noout --valid $$xml; done +indent: + chmod u+w *maskdump.c + indent $(INDENT_OPTIONS) $(INDENT_FILES) + for f in $(INDENT_FILES); \ + do \ + sed <$${f} >/tmp/reindent$$$$ -e 's/@ \*/@*/' ; \ + mv /tmp/reindent$$$$ $${f} ; \ + done + chmod u-w *maskdump.c + @echo "Diff lines:" `git diff | wc -l` + +version: + @echo $(VERSION) + +# Regression-test the daemon +gps-regress: gpsd stamp-python + $(run_regress_driver) $(srcdir)/test/daemon/*.log + +# Test that super-raw mode works. Compare each logfile against itself +# dumped through the daemon running in R=2 mode. (This test is not +# included in the normal regressions.) +raw-regress: stamp-python + $(run_regress_driver) -r $(srcdir)/test/daemon/*.log + +# Build the regression tests for the daemon. +gps-makeregress: gpsd stamp-python + $(run_regress_driver) -b $(srcdir)/test/daemon/*.log + +# To build an individual test for a load named foo.log, put it in +# test/daemon and do this: +# regress-driver -b test/daemon/foo.log + +# Regression-test the RTCM decoder. +rtcm-regress: gpsdecode + @echo "Testing RTCM decoding..." + @mkdir -p test + @for f in $(srcdir)/test/*.rtcm2; do \ + echo "Testing $${f}..."; \ + $(srcdir)/gpsdecode <$${f} >/tmp/test-$$$$.chk; \ + diff -ub $${f}.chk /tmp/test-$$$$.chk; \ + done; + @echo "Testing idempotency of JSON dump/decode for RTCM2" + @$(srcdir)/gpsdecode -e -j /tmp/test-$$$$.chk; \ + grep -v '^#' test/synthetic-rtcm2.json | diff -ub - /tmp/test-$$$$.chk; \ + rm /tmp/test-$$$$.chk + +# Rebuild the RTCM regression tests. +rtcm-makeregress: gpsdecode + @for f in $(srcdir)/test/*.rtcm2; do \ + $(srcdir)/gpsdecode -j < $${f} > $${f}.chk; \ + done + +# Regression-test the AIVDM decoder. +aivdm-regress: gpsdecode + echo "Testing AIVDM decoding..." + @mkdir -p $(srcdir)/test + @for f in $(srcdir)/test/*.aivdm; do \ + echo "Testing $${f}..."; \ + $(srcdir)/gpsdecode -u -c <$${f} >/tmp/test-$$$$.chk; \ + diff -ub $${f}.chk /tmp/test-$$$$.chk; \ + done; + @echo "Testing idempotency of JSON dump/decode for AIS" + @$(srcdir)/gpsdecode -e -j <$(srcdir)/test/synthetic-ais.json >/tmp/test-$$$$.chk; \ + grep -v '^#' $(srcdir)/test/synthetic-ais.json | diff -ub - /tmp/test-$$$$.chk; \ + rm /tmp/test-$$$$.chk + +# Rebuild the AIVDM regression tests. +aivdm-makeregress: gpsdecode + @for f in $(srcdir)/test/*.aivdm; do \ + $(srcdir)/gpsdecode -u -c <$${f} > $${f}.chk; \ + done + +# Regression-test the packet getter. +packet-regress: test_packet + @echo "Testing detection of invalid packets..." + @$(srcdir)/test_packet | diff -u $(srcdir)/test/packet.test.chk - + +# Rebuild the packet-getter regression test +packet-makeregress: test_packet + @mkdir -p $(srcdir)/test + $(srcdir)/test_packet >$(srcdir)/test/packet.test.chk + +# Regression-test the geoid tester. +geoid-regress: test_geoid + @echo "Testing the geoid model..." + @$(srcdir)/test_geoid 37.371192 122.014965 | diff -u $(srcdir)/test/geoid.test.chk - + +# Rebuild the packet-getter regression test +geoid-makeregress: test_geoid + @mkdir -p $(srcdir)/test + $(srcdir)/test_geoid 37.371192 122.014965 >$(srcdir)/test/geoid.test.chk + +# Regression-test the calendar functions +time-regress: test_mkgmtime + $(srcdir)/test_mkgmtime + +# Regression test the unpacking code in libgps +unpack-regress: libgps + @echo "Testing the client-library sentence decoder..." + $(run_regress_driver) -c $(srcdir)/test/clientlib/*.log + +# Build the regression test for the sentence unpacker +unpack-makeregress: libgps + @echo "Rebuilding the client sentence-unpacker tests..." + $(run_regress_driver) -c -b $(srcdir)/test/clientlib/*.log + +# Unit-test the JSON parsing +json-regress: test_json + $(srcdir)/test_json + +# Unit-test the bitfield extractor - not in normal tests +bits-regress: test_bits + $(srcdir)/test_bits + +# Do all normal regression tests. +testregress: gps-regress rtcm-regress aivdm-regress packet-regress time-regress unpack-regress json-regress + @echo "Regressions complete." + +# The website directory +# +# None of these productions are fired by 'make all'. + +@XMLTOSTDOUT_TRUE@www/%.html: %.xml +@XMLTOSTDOUT_TRUE@ $(XMLPROC) $(XMLPROCFLAGS) $(HTMLTARGET) $< >$(<:.xml=.html) ; cp $(<:.xml=.html) $@ +@XMLTOSTDOUT_FALSE@www/%.html: %.xml +@XMLTOSTDOUT_FALSE@ $(XMLPROC) $(XMLPROCFLAGS) $(HTMLTARGET) $<; cp $(<:.xml=.html) $@ + +website: www/gpscat.html www/gpsctl.html www/gpsdecode.html \ + www/gpsd.html www/gpsfake.html www/gpsmon.html \ + www/gpspipe.html www/gpsprof.html www/gps.html \ + www/libgpsd.html www/libgpsmm.html www/libgps.html \ + www/rtcm-104.html www/srec.html \ + www/AIVDM.html www/NMEA.html \ + www/protocol-evolution.html www/protocol-transition.html \ + www/client-howto.html www/writing-a-driver.html \ + www/index.html www/hardware.html \ + www/performance/performance.html \ + www/internals.html + +www/AIVDM.html: www/AIVDM.txt + asciidoc -a toc -o www/AIVDM.html www/AIVDM.txt + +www/NMEA.html: www/NMEA.txt + asciidoc -a toc -o www/NMEA.html www/NMEA.txt + +www/protocol-evolution.html: www/protocol-evolution.txt + asciidoc -a toc -o www/protocol-evolution.html www/protocol-evolution.txt + +www/protocol-transition.html: www/protocol-transition.txt + asciidoc -a toc -o www/protocol-transition.html www/protocol-transition.txt + +www/client-howto.html: www/client-howto.txt + asciidoc -a toc -o www/client-howto.html www/client-howto.txt + +www/writing-a-driver.html: www/writing-a-driver.xml + xmlto xhtml-nochunks www/writing-a-driver.xml; mv writing-a-driver.html www + +www/index.html: www/index.html.in + sed -e "/@DATE@/s//`date '+%B %d, %Y'`/" www/index.html + +www/hardware.html: www/hardware-head.html gpscap.ini www/hardware-tail.html + (cat www/hardware-head.html; python gpscap.py; cat www/hardware-tail.html) >www/hardware.html + +www/performance/performance.html: www/performance/performance.xml + (cd www/performance; xmlto xhtml-nochunks performance.xml) + +www/internals.html: $(shell ls doc/*.xml) + cd doc; xmlto xhtml-nochunks explanation.xml; cp explanation.html ../www/internals.html + +# Experimenting with pydoc. Not yet fired by any other productions. + +@HAVE_PYTHON_TRUE@pydoc: www/pydoc/index.html + +@HAVE_PYTHON_TRUE@www/pydoc/index.html: gps gpsfake gpscat gpsprof stamp-python +@HAVE_PYTHON_TRUE@ mkdir -p www/pydoc +@HAVE_PYTHON_TRUE@ $(EPYDOC) -v --html --graph all -n GPSD $(EPYDOCSCRIPTS) $(EPYDOCMODULES) -o www/pydoc + +# Productions for setting up and performing udev tests. +# +# Requires root. Do "udev-install", then "tail -f /var/run/syslog" in +# another window, then run 'make udev-test', then plug and unplug the +# GPS ad libitum. All is well when you get fix reports each time a GPS +# is plugged in. + +udev-install: + cp $(srcdir)/gpsd.rules /lib/udev/rules.d/025_gpsd.rules + cp $(srcdir)/gpsd.hotplug $(srcdir)/gpsd.hotplug.wrapper /lib/udev/ + chmod a+x /lib/udev/gpsd.hotplug /lib/udev/gpsd.hotplug.wrapper + +udev-uninstall: + rm -f /lib/udev/{gpsd.hotplug,gpsd.hotplug.wrapper} + rm -f /lib/udev/rules.d/025_gpsd.rules + +udev-test: + $(srcdir)/gpsd -N -F /var/run/gpsd.sock -D 4 + +# Release machinery begins here +# + +# Make RPM from the specfile in packaging +dist-rpm: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + rpmbuild -ta $(distdir).tar.gz + $(am__remove_distdir) + +# This is how to ship a release to Berlios incoming. +# It requires developer access verified via ssh. +# +upload-ftp: dist + shasum gpsd-$(VERSION).tar.gz >gpsd.sum + lftp -c "open ftp://ftp.berlios.de/incoming; mput gpsd-$(VERSION).tar.gz gpsd.sum" + +# +# This is how to tag a release. +# It requires developer access verified via ssh. +# +release-tag: + git tag -s -m "Tagged for external release $(VERSION)" release-$(VERSION) + git push --tags + +# +# Ship a release, providing all regression tests pass. +# The clean is necessary so that dist will remake revision.h +# with the current revision level in it. +# +ship: testregress clean dist upload-ftp release-tag + +.PHONY: print_libgps_VERSION_CURRENT \ + print_libgps_VERSION__REVISION \ + print_libgps_VERSION_AGE \ + print_libgps_SONAME \ + print_libgps_VERSION \ + pydoc + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..3bc6eab --- /dev/null +++ b/NEWS @@ -0,0 +1,588 @@ +* Tue Jul 13 2010 Eric S. Raymond - 2.95 + The autonomous robot submarine total world domination release! + Rationalize clearing and generation of DOPs, this makes epx/epy much + more generally available. Fixed the test productions for the udev + magic and added a troubleshooting note in INSTALL. cgps now displays + epx/epy rather than eph. Speed is now always reported if our last + two fixes were good, even if the GPS didn't compute it. Reading + packets from UDP datagrams by specifying a listening address and + port is now supported, and the regression-test driver cam now be + told to force this with -u; this enables regression testing in + chroot jails where access to ptys is locked out. AIS code now + interprets message type 6 and 8 application IDs correctly as a + Designated Area Code and Functional ID pair. gpspipe has a new -T + option for setting the timestamp format. xgpsspeed is completely + rewritten in Python, eliminating some dependencies on ancient X + libraries. We now ship a Qt binding for the client library. Note + a GCC 4.2.1 optimizer bug. gpsdcode now uses | as a field separator + in -c mode, as string fields can contain commas. Corrected error + or reporting of AIS rate-of-turn fields. + +* Tue Apr 20 2010 Eric S. Raymond - 2.94 + Error-checking in the 50bps subframe code has been greatly improved. + The Garmin GPS driver can now use libusb, if it is present, to do + device discovery. The libgps library has been split apart; the + service functions used by the daemon now live in libgpsd. This + will shave some code volume from GPSD client applications. A packaging + error that resulted in xgps not being shipped in 2.93 has been + corrected. We now have stronger checking for valid ephemeris before + extracting the leap-second offset; they should prevent many cases + where gpsd might previously have used an invalid leap-second offset. + +* Fri Apr 16 2010 Eric S. Raymond - 2.93 + Support for JSON dumping and parsing of AIS message types 25 and 26, + not yet observed in the wild on AISHub. Fix Debian bug #569703. by + removing non-streaming mode from the Python exerciser. Fix Debian + bug #572900 by unsetting the appropriate in-use flag in the device + array. Change the libgps default from old protocol to JSON. Add a + close() method to the C++ binding. Try to recover better from + sporadic cases of false matches to Trimble packet format from a SiRF + binary datastream. gps_poll() now returns -1 with errno not set when + the gpsd socket closes. TPV now refrains from reporting fields the + fix quality won't support. gpsmon option for listing device types is + now -L to -l can be used to enable logging (to stay consistent with + the l command). There is new FAQ material on improving fix and time + reference accuracy. New sections have been added to NMEA.txt on + error status indications and satellite IDs. New POLL command brings + back polling-mode operation. A Client-HOWTO has been added to the + documentation. gpsd no longer eats CPU when a device is unexpectedly + unplugged. Support for the TNT revolution is back (run mode only). + There is now a gpsdfake diagnostic tool that fakes being gpsd shipping + arbitrary specified data to clients. + +* Wed Mar 3 2010 Eric S. Raymond - 2.92 + Fix a packaging error. The new Python library module was + inadvertently omitted from the 2.91 tarball. Also, improve the json + import test slightly. + +* Mon Mar 1 2010 Eric S. Raymond - 2.91 + We have support for NMEA GLONASS sentences, and a regression test. + Clients now get a DEVICE notification on every driver switch. It is + possible to specify a TCP/IP AIS feed such as AISHub as a data + source. Serious bitrot in the NTRIP support has been fixed - it was + probably nonfunctional for several releases before this. Fixed + buggy display of satellite-used flags in cgps. xgps is replaced by + a rewrite in Python that uses pygtk, eliminating a dependency on + Motif; also, it now displays AIS information. Uniform treatment of + display-unit defaulting and -u in xgps, cgps, and lcdgps. Support + for AIS message types 25 and 26. Support for IPv6. A numeric + instability in the earth_distance() function affecting track error + modeling has been fixed. Old protocol has been removed from the + daemon; the library still speaks it. + +* Fri Dec 4 2009 Eric S. Raymond - 2.90 + GPSD-NG, the new JSON-based command protocol, is now deployed; as a + consequence, AIS is now fully supported in both daemon and client. + Detection of end of a fix-reporting cycle is now reliable; + accordingly data is accumulated from cycle start and the "J" + (nojitter) option on both server and client side is gone. We have + abandoned the gpsflash subproject since it has become apparent that + we can't do it without more vendor cooperation than we're likely to + get. Increase major version of shared library due to significant API + change. Added new driver for Motorola Oncore receivers, with help + from Håkan Johansson. gpsfake can now accept multiple logfiles, + interleaving test sentences from each. gpsd now accepts error + estimates from the NMEA $GPGBS sentence. + +* Wed Mar 18 2009 Eric S. Raymond - 2.39 + Fixed potential core dump in C client handling of "K" responses. + Made device hotplugging work again; had been broken by changes in udev. + Introduced major and minor API version symbols into the public interfaces. + The sirfmon utility is gone, replaced by gpsmon which does the same + job for multiple GPS types. Fixed a two-year old error in NMEA parsing + that nobody noticed because its only effect was to trash VDOP values from + GSA sentences, and gpsd computes those with an internal error model + when they look wonky. cgpxlogger has been merged into gpxlogger. + Speed-setting commands now allow parity and stop-bit setting if the + GPS chipset and adaptor can support it. Specfile and other packaging + paraphenalia now live in a packaging subdirectory. rtcmdecode becomes + gpsdecode and can now de-armor and dump AIDVM packets. The client + library now works correctly in locales where the decimal separator is + not a period. + +* Tue Feb 10 2009 Eric S. Raymond - 2.38 + Regression test load for RoyalTek RGM3800 and Blumax GPS-009 added. + Scaling on E error-estimate fields fixed to match O. Listen on + localhost only by default to avoid security problems; this can be + overridden with the -G command-line option. The packet-state machine + can now recognize RTCM3 packets, though support is not yet complete. + Added support for ublox5 and mtk-3301 devices. Add a wrapper around + gpsd_hexdump to save CPU. Lots of little fixes to various packet + parsers. Always keep the device open: "-n" is not optional any more. + xgpsspeed no longer depends on Motif. gpsctl can now ship arbitrary + payloads to a device. It's possible to send binary through the + control channel with the new "&" command. Experimental new driver + for Novatel SuperStarII. The 'g' mode switch command now requires, + and returns, 'rtcm104v2' rather than 'rtcm104'; this is design forward + for when RTCM104v3 is fully working. + +* Sun Feb 17 2008 Chris Kuethe - 2.37 + The C++ bindings, Garmin USB support, and multiple instances of ntp + pps thread starting were fixed. Handling of odd PPS signals was + improved. The eye candy in the PHP visualizers was fixed. + +* Tue Jan 1 2008 Eric S. Raymond - 2.36 + Urgent fix to leap-day calculation affecting dates from today to + 28 Feb on generic NMEA GPSes, Zodiacs, and SirFs emitting message 0x62. + Integrated Garmin Simple Text Protocol driver from Peter Slansky. + Minor fixes in error modeling and a better NaN guard stabilize the + Trimble regression tests. Remove the wired-in NTP time offset from the + NMEA driver, this could only have worked by accident and should be + set in ntpd.conf. Integrated Ashtech driver from Chris Kuethe. + +* Mon Dec 10 2007 Eric S. Raymond - 2.35-1 + Navcom driver merged. Removed -d -f and -p options of gpsd; these + have been undocumented for a while. Make gpsd play well with pkgconfig. + Incorrect computation of VDOP when GPSes didn't supply it has been fixed. + The xgps code has been revamped and now has a much nicer interface. + Add -b (no-configuration) option as a sadly clumsy workaround for some + problems with Bluetooth receivers. Added tests for Haicom-305N and Pharos + 360; separated out the tests for the unstable Trimble drivers. + 32-vs-64-bit problems in the regression tests have been solved. + +* Thu Dec 14 2006 Eric S. Raymond - 2.34-1 + Fix for byte-swapping of Zodiac control messages on big-endian hardware. + Disable iTalk by default and note that it needs to be tested. Command line + arguments can now be DGPSIP or NTRIP URLs; -d is deprecated. Added udev + rules. Address excessive processor and memory utilization on SBCs; it's + now possible to configure compile-time limits on the number of devices + and client sessions. Eliminate use of fuser(1) in gpsfake. Get gpsd + working with EarthMates again, this had been broken since 2.15. Massive + string safety audit and OpenBSD port by Chris Kuethe. J command added. + The gpsctl and gpscat tools and the gpsd.phps script were added. Switched + to lesstif from openmotif. Better autodetection of DLE-led packet + protocols (notably TSIP and Garmin binary) and of SiRFStar I and III + devices. Fixed buggy parsing and generation of PGRME. + +* Fri Jun 9 2006 Eric S. Raymond - 2.33-1 + Fix bad unit conversion in V output. Clean up some man-page messes. + Fixed buggy libgps parsing of multiple responses. It's now possible + to lock gpsd to a fixed speed at compile time for embedded use. Added + NTRIP support, thanks to Ville Nuorvala. O command now ships an + explicit mode field. + +* Sun Mar 12 2006 Eric S. Raymond - 2.32-1 + Cleanup of the xgps layout, and minor memory-leak fixes for xgps. Fix + to cope with Antares uBlox by Andreas Stricker. Minor fix to libgps + cgpxlogger. Merge cgpxlogger and gpxlogger documentation onto + the xgps(1) manual page and rename it gps(1). + +* Fri Feb 17 2006 Eric S. Raymond - 2.31-1 + Now builds and runs under Cygwin. Correct the speed units in + synthetic NMEA. Slightly better time handling under NMEA. Daemon + now builds with all but NMEA disabled. Update the leap-second + offset. cgpxlogger introduced. Upgrade gpxlogger to DBUS 0.60 + conformance. Jason von Nieda's patch may fix the chronic TSIP + driver problems. + +* Wed Sep 14 2005 Eric S. Raymond - 2.30-1 + Prevent core dump on -d option. The .log extension is no longer required for + test loads. cgps and xgps now have configurable latitude/longitude formats + via the -l option. Introduced new 'g' command that allows clients to + specify whether they want GPS or RTCM104 information. + +* Fri Aug 19 2005 Eric S. Raymond - 2.29-1 + Added Sony CXD2951 support, untested. All error estimates are + now nailed to 95% confidence interval. Added rtcmdecode and its + documentation; also, gpsd can now monitor serial devices emitting + RTCM104 and display differential-GPS data in a readable format. + Added dangerous alpha version of gpsflash. Work around a nasty bug + in SiRFStar III firmware version < 3.1.1. Added support for True + North Technologies Revolution 2X Digital compass. Added the + gpxlogger client for systems with DBUS support and the gpspipe + and cgps clients for general use. + +* Wed Jul 6 2005 Eric S. Raymond - 2.28-1 + The 2.27 source tarball somehow got truncated on upload. + Due to procedural mechanics at berlios.de, shipping a new release + seems to be the least painful way to recover. This release is + identical to 2.27 except the roadmap stuff has been added to TODO. + +* Wed Jul 06 2005 Eric S. Raymond - 2.27 + Arrange for the daemon to remove its pid file on exit. Fix some + buffering problems with the Python side of the hotplug interface. + gpsfake can now run sessions under a monitor like Valgrind. Most + of the gpsfake logic now lives in a module that can be used to write + other test loads; its progress baton is now optional. Fixed + some minor bugs found by valgrind audit, including (1) a slow + memory leak, (2) a possible but unconfirmed file-descriptor leak, + and (3) a subtle error in the channel-assignment logic that only + showed up with multiple sessions active. In fact, the daemon code + no longer uses dynamic-memory allocation at all. Also, the code + no longer relies on FIONREAD working. The track error field in the + O response is now computed. The project website has some new eye candy. + Client connections now time out when the mode is neither raw nor watcher. + Fixed a core-dump that could happen if C, B or I commands were issued + at odd times. + +* Wed Jun 22 2005 Eric S. Raymond - 2.26 + Time DOP and total DOP are now passed on from GPSes that report + them. Ensure longitude has a leading zero when <100, for + compatibility with gpsdrive. Synchronous and thread hooks are now + separate in the client library. Packet-sniffing on a new device no + longer holds up incoming data on already-connected ones. There is + now a super-raw mode (R=2) that dumps a hex-encoding of every binary + packet received to the client; sirfmon uses it to operate through + the daemon if one is running. Support for Trimble TSIP GPSes + merged. gpsfake now works with SiRF and Zodiac logs. Python library + supports thread callbacks. New -p option of gpsfake supports + regression testing of the daemon, and there is a test suite included + with the distribution. PPS support is turned off, as there is some + pthreads problem that sometimes kills the daemon on pthreads exit. + Correct off-by-one error in GPZDA processing. The code has been + audited and cleaned with splint (www.splint.org). + +* Sat May 21 2005 Eric S. Raymond - 2.25-1 + Various signedness and scaling fixes and an OpenBSD port patch for the + Zodiac driver. Command-line arguments to gpsd are now treated as a default + device list; -f is still supported but deprecated. sirfmon now tries not + changing the line speed first, so it syncs up much faster. Prevent a + potential buffer overrun in the client library. PPS-thread support is now + on by default. Lots of documentation improvements. D-BUS broadcast support + by Amaury Jacquot. Added Alfredo Pironti's thread-callback and C++ + support. gpsd no longer uses the system clock for anything, so it + can be used to set that clock. + +* Tue May 17 2005 Eric S. Raymond - 2.24-1 + Crazy-speed bug is finally fixed. Autobauding now starts with the + current speed of the device, not the stored gpsd speed; this means + hunting only takes place when device and GPS speed aren't matched. + xgpsspeed unit-conversion bug introduced in 2.22 is fixed. Satellite + display now really shows 12 channels, not just 11. Major improvements + in ntp notifications. + +* Wed May 4 2005 Eric S. Raymond - 2.23-1 + For better security, the daemon now drops root privileges after startup. + gpsd-clients is now a separate RPM; this is helpful on lean systems + that don't run X. The O command now reports speeds in meters per second + rather than knots, client code has been adjusted so there is no user-visible + change. We now compute the missing components of DOP when using SiRF chips. + /dev/gps is no longer special; there is no default GPS device unless you + specify one. The intermittent processor-hogging problem introduced by the + control-channel change in 2.21 has been solved. + +* Mon Apr 25 2005 Eric S. Raymond - 2.22-1 + SiRF-binary driver can now get leap-second corrections from subframe data. + Device add/delete commands now send back OK or ERROR. Error-modeling + corrections from the SiRF folks. Higher precision in position reports. + +* Tue Apr 12 2005 Eric S. Raymond - 2.21-1 + Add tag and timestamp to Y response. Use computed geoid separation as + SiRF packet 42 is flaky. Security fix: hotplug scripts now do device + add/removes through a separate local control channel. True multi-device + support is in place. When in watcher mode, device switches are announced. + +* Thu Mar 31 2005 Eric S. Raymond - 2.20-1 + Rob Janssen's patches to fix timezone issues and improve cooperation + with NTP. License changed to BSD so linking to libgps won't make people + nervous. gpsprobe and gpsd.py are obsolete and have been removed, the + autoprobe and profiling capabilities in the daemon more than replace + them. gpsprof now ships self-contained GNUPLOT scripts to stdout, + so they can be saved and redisplayed. Zodiac sort of works again, but + occasionally spins madly during autobauding. + +* Sat Mar 26 2005 Eric S. Raymond - 2.19-1 + Fix brown-paper-bag bug with NMEA parsing. Set SiRF GPSes to use + SBAS. sirfmon now displays SBAS parameters, and is included in the + installed programs. Add to FAQ a fix for spurious high speeds reported + in XTrac mode. We now interpret GPZDA. We no longer fudge a missing + ddmmyy in NMEA timestamps from the system clock, so replay will work better. + +* Wed Mar 23 2005 Eric S. Raymond - 2.18-1 + First cut at cooperating with NTP. Major library restructuring; + a fix is now a data structure of its own, and per-field timestamps + are gone. Use new 'o' command for watcher mode. Compute some estimated + error bounds. + +* Wed Mar 16 2005 Eric S. Raymond - 2.17 + Fix packet-engine problem that made disconnect/reconnect unreliable + (important!). Fix bonehead error in interpretation of PGRME. We + don't use O_SYNC (it turned out not to be reliable) so remove it to make + life easier under Mac OS X. Allow gpsfake to accept subsecond cycle times. + Add a FAQ to the HTML documentation. gps_poll() now handles multi-line + responses. Add N command for switching driver modes. + +* Fri Mar 11 2005 Eric S. Raymond - 2.16-1 + New F command allows changing the GPS device after startup time. + Hotplug scripts to go with it are now installed by the RPM. The + Garmin probe is working. The -T and -s options are gone. We have + achieved zero configuration! + +* Wed Mar 02 2005 Eric S. Raymond - 2.15-1 + A new packet engine autobauds much more quickly, and now iterates + over both 1 and 2 stopbits. Explicit support for FV18 (the -T f + option) is gone; instead, gpsd syncs with any 7N2 device and always + ships a suitable init string. New E command, supporting the Garmin + position-error sentence or computing these numbers from DOP and an + error model. New U command reports climb/sink from GPSes that report + vertical velocity. There is a prototype driver for SiRF-binary GPses, + invoked automatically when SiRF packets present themselves on the + wire after device open. + +* Fri Feb 25 2005 Eric S. Raymond - 2.14-1 + Pass zero magnetic variation in generated NMEA from binary GPSes + correctly. Use O_SYNC rather than timeouts to guarantee that + baud-rate change strings get to the GPS before changing the line + parameters. Introduced I command. Spatial scattergram plotting + moved from gpsprobe to gpsprof. + +* Mon Feb 21 2005 Eric S. Raymond - 2.13-1 + Correct a bug in binary-protocol dumping (applies to Zodiac and + Garmin only). Gary Miller's patch to deal gracefully with GPSes + like the Magellan EC10X that send only GPRMC and never GPGGA or + GPGSA, and thus never set mode or status fields. Fixed buggy + handling of units options in xgps and xgpsspeed. Bumped library + major version, since seen_sentences is now exposed and drivers have + more capabilities. Stricter NMEA buffer validation. Withdrew the + change that always passed up a timestamp; on SiRF receivers, the year + part is garbage when the PVT fields are garbage. Can now recognize + SiRF GPSes. Experimental baud-switching support for Zodiac. + +* Tue Feb 15 2005 Eric S. Raymond - 2.12-1 + Fixed core-dump bug in processing of the GLL variant that does not + include an FAA Mode Indicator. When using the NMEA driver, gpsd now + hunts for a baud rate rather than requiring a fixed one to be set. + A new 'B' command returns the RS232 parameters, and a new 'C' + command returns the update cycle time. Added gpsfake test harness. + Alpha driver for Garmin binary protocol added, requires Linux + garmin_usb kernel driver. The daemon now always passes up a + timestamp for every sentence that has one, even if the PVT fields + aren't valid. + +* Thu Feb 10 2005 Eric S. Raymond - 2.11-1 + Added gpsprof and the capability to generate GPS latency profiles. + gpsprobe now hunts through plausible baud rates when looking for NMEA + data from a GPS. The -b (baudrate) option fixes a speed, disabling + the baud-matching logic. Also, gpsprobe can now recognize SiRF + protocol, though not speak it. Fixed a math domain error in + gps.EarthDistance due to numeric blowup on points very close together, + and another in gps.MeterOffset() that was screwing up gpsprobe plots. + +* Tue Feb 1 2005 Eric S. Raymond - 2.10 + Add -N option to explicitly foreground the daemon. Fixed a bug + that was causing gpsd to keep reopening the GPS device after + leaving raw or watcher mode. Fixed Gary Miller's core-dump bug. + +* Thu Jan 27 2005 Eric S. Raymond - 2.9-1 + Python files restored to RPM. + +* Thu Jan 27 2005 Eric S. Raymond - 2.8-1 + Embarrassing typo fix in gps.py. Avoid buffer overrun in xgps.c. + Plug Debian security bug 292347, CVE number CAN-2004-1388. + This version issued on an emergency basis without Python libraries, + which have packaging problems due to the 2.3/2.4 transition. + +* Fri Jan 14 2005 Eric S. Raymond - 2.7-1 + More compiler-warning cleanups. gps client name changed to xgps. + Added --speedunits option to xgpsspeed, --speedunits and --altunits + options to xgps. Improved GPGSV parsing so it copes gracefully if + we start in the middle of a sequence. Merged Petter Reinholdtsen's + fix for GPGSA lists with holes. In xgps, satellites used in the + last fix are now dotted in the middle. New -P option to create + pidfile. Audited for potential buffer overruns, found and fixed + two. + +* Sat Jan 01 2005 Eric S. Raymond - 2.6-1 + Petter Reinholdtsen's fix for gps.py buffering. Fix syntax errors + in udev scriptlets. Clean up after GCC warning messages. Drop use of + vsprintf, so we get a link-time error on systems that might produce + buffer overruns (all modern Unixes support vsnsprintf which is safe). + +* Thu Dec 23 2004 Eric S. Raymond - 2.5.1 + Use gmtime instead of localtime when guessing the day or year of a date; + this avoids jitter in the day after 19:00 GMT. Added -v option to dump + version and exit. Commented out a crash-causing debug line in gps.py. + +* Thu Dec 9 2004 Eric S. Raymond - 2.4-1 + Minor bugs in gpsd.py fixed. M now returns 0 status if GPGSA not yet + seen; this change also fixes a bug where gpsd claimed it was confused + if GPGSA had not been seen and status was set. RPM will now install + a udevd rule if the host system uses it. Don't set the online flag + on activate. HP port changes and -Wall cleanup. James Cameron's + fixes to clean up gps.c and use X timeouts rather than alarms. + +* Mon Oct 25 2004 Eric S. Raymond - 2.3-1 + Documentation and comment fixes. Last two globals removed from + low-level interface; library should now be fully re-entrant. Mac OS X + port fixes. Q command fix from Robin L Darroch . + +* Mon Oct 18 2004 Eric S. Raymond - 2.2-1 + Documentation improvements. BSD port fixes. Bug fix: speed timestamp + wasn't initialized properly in libgps. Device is now an optional + command-line argument of gpsprobe, in line with the clients. gpsd.py + now should handle fvwm devices correctly. Values in gps data + panel are now labeled with units. Attempted fix for 2.1 bug of DTR + not being pulled low on exit. + +* Thu Sep 30 2004 Eric S. Raymond - 2.1-1 + Various internal cleanups, including fossil removal in the + configuration machinery. FV-18, Tripmate, Earthmate and are now + enabled but can be disable with --disable-$NAME at configure time. + When you call configure with --disable-shared, libgps is linked + statically to the binaries (native libs are still linked + shared). Fixed buggy handling of -p option in gps.c and xgpsspeed.c; + it's now an optional command-line argument. + +* Thu Sep 16 2004 Eric S. Raymond - 2.0-1 + Packaging fixes for 2.0 release. + +* Wed Sep 8 2004 Eric S. Raymond - 1.98-1 + Only do one getdtablesize() call, otherwise we do several + getrlimits() each poll cycle. TripMate is working. gpsprobe now + deduces NMEA version. Zodiac Earthmate seems to work. + +* Wed Sep 08 2004 Eric S. Raymond - 1.97-1 + Removed PRWIZCH support (it still passes through in raw mode). + Build Motif-dependent programs conditionally. Added gpsprobe. + Fixed a brown-paper-bag-bug in 1.96 RPM packaging. + +* Tue Aug 31 2004 Eric S. Raymond - 1.96-1 + Implemented non-blocking writes to clients, so a stalled client + cannot stall gpsd. Fixed a nasty array-overrun bug. Timestamps + are now in ISO8601 format, with sub-second precision if the GPS + delivers that. First cuts at Python interfaces included. libgps.a + interface now bundles session fd into an allocated session block. + Automake-based build machinery from Jens Oberender; RPM now + installs shared libraries. FV18 driver added. Offline timer in GPS. + +* Wed Aug 25 2004 Eric S. Raymond - 1.95-1 + Fixed broken 'make dist', missing display.c and Tachometer.c + are in there now. + +* Tue Aug 24 2004 Eric S. Raymond - 1.94-1 + Fix embarrassing bug -- watcher mode did not work for more than one + client at a time. Y command now carries information about which + satellites were used in the last fix. New timeout mechanism, no + longer dependent on FIONREAD. + +* Mon Aug 23 2004 Eric S. Raymond - 1.93-1 + Fourth prerelease. Daemon-side timeouts are gone, they complicated + the interface without adding anything. Command responses now + contain ? to tag invalid data. -D2 feature of 1.92 backed out. + +* Sun Aug 22 2004 Eric S. Raymond - 1.92-1 + Third prerelease. Clients in watcher mode now get notified when + the GPS goes online or offline. Major name changes -- old libgps + is new libgpsd and vice-versa (so the high-level interface is more + prominent). Specfile now includes code to install gpsd so it will + be started at boot time. -D2 now causes command error messages + to be echoed to the client. + +* Sat Aug 21 2004 Eric S. Raymond - 1.91-1 + Second pre-2.0 release. Features a linkable C library that hides the + details of communicating with the daemon. The daemon now recovers + gracefully from having the GPS unplugged and plugged in at any time; + one of the bits of status it can report is whether the GPS is online. + The gps and xgpsspeed clients now query the daemon; their code + for direct access to the serial port has been deliberately removed. + +* Sun Aug 15 2004 Eric S. Raymond - 1.90 + Creation of specfile. + +* Sun Mar 21 2004 Remco Treffkorn - ? + Without PRWIZCH sentence: sat. colors in gps according to ss, grey==lt20, + yellow==lt40 else green. + Added L Q and I to the protocol. Removed G and T. + Changed the timeout mechanism. Try to not return Lat/Lon/Alt if + validity is in doubt. + +* Thu Jan 29 2004 Remco Treffkorn - ? + Make applications null-terminate their resource lists. + +* Sat Dec 20 2003 Remco Treffkorn - ? + Removed from netlib. Not needed, and new gcc does not support + it any more. + +* Wed Aug 20 2003 Remco Treffkorn - 1.10 + Add install target. Fix clean target. Make GPS timeout configurable. + Make xgpsspeed build with Apple's X11. + Make sure that we don't segfault if the NMEA is badly formed. + +* Mon Aug 18 2003 Remco Treffkorn - ? + Use cfset[io]speed() to set speed in serial.h. Glibc is quite insane + and I am tired to chase it, so I give up. Hope this works for BSD. + Set status and mode 0 after GPS timeout (5 sec) - Cougar + +* Sun Feb 16 2003 Remco Treffkorn - 1.09 + Include sys/time.h in gpsd.c for struct timeval. + +* Sun Nov 03 2002 Remco Treffkorn - ? + G or g command returns six-digit Maidenhead grid square (like FN12fx) + +* Thu Oct 03 2002 Remco Treffkorn - 1.08 + Added sockopt SO_REUSEADDR to netlib.c passive_sock. + +* Tue Feb 05 2002 Remco Treffkorn - 1.07 + em.c uses (as it should). Removed some + where they were not needed. + Russ Nelson: Improved Earthmate support: added state machine for + EARTHA recognizer, removed alignment problems seen on ARM architecture. + Added setsockopt to add SO_REUSEADDR, so that + gpsd can stop and immediately restart. Added support for bitrates + higher than 38400, needed for the SIRF chipset. + Derrick: my patch causes longitude when under 100 degrees to be printed + zero-padded as needed, the latitude same deal under 10, fixes the GGA + sentence to not erroneously print fix type (2/3) instead of fix quality, + and calculates fix type correctly. + +* Fri Aug 11 2000 Remco Treffkorn - 1.06 + Change from C++ (/) to C comments (/* */)for compatibility. + Added -n (need init) flag. + Don't init unless lat/lon specified. + Remove gps.mayko.com as the default hostname. + +* Fri May 12 2000 Remco Treffkorn - 1.05 + (even though version.h says 1.04) + Added some includes to xgpsspeed.c for portability. + Fix problem with flags being overwritten, and using the wrong port + variable also in xgpsspeed.c + Add a note about Y2K compatibility fix. + Pass latitude and longitude into em_init(). + +* Fri Mar 17 2000 Remco Treffkorn - 1.02 + (even though version.h says 1.01) + +* Sun Mar 05 2000 Remco Treffkorn - 1.01 + Updated to IANA port. + Fixes to DGPS support. + +* Sun Jan 02 2000 Remco Treffkorn - 1.0 + Added DGPS fixes from Curt Mills. (See README for contact info.) + +* Mon Dec 13 1999 Remco Treffkorn - 0.99dgps + Added minimal DGPS support by Derrick J Brashear + +* Sat Jul 17 1999 Remco Treffkorn - 0.99 + Rockwell binary is now translated to NMEA format, so that + clients like gps will work with an EarthMate. + Added speedometer application. Thanks to Derrick J Brashear + for his work (see README for contact info). + +* Thu Mar 04 1999 Remco Treffkorn - 0.96 + Changed EarthMate support. Rockwell binary is now almost properly + supported. Only the minimum required information is extracted. + +* Sat Feb 06 1999 Remco Treffkorn - 0.95 + Added support for EarthMate receivers. Since I do not have one, this is + untested. + If it works, it does the following: You start gpsd with a baudrate of 9600 + and give it the -Te option. If gpsd gets the EartMate it will enable the + receiver and then attempt to switch it into NMEA mode. If the EarthMate id + is not received, but a binary data header is received, then we will try to + switch NMEA too. + +* Sun Jan 24 1999 Remco Treffkorn - 0.94 + Y2K compliant ;-) (... is NOT. Look for "FIXME:" in nmea_parse.c) + +* Tue Jan 27 1998 Remco Treffkorn - 0.93 + using GNU autoconf now. + combined gpsd + gpsclient. No more init files, command line only. + +* Tue May 13 1997 Remco Treffkorn - 0.9 + some cleanups in the ini code. version 0.9 ... + +* Fri Apr 25 1997 Remco Treffkorn - 0.8 + version 0.8, some bug fixes. New MODE member, STATUS member changed. + +* Mon Apr 21 1997 Remco Treffkorn - 0.7 + released version 0.7 diff --git a/README b/README new file mode 100644 index 0000000..b1688b1 --- /dev/null +++ b/README @@ -0,0 +1,120 @@ +COPYRIGHT +========= + +This software (gpsd) released under the terms and conditions of the BSD +License, a copy of which is included in the file COPYING. + +GENERAL +======= + +gpsd is a userland daemon acting as a translator between GPS or +Loran-C receivers and clients. gpsd listens on port 2947 for clients +requesting position/time/velocity information. The receivers are +expected to generate position information in a well-known format -- as +NMEA-0183 sentences, SiRF binary, Rockwell binary, Garmin binary +format, or other vendor binary protocols. gpsd takes this +information from the GPS and translates it into something uniform and +easier to understand for clients. The distribution includes sample +clients, application interface libraries, and test/profiling tools. + +There is a project site for gpsd at . +Look there for updates, news, and project mailing lists. See that +website for a list of GPS units known to be compatible. + +See the file INSTALL for installation instructions and some tips on +how to troubleshoot your installation. + +Distro integrators: An RPM spec file is included in the gpsd +distribution. It wants to set up a hotplug script to notify gpsd +when a potential GPS device goes active and should be polled. The +goal is zero configuration; users should never have to tell gpsd how +to configure itself. If you can't use RPM, use what you see in the +specfile as a model. + +1.X CREDITS +=========== + +Remco Treffkorn designed and originated the code. + +Russ Nelson maintained gpsd for a couple of years. + +Carsten Tschach's gpstrans-0.31b code was the original model for nmea_parse.c. + +Bob Lorenzini provided testing and feedback. + +Brook Milligan combined gpsd and gpsclient +into one package and autoconfiscated it. + +Derrick J. Brashear (KB3EGH) added code for the +EarthMate DeLorme. He also added "incredibly gross code to output +NMEA sentences" (his own words :-) He also did the first cut at +DGPS support (see http://www.wsrcc.com/wolfgang/gps/dgps-ip.html), +for the Earthmate. + +Curt Mills (WE7U) furthered the dgps support, +writing the portion for other GPS receivers. + +None of these people are active in 2.X, through Remco de-lurks on the +mailing list occasionally. + +2.X CREDITS +=========== + +Eric S. Raymond drastically rewrote this code to clean it up and extend it. +The 2.X architecture has become significantly different and far more +modularized. His new features include: + * Documentation (what a concept!) + * Cleaned up, simplified command-line options. + * Now understands the GLL (Geographic position - Latitude, Longitude) + sentence from NMEA 3.0. + * Now parses both the NMEA 3.01 and pre-3.01 variants of the VTG sentence + correctly. + * New 'y' command supports satellite location -- it should no longer ever + be necessary for clients to go to raw mode unless they want to monitor and + and log the NMEA stream itself. + * New 'w' command toggles 'watcher' mode. In watcher mode gpsd ships + a gpsd-style response for each incoming sentence as if the client + had just sent all commands that asked for data contained in the sentence. + * New 'x' command allows the client to query whether or not the GPS + is on-line. + * Massive refactoring -- one main loop now calls a self-contained + driver object for each type. + * The GPS-bashing code the daemon uses can now be directly linked as a + library, libgpsd(3). + * C and Python libraries are available to encapsulate the client side of + querying gpsd, see libgps(3). + * Cleaned-up error reporting, we don't use syslog when running in foreground + but send all error and status messages to the tty instead. + * Added -n option to do batch monitoring of GPSes. + * xgpsspeed is working again; xgps has been seriously reworked and improved. + * RPMs which include installation of gpsd to start up at boot time + are available. + * New gpsprobe program probes the capabilities of GPSes and generates + error scattergrams from fixes. (Later this moved to gpsprof.) + * Autobauding, self-configuration, and hotplugging. gpsd can now get + its device from a hotplug script, and figures out itself which baud + rate to use and what the GPS's device type is. + * More new commands: 'I', 'U', 'E', 'B', 'Z'. See the docs. + * Support for SiRF binary mode. + * Support for RTCM104 and AIVDM. + * Support for multiple devices. + * Other test tools -- gpsfake, gpscat. + +Chris Kuethe maintains the OpenBSD port, shipped +the 2.34 release, is our SiRF and low-level protocols expert, and does a +lot of general hacking and support. + +Gary Miller wrote the driver for Garmin binary protocol. + +Amaury Jacquot added DBUS support. + +Ville Nuorvala wrote the NTRIP support. + +We are delighted to acknowlege the assistance of Carl Carter, a field +application engineer at SiRF. He assisted us with the correction and +tuning of the SiRF binary-protocol driver, shedding a good deal of +light on murky aspects of the chip's behavior. + +We are also delighted to acknowlege the assistance of Timo Ylhainen, VP of +Software Operations at Fastrax. He clarified a number of points about +the iTalk protocol, helping to further development of iTalk support. diff --git a/TODO b/TODO new file mode 100644 index 0000000..59b45f0 --- /dev/null +++ b/TODO @@ -0,0 +1,224 @@ +This is the gpsd to-do list. If you're viewing it with Emacs, try +doing Ctl-C Ctl-t and browsing through the outline headers. Ctl-C Ctl-a +will unfold them again. + +For contribution guidelines and internals documentation, please see +. + +The list of bugs exposed by gpsd in other software has moved to +. + +** Bugs in gpsd and its clients: + +*** Tracker bugs + +See the GPSD bug tracker at https://developer.berlios.de/bugs/?group_id=2116 +but don't be surprised if it's empty or very sparse. Our rate of new defects +per month is quite low. + +*** Driver issues + +**** gpsctl -b should work on UBX, but does not. + +Presently this means there's no way to kick a UBX into returning +binary data. + +** Ports + +*** Windows port + +Partially complete. David Ludlow is working on it. + +** To do: + +*** Bump MAXCHANNELS to support GPS/GLONASS devices + +This will require a major soname bump. Probably goes with the API +changes on the Future page. Here's a test log for a GPS/GLONASS device, +the Geostar Geos 1M: . + +*** Write advanced features for TNT Revolution device + +The baud-rate switcher in the TNT driver needs to be tested. + +gpsmon could support a number of TNT configuration commands, including +unit changes. See http://gpsd.googlecode.com/truenorth-reference.pdf +for possibilities. + +Jon Schlueter has one of these on a flock machine, so testing +shouldn't be difficult. + +*** Finish gpssim + +It's blocked on skyview computation. + +*** Complete and test the speed/parity/stopbit methods in the drivers + +These are used for the '?DEVICE' command. All work for 8N1. + +**** superstar2: not implemented (driver is unfinished) +**** italk: not implemented (but could be) +**** tsip: speed tested, parity and stop-bit switching not tested +**** sirf: speed tested, parity and stop-bit switching not tested +**** evermore: speed tested, rejects parity/stopbit setting +**** ubx: fully implemented, parity and stop-bit switching not tested +**** zodiac: fully implemented, not tested +**** navcom.c: speed tested, rejects parity/stopbit setting + +SiRF, UBX, TSIP, and even Zodiac can support non-8N1 modes; these need +to be tested. + +*** Command to ship RTCM corrections to a specified device + +At the moment, if a GPS accepts RTCM corrections and they are +available, gpsd ships them to the serial device from which the GPS is +reporting fix data. Some GPSes have auxiliary ports for RTCM; +there should be a (privileged) command to redirect RTCM connections. + +*** Per-driver restore of changed config settings on exit. + +This is a solved problem for generic NMEA, EverMore, TripMate, +EarthMate, TNTC, Zodiac, and RTCM104 drivers (if only because they +don't configure any device settings). + +The SiRF driver now restores NMEA when necessary. It also restores +some (but not all) of the things it tweaks in binary mode -- at the +moment, just the Navigation Parameters from message 0x13. With more +work, we should be able to do a full revert. + +The TSIP driver changes its per-cycle sentence inventory and thus +needs some state-restore logic. This can be done; the same packet 0x35 +we use to configure it can be sent in a no-argument mode to query +the current sentence mix for later restore. + +The FV18 changes its per-cycle sentence inventory to include GSAs. It +is possible to query that inventory, though we don't have code to do +it yet. + +Garmin devices are a mess. We reconfigure those heavily, and we +don't know if there's any way to capture their configuration state +before we do it. + +The iTrax02 driver sets SYNCMODE to start navigation messages without +checking to see if it's already on, and stops navigation methods on +wrapup. It also forces the set of sentences issued. There doesn't +seem to be any way to query these settings. + +*** Industry-standard format dumping of raw satellite data + +It would be useful to be able to extract RINEX (or some other standard) +format data from any GPS device that can report pseudoranges etc. This +belongs in the daemon because the device drivers are already doing the +packet-cracking needed to get the data off the chips. + +Several commodity chipsets (ANTARIS, iTrax3, SiRF and Trimble) readily +output enough data to make this a chore, rather than a hard problem. + +It has been suggested one way to do this is to have a generic structure +in memory and corresponding output message with clock, doppler carrier +phase and pseudoranges. This message is then reformatted by a client +program. There are numerous formats for this information, and it would +be easier to adapt to new formats if the formatting and use was handled +by something other than the gpsd daemon. Currently the RT-IGS format is +looking like the favorite for implementation; it's a fairly lightweight +protocol, flexible enough to handle all the quantities required, and it +is actually in use in production reference networks. RT-IGS is also a +packet-oriented format, rather than a file-oriented format like RINEX. + +*** RTCM3 support. + +Previous plans for more RTCM2 support seem to have been overtaken by +events, e.g. the world moving to RTCM3. We have support for analyzing +RTCM3 messages, but it's entirely theoretical - written from the +standard. We need to find a pair of files consisting of a +representative set of RTCM3 sentences and some sort of ASCII dump of +them so we can test whether our analyzer gets all the bitfield +boundaries right. + +** Future features (?) + +*** Support for more survey / professional / up-scale receivers. + +Devices such as the Javad JNSCore, Hemisphere Crescent, Septentrio +AsteRx and PolaRx, NovAtel Superstar2 and OEMV, Thales (Magellan +Professional) AC12 and DG14 would all be welcome. Of course, these +are not $50 usb mice... + +*** Audio cues in the client when the fix status changes + +Calum writes: +>Is it possible to add functionality (with a switch to enable it to +>avoid annoying those that don't want it) so that beeps indicate NO +>FIX, FIX, and OFFLINE status changes? +> +>For example - I run cgps and my laptop battery doesn't always supply +>my PS2 port-powered GPS device with enough power, and it goes into +>OFFLINE mode. As I can't drive, and check my laptop all the time, if +>it emitted 5 1 second beeps when it went OFFLINE, it would be a handy alert. +> +>Similarly, a PCMCIA "eject" 2 beeps for NO FIX, and a PCMCIA "happy" 2 +>beeps when it gets a fix again? +> +>Or something like that. + +This is a good idea for supporting hands-free operation, e.g. while driving. + +It would be an easy first project for somebody who wants to get into +the client code. + +*** Set the system time zone from latitude/longitude + +If we're going to give gpsd the capability to set system time via +ntpd, why not let it set timezone as well? A good thing for hackers +travelling with laptops! + +The major issue here is that I have not yet found code, or a +database, that would allow mapping from lon/lat to timezone. +And the rules change from year to year. + +Actually this should be built as a specialized client, as some +people won't want it. + +From : + + The timezone under Linux is set by a symbolic link from + /etc/localtime[1] to a file in the /usr/share/zoneinfo[2] directory + that corresponds with what timezone you are in. For example, since I'm + in South Australia, /etc/localtime is a symlink to + /usr/share/zoneinfo/Australia/South. To set this link, type: + + ln -sf ../usr/share/zoneinfo/your/zone /etc/localtime + + Replace your/zone with something like Australia/NSW or + Australia/Perth. Have a look in the directories under + /usr/share/zoneinfo to see what timezones are available. + + [1] This assumes that /usr/share/zoneinfo is linked to /etc/localtime as it is under Red Hat Linux. + + [2] On older systems, you'll find that /usr/lib/zoneinfo is used + instead of /usr/share/zoneinfo. + +Changing the hardlink will, of course, update the system timezone for +all users. If I were designing this feature, I'd ensure that the +system timezone can be overridden by a user-set TZ, but I don't know +if it actually works that way. + +If I'm reading the tea leaves correctly, this functionality is actually +embedded in the GCC library version of tzset(), so the same method will +work on any system that uses that. + +Problem: system daemons use the timezone set when they start up. You +can't get them to grok a new one short of rebooting. + +Sources: + +Sources for Time Zone and Daylight Saving Time Data +http://www.twinsun.com/tz/tz-link.htm + +Free time-zone maps of the U.S. +http://www.manifold.net/download/freemaps.html + +Local variables: +mode: outline +paragraph-separate: "[ ]*$" +end: diff --git a/Tachometer.h b/Tachometer.h new file mode 100644 index 0000000..a80cd4f --- /dev/null +++ b/Tachometer.h @@ -0,0 +1,52 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#ifndef _GPSD_TACHOMETER_H_ +#define _GPSD_TACHOMETER_H_ + +/* Tachometer.h -- tachometer widget interface */ +#include + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + border BorderColor Pixel XtDefaultForeground + circleColor BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 0 + cursor Cursor Cursor None + destroyCallback Callback XtCallbackList NULL + foreground Foreground Pixel XtDefaultForeground + height Height Dimension 100 + insensitiveBorder Insensitive Pixmap Gray + internalBorderWidth BorderWidth Dimension 0 + mappedWhenManaged MappedWhenManaged Boolean True + needleColor BorderColor Pixel XtDefaultForeground + needleSpeed NeedleSpeed int 1 + sensitive Sensitive Boolean True + width Width Dimension 100 + value Value int 0 + x Position Position 0 + y Position Position 0 + +*/ + +#define XtNinternalBorderWidth "internalBorderWidth" +#define XtNtachometerNeedleSpeed "needleSpeed" +#define XtNtachometerCircleColor "circleColor" +#define XtNtachometerNeedleColor "needleColor" +#define XtCtachometerNeedleSpeed "NeedleSpeed" + +extern int TachometerGetValue(Widget); +extern int TachometerSetValue(Widget, int); + +/* Class record constants */ + +extern WidgetClass tachometerWidgetClass; + +typedef struct _TachometerClassRec *TachometerWidgetClass; +typedef struct _TachometerRec *TachometerWidget; + +#endif /* _GPSD_TACHOMETER_H_ */ diff --git a/TachometerP.h b/TachometerP.h new file mode 100644 index 0000000..401c3cf --- /dev/null +++ b/TachometerP.h @@ -0,0 +1,44 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#ifndef _GPSD_TACHOMETERP_H_ +#define _GPSD_TACHOMETERP_H_ + +/* TachometerP.h -- Tachometer widget private data */ +#include +#include + +/* New fields for the Tachometer widget class record */ +typedef struct {int foo;} TachometerClassPart; + +/* Full class record declaration */ +typedef struct _TachometerClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + TachometerClassPart label_class; +} TachometerClassRec; + +extern TachometerClassRec tachometerClassRec; + +/* New fields for the Tachometer widget record */ +typedef struct { + /* resources */ + Pixel needle, scale, circle; + int value, speed; + /* private state */ + GC needle_GC, scale_GC, circle_GC, background_GC; + /* We need to store the width and height separately, because when */ + /* we get a resize request, we need to know if the window has */ + /* gotten bigger. */ + Dimension width, height, internal_border; +} TachometerPart; + +/* Full instance record declaration */ +typedef struct _TachometerRec { + CorePart core; + SimplePart simple; + TachometerPart tachometer; +} TachometerRec; + +#endif /* _GPSD_TACHOMETERP_H_ */ diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..be021f4 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,9309 @@ +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],, +[m4_warning([this file was generated for autoconf 2.67. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 56 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl +_LT_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Fix-up fallback echo if it was mangled by the above quoting rules. +case \$lt_ECHO in +*'\\\[$]0 --fallback-echo"')dnl " + lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` + ;; +esac + +_LT_OUTPUT_LIBTOOL_INIT +]) + + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +cat >"$CONFIG_LT" <<_LTEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate a libtool stub with the current configuration. + +lt_cl_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AS_SHELL_SANITIZE +_AS_PREPARE + +exec AS_MESSAGE_FD>&1 +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2008 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +if test "$no_create" != yes; then + lt_cl_success=: + test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" + exec AS_MESSAGE_LOG_FD>/dev/null + $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false + exec AS_MESSAGE_LOG_FD>>config.log + $lt_cl_success || AS_EXIT(1) +fi +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_XSI_SHELLFNS + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX +# ----------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_SHELL_INIT + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[_LT_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$lt_ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +ECHO=${lt_ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<_LT_EOF +[$]* +_LT_EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$lt_ECHO"; then + if test "X${echo_test_string+set}" != Xset; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if { echo_test_string=`eval $cmd`; } 2>/dev/null && + { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null + then + break + fi + done + fi + + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : + else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$ECHO" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + ECHO='print -r' + elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + ECHO='printf %s\n' + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + ECHO="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + ECHO=echo + fi + fi + fi + fi + fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +lt_ECHO=$ECHO +if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(lt_ECHO) +]) +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], + [An echo program that does not interpret backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[AC_CHECK_TOOL(AR, ar, false) +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1]) + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ + = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line __oline__ "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method == "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC*) + # IBM XL 8.0 on PPC + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl*) + # IBM XL C 8.0/Fortran 10.1 on PPC + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac +AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + linux* | k*bsd*-gnu) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag= + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE(int foo(void) {}, + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + ) + LDFLAGS="$save_LDFLAGS" + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], + [[If ld is used when linking, flag to hardcode $libdir into a binary + during linking. This must work even if $libdir does not exist]]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [fix_srcfile_path], [1], + [Fix the shell variable $srcfile for the compiler]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_PROG_CXX +# ------------ +# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ +# compiler, we have our own version here. +m4_defun([_LT_PROG_CXX], +[ +pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) +AC_PROG_CXX +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_CXX + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_CXX], []) + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[AC_REQUIRE([_LT_PROG_CXX])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 will use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + xl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=echo + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +]) +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_PROG_F77 +# ------------ +# Since AC_PROG_F77 is broken, in that it returns the empty string +# if there is no fortran compiler, we have our own version here. +m4_defun([_LT_PROG_F77], +[ +pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) +AC_PROG_F77 +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_F77 + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_F77], []) + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_REQUIRE([_LT_PROG_F77])dnl +AC_LANG_PUSH(Fortran 77) + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + CC=${F77-"f77"} + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_PROG_FC +# ----------- +# Since AC_PROG_FC is broken, in that it returns the empty string +# if there is no fortran compiler, we have our own version here. +m4_defun([_LT_PROG_FC], +[ +pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) +AC_PROG_FC +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_FC + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_FC], []) + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_REQUIRE([_LT_PROG_FC])dnl +AC_LANG_PUSH(Fortran) + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + CC=${FC-"f95"} + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC="$lt_save_CC" +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC="$lt_save_CC" +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_XSI_SHELLFNS +# --------------------- +# Bourne and XSI compatible variants of some useful shell functions. +m4_defun([_LT_PROG_XSI_SHELLFNS], +[case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $[*] )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + +dnl func_dirname_and_basename +dnl A portable version of this function is already defined in general.m4sh +dnl so there is no need for it here. + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[[^=]]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$[@]"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$[1]+=\$[2]" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$[1]=\$$[1]\$[2]" +} + +_LT_EOF + ;; + esac +]) + +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [0], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) + +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) + +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# Generated from ltversion.in. + +# serial 3017 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.2.6b]) +m4_define([LT_PACKAGE_REVISION], [1.3017]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.2.6b' +macro_revision='1.3017' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) + +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 4 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 10 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# --------------------------------------------------------------------------- +# Adds support for distributing Python modules and packages. To +# install modules, copy them to $(pythondir), using the python_PYTHON +# automake variable. To install a package with the same name as the +# automake package, install to $(pkgpythondir), or use the +# pkgpython_PYTHON automake variable. +# +# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as +# locations to install python extension modules (shared libraries). +# Another macro is required to find the appropriate flags to compile +# extension modules. +# +# If your package is configured with a different prefix to python, +# users will have to add the install directory to the PYTHONPATH +# environment variable, or create a .pth file (see the python +# documentation for details). +# +# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will +# cause an error if the version of python installed on the system +# doesn't meet the requirement. MINIMUM-VERSION should consist of +# numbers and dots only. +AC_DEFUN([AM_PATH_PYTHON], + [ + dnl Find a Python interpreter. Python versions prior to 2.0 are not + dnl supported. (2.0 was released on October 16, 2000). + m4_define_default([_AM_PYTHON_INTERPRETER_LIST], + [python python2 python3 python3.0 python2.5 python2.4 python2.3 python2.2 dnl +python2.1 python2.0]) + + m4_if([$1],[],[ + dnl No version check is needed. + # Find any Python interpreter. + if test -z "$PYTHON"; then + AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) + fi + am_display_PYTHON=python + ], [ + dnl A version check is needed. + if test -n "$PYTHON"; then + # If the user set $PYTHON, use it and don't search something else. + AC_MSG_CHECKING([whether $PYTHON version >= $1]) + AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], + [AC_MSG_RESULT(yes)], + [AC_MSG_ERROR(too old)]) + am_display_PYTHON=$PYTHON + else + # Otherwise, try each interpreter until we find one that satisfies + # VERSION. + AC_CACHE_CHECK([for a Python interpreter with version >= $1], + [am_cv_pathless_PYTHON],[ + for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do + test "$am_cv_pathless_PYTHON" = none && break + AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) + done]) + # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. + if test "$am_cv_pathless_PYTHON" = none; then + PYTHON=: + else + AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) + fi + am_display_PYTHON=$am_cv_pathless_PYTHON + fi + ]) + + if test "$PYTHON" = :; then + dnl Run any user-specified action, or abort. + m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) + else + + dnl Query Python for its version number. Getting [:3] seems to be + dnl the best way to do this; it's what "site.py" does in the standard + dnl library. + + AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], + [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`]) + AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) + + dnl Use the values of $prefix and $exec_prefix for the corresponding + dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made + dnl distinct variables so they can be overridden if need be. However, + dnl general consensus is that you shouldn't need this ability. + + AC_SUBST([PYTHON_PREFIX], ['${prefix}']) + AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) + + dnl At times (like when building shared libraries) you may want + dnl to know which OS platform Python thinks this is. + + AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], + [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) + AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) + + + dnl Set up 4 directories: + + dnl pythondir -- where to install python scripts. This is the + dnl site-packages directory, not the python standard library + dnl directory like in previous automake betas. This behavior + dnl is more consistent with lispdir.m4 for example. + dnl Query distutils for this directory. distutils does not exist in + dnl Python 1.5, so we fall back to the hardcoded directory if it + dnl doesn't work. + AC_CACHE_CHECK([for $am_display_PYTHON script directory], + [am_cv_python_pythondir], + [if test "x$prefix" = xNONE + then + am_py_prefix=$ac_default_prefix + else + am_py_prefix=$prefix + fi + am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null || + echo "$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages"` + case $am_cv_python_pythondir in + $am_py_prefix*) + am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` + am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` + ;; + *) + case $am_py_prefix in + /usr|/System*) ;; + *) + am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + ]) + AC_SUBST([pythondir], [$am_cv_python_pythondir]) + + dnl pkgpythondir -- $PACKAGE directory under pythondir. Was + dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is + dnl more consistent with the rest of automake. + + AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) + + dnl pyexecdir -- directory for installing python extension modules + dnl (shared libraries) + dnl Query distutils for this directory. distutils does not exist in + dnl Python 1.5, so we fall back to the hardcoded directory if it + dnl doesn't work. + AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], + [am_cv_python_pyexecdir], + [if test "x$exec_prefix" = xNONE + then + am_py_exec_prefix=$am_py_prefix + else + am_py_exec_prefix=$exec_prefix + fi + am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null || + echo "$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages"` + case $am_cv_python_pyexecdir in + $am_py_exec_prefix*) + am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` + am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` + ;; + *) + case $am_py_exec_prefix in + /usr|/System*) ;; + *) + am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + ]) + AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) + + dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) + + AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) + + dnl Run any user-specified action. + $2 + fi + +]) + + +# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# --------------------------------------------------------------------------- +# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. +# Run ACTION-IF-FALSE otherwise. +# This test uses sys.hexversion instead of the string equivalent (first +# word of sys.version), in order to cope with versions such as 2.2c1. +# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). +AC_DEFUN([AM_PYTHON_CHECK_VERSION], + [prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] +sys.exit(sys.hexversion < minverhex)" + AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/ais_json.c b/ais_json.c new file mode 100644 index 0000000..22fa9bd --- /dev/null +++ b/ais_json.c @@ -0,0 +1,154 @@ +/**************************************************************************** + +NAME + ais_json.c - deserialize AIS JSON + +DESCRIPTION + This module uses the generic JSON parser to get data from AIS +representations to libgps structures. + +***************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "gps_json.h" + +/*@ -mustdefine @*/ +static void lenhex_unpack(const char *from, + size_t * plen, /*@out@*/ char *to, size_t maxlen) +{ + char *colon = strchr(from, ':'); + + *plen = (size_t) atoi(from); + if (colon != NULL) + (void)gpsd_hexpack(colon + 1, to, maxlen); +} + +/*@ +mustdefine @*/ + +int json_ais_read(const char *buf, + char *path, size_t pathlen, struct ais_t *ais, + /*@null@*/ const char **endptr) +{ + /* collected but not actually used yet */ + bool scaled; + /*@-compdef@*//* splint is confused by storage declared in the .i file */ + /*@-nullstate@*/ + +#define AIS_HEADER \ + {"class", t_check, .dflt.check = "AIS"}, \ + {"type", t_uinteger, .addr.uinteger = &ais->type}, \ + {"device", t_string, .addr.string = path, \ + .len = pathlen}, \ + {"repeat", t_uinteger, .addr.uinteger = &ais->repeat}, \ + {"scaled", t_boolean, .addr.boolean = &scaled, \ + .dflt.boolean = false}, \ + {"mmsi", t_uinteger, .addr.uinteger = &ais->mmsi} + + int status; + +#include "ais_json.i" /* JSON parser template structures */ + +#undef AIS_HEADER + + memset(ais, '\0', sizeof(struct ais_t)); + + if (strstr(buf, "\"type\":1,") != NULL + || strstr(buf, "\"type\":2,") != NULL + || strstr(buf, "\"type\":3,") != NULL) { + status = json_read_object(buf, json_ais1, endptr); + } else if (strstr(buf, "\"type\":4,") != NULL + || strstr(buf, "\"type\":11,") != NULL) { + status = json_read_object(buf, json_ais4, endptr); + if (status == 0) { + ais->type4.year = AIS_YEAR_NOT_AVAILABLE; + ais->type4.month = AIS_MONTH_NOT_AVAILABLE; + ais->type4.day = AIS_DAY_NOT_AVAILABLE; + ais->type4.hour = AIS_HOUR_NOT_AVAILABLE; + ais->type4.minute = AIS_MINUTE_NOT_AVAILABLE; + ais->type4.second = AIS_SECOND_NOT_AVAILABLE; + (void)sscanf(timestamp, "%4u-%02u-%02uT%02u:%02u:%02uZ", + &ais->type4.year, + &ais->type4.month, + &ais->type4.day, + &ais->type4.hour, + &ais->type4.minute, &ais->type4.second); + } + } else if (strstr(buf, "\"type\":5,") != NULL) { + status = json_read_object(buf, json_ais5, endptr); + if (status == 0) { + ais->type5.month = AIS_MONTH_NOT_AVAILABLE; + ais->type5.day = AIS_DAY_NOT_AVAILABLE; + ais->type5.hour = AIS_HOUR_NOT_AVAILABLE; + ais->type5.minute = AIS_MINUTE_NOT_AVAILABLE; + (void)sscanf(eta, "%02u-%02uT%02u:%02uZ", + &ais->type5.month, + &ais->type5.day, + &ais->type5.hour, &ais->type5.minute); + } + } else if (strstr(buf, "\"type\":6,") != NULL) { + status = json_read_object(buf, json_ais6, endptr); + if (status == 0) + lenhex_unpack(data, &ais->type6.bitcount, + ais->type6.bitdata, sizeof(ais->type6.bitdata)); + } else if (strstr(buf, "\"type\":7,") != NULL + || strstr(buf, "\"type\":13,") != NULL) { + status = json_read_object(buf, json_ais7, endptr); + } else if (strstr(buf, "\"type\":8,") != NULL) { + status = json_read_object(buf, json_ais8, endptr); + if (status == 0) + lenhex_unpack(data, &ais->type8.bitcount, + ais->type8.bitdata, sizeof(ais->type8.bitdata)); + } else if (strstr(buf, "\"type\":9,") != NULL) { + status = json_read_object(buf, json_ais9, endptr); + } else if (strstr(buf, "\"type\":10,") != NULL) { + status = json_read_object(buf, json_ais10, endptr); + } else if (strstr(buf, "\"type\":12,") != NULL) { + status = json_read_object(buf, json_ais12, endptr); + } else if (strstr(buf, "\"type\":14,") != NULL) { + status = json_read_object(buf, json_ais14, endptr); + } else if (strstr(buf, "\"type\":15,") != NULL) { + status = json_read_object(buf, json_ais15, endptr); + } else if (strstr(buf, "\"type\":16,") != NULL) { + status = json_read_object(buf, json_ais16, endptr); + } else if (strstr(buf, "\"type\":17,") != NULL) { + status = json_read_object(buf, json_ais17, endptr); + if (status == 0) + lenhex_unpack(data, &ais->type17.bitcount, + ais->type17.bitdata, sizeof(ais->type17.bitdata)); + } else if (strstr(buf, "\"type\":18,") != NULL) { + status = json_read_object(buf, json_ais18, endptr); + } else if (strstr(buf, "\"type\":18,") != NULL) { + status = json_read_object(buf, json_ais17, endptr); + } else if (strstr(buf, "\"type\":19,") != NULL) { + status = json_read_object(buf, json_ais19, endptr); + } else if (strstr(buf, "\"type\":20,") != NULL) { + status = json_read_object(buf, json_ais20, endptr); + } else if (strstr(buf, "\"type\":21,") != NULL) { + status = json_read_object(buf, json_ais21, endptr); + } else if (strstr(buf, "\"type\":22,") != NULL) { + status = json_read_object(buf, json_ais22, endptr); + } else if (strstr(buf, "\"type\":23,") != NULL) { + status = json_read_object(buf, json_ais23, endptr); + } else if (strstr(buf, "\"type\":24,") != NULL) { + status = json_read_object(buf, json_ais24, endptr); + } else if (strstr(buf, "\"type\":25,") != NULL) { + status = json_read_object(buf, json_ais25, endptr); + } else if (strstr(buf, "\"type\":26,") != NULL) { + status = json_read_object(buf, json_ais26, endptr); + } else { + if (endptr != NULL) + *endptr = NULL; + return JSON_ERR_MISC; + } + /*@+compdef +nullstate@*/ + return status; +} + +/* ais_json.c ends here */ diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..4c59eeb --- /dev/null +++ b/autogen.sh @@ -0,0 +1,140 @@ +#!/bin/sh + +# Automakeversion +AM_1=1 +AM_2=7 +AM_3=6 + +# Autoconfversion +AC_1=2 +AC_2=57 + +# Libtoolversion +LT_1=1 +LT_2=5 + +# Check automake version +AM_VERSION=`automake --version | sed -n -e 's#[^0-9]* \([0-9]*\)\.\([0-9]*\)\.*\([0-9]*\).*$#\1 \2 \3#p'` +AM_V1=`echo $AM_VERSION | awk '{print $1}'` +AM_V2=`echo $AM_VERSION | awk '{print $2}'` +AM_V3=`echo $AM_VERSION | awk '{print $3}'` + +if [ "$AM_1" -gt "$AM_V1" ]; then + AM_ERROR=1 +else + if [ "$AM_1" -eq "$AM_V1" ]; then + if [ "$AM_2" -gt "$AM_V2" ]; then + AM_ERROR=1 + else + if [ "$AM_2" -eq "$AM_V2" ]; then + if [ -n "$AM_V3" -o "$AM_3" -gt "$AM_V3" ]; then + AM_ERROR=1 + fi + fi + fi + fi +fi + +if [ "$AM_ERROR" = "1" ]; then + echo -n "Your automake version `automake --version | sed -n -e 's#[^0-9]* \([0-9]*\.[0-9]*\.[0-9]*\).*#\1#p'`" + echo " is older than the suggested one, $AM_1.$AM_2.$AM_3" + echo "Go on at your own risk. :-)" + echo +fi + +# Check autoconf version +AC_VERSION=`autoconf --version | sed -n -e 's#[^0-9]* \([0-9]*\)\.\([0-9]*\).*$#\1 \2#p'` +AC_V1=`echo $AC_VERSION | awk '{print $1}'` +AC_V2=`echo $AC_VERSION | awk '{print $2}'` + +if [ "$AC_1" -gt "$AC_V1" ]; then + AC_ERROR=1 +else + if [ "$AC_1" -eq "$AC_V1" ]; then + if [ "$AC_2" -gt "$AC_V2" ]; then + AC_ERROR=1 + fi + fi +fi + +if [ "$AC_ERROR" = "1" ]; then + echo -n "Your autoconf version `autoconf --version | sed -n -e 's#[^0-9]* \([0-9]*\.[0-9]*\).*#\1#p'`" + echo " is older than the suggested one, $AC_1.$AC_2" + echo "Go on at your own risk. :-)" + echo +fi + +#Check for pkg-config +if which pkg-config 1>/dev/null 2>&1; then + #pkg-config seems to be installed. Check for m4 macros: + tmpdir=`mktemp -d "./autogenXXXXXX"` + if [ -z ${tmpdir} ]; then + echo -n "Creating a temporary directory failed. " + echo 'Is mktemp in $PATH?' + echo + exit 1 + fi + + oldpwd=`pwd` + cd "${tmpdir}" + cat > configure.ac << _EOF_ +AC_INIT +PKG_CHECK_MODULES(QtNetwork, [QtNetwork >= 4.4], ac_qt="yes", ac_qt="no") +_EOF_ + aclocal + autoconf --force + grep -q PKG_CHECK_MODULES configure + PKG_MACRO_AVAILABLE=$? + cd "${oldpwd}" + rm -rf "${tmpdir}" + if [ ${PKG_MACRO_AVAILABLE} -eq 0 ]; then + echo -n "pkg-config installed, but autoconf is not able to find pkg.m4. " + echo "Unfortunately the generated configure would not work, so we stop here." + echo + exit 1 + fi +else + echo -n "pkg-config not found. " + echo "pkg-config is required to create a working configure, so we stop here." + echo + exit 1 +fi + + +# Check libtool version +if [ -z "$LIBTOOL" ] ; then + LIBTOOL="libtool" +fi +LT_VERSION=`${LIBTOOL} --version | sed -n -e 's#[^0-9]* \([0-9]*\)\.\([0-9]*\).*$#\1 \2#p'` +LT_V1=`echo $LT_VERSION | awk '{print $1}'` +LT_V2=`echo $LT_VERSION | awk '{print $2}'` + +if [ "$LT_1" -gt "$LT_V1" ]; then + LT_ERROR=1 +else + if [ "$LT_1" -eq "$LT_V1" ]; then + if [ "$LT_2" -gt "$LT_V2" ]; then + LT_ERROR=1 + fi + fi +fi + +if [ "$LT_ERROR" = "1" ]; then + echo -n "Your libtool version `libtool --version | sed -n -e 's#[^0-9]* \([0-9]*\.[0-9]*\).*#\1#p'`" + echo " is older than the suggested one, $LT_1.$LT_2" + echo "Go on at your own risk. :-)" + echo +fi + +if [ -z "$LIBTOOLIZE" ] ; then + LIBTOOLIZE="libtoolize" +fi +echo Configuring build environment for gpsd +aclocal \ + && ${LIBTOOLIZE} --force --copy \ + && autoheader --force \ + && automake --add-missing --foreign --copy --include-deps \ + && autoconf --force \ + && echo Now running configure to configure gpsd \ + && echo "./configure $@" \ + && ./configure "$@" diff --git a/bits.c b/bits.c new file mode 100644 index 0000000..ba546f9 --- /dev/null +++ b/bits.c @@ -0,0 +1,90 @@ +/* bits.c - bitfield extraction code + * + * This file is Copyright (c)2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + * Bitfield extraction functions. In each, start is a bit index (not + * a byte index) and width is a bit width. The width bounded above by + * the bit width of a long long, which is 64 bits in all standard data + * models for 32- and 64-bit processors. + * + * The sbits() function assumes twos-complement arithmetic. + */ +#include + +#include "bits.h" +#ifdef DEBUG +#include +#include "gpsd.h" +#endif /* DEBUG */ + +#define BITS_PER_BYTE 8 + +unsigned long long ubits(char buf[], unsigned int start, unsigned int width) +/* extract a (zero-origin) bitfield from the buffer as an unsigned big-endian long long */ +{ + unsigned long long fld = 0; + unsigned int i; + unsigned end; + + /*@i1@*/ assert(width <= sizeof(long long) * BITS_PER_BYTE); + for (i = start / BITS_PER_BYTE; + i < (start + width + BITS_PER_BYTE - 1) / BITS_PER_BYTE; i++) { + fld <<= BITS_PER_BYTE; + fld |= (unsigned char)buf[i]; + } +#ifdef DEBUG + (void)printf("%d:%d from %s:\n", start, width, gpsd_hexdump(buf, 32)); +#endif + +#ifdef DEBUG + (void)printf(" segment=0x%llx,", fld); +#endif /* DEBUG */ + end = (start + width) % BITS_PER_BYTE; + if (end != 0) { + fld >>= (BITS_PER_BYTE - end); +#ifdef DEBUG + (void)printf(" after downshifting by %d bits: 0x%llx", + BITS_PER_BYTE - end, fld); +#endif /* UDEBUG */ + } +#ifdef DEBUG + (void)printf(" = %lld\n", fld); +#endif /* UDEBUG */ + + /*@ -shiftimplementation @*/ + fld &= ~(-1LL << width); + /*@ +shiftimplementation @*/ +#ifdef DEBUG + (void) + printf(" after selecting out the bottom %u bits: 0x%llx = %lld\n", + width, fld, fld); +#endif /* DEBUG */ + + return fld; +} + +signed long long sbits(char buf[], unsigned int start, unsigned int width) +/* extract a bitfield from the buffer as a signed big-endian long */ +{ + unsigned long long fld = ubits(buf, start, width); + +#ifdef SDEBUG + (void)fprintf(stderr, "sbits(%d, %d) extracts %llx\n", start, width, fld); +#endif /* SDEBUG */ + /*@ +relaxtypes */ + if (fld & (1 << (width - 1))) { +#ifdef SDEBUG + (void)fprintf(stderr, "%llx is signed\n", fld); +#endif /* SDEBUG */ + /*@ -shiftimplementation @*/ + fld |= (-1LL << (width - 1)); + /*@ +shiftimplementation @*/ + } +#ifdef SDEBUG + (void)fprintf(stderr, "sbits(%d, %d) returns %lld\n", start, width, + (signed long long)fld); +#endif /* SDEBUG */ + return (signed long long)fld; + /*@ -relaxtypes */ +} diff --git a/bits.h b/bits.h new file mode 100644 index 0000000..908cca0 --- /dev/null +++ b/bits.h @@ -0,0 +1,91 @@ +/* + * bits.h - extract binary data from message buffer + * + * These macros extract bytes, words, longwords, floats, doubles, or + * bitfields of arbitrary length and size from a message that contains + * these items in either MSB-first or LSB-first byte order. + * + * By defining the GET_ORIGIN and PUT_ORIGIN macros before including + * this header, it's possible to change the origin of the indexing. + * + * Assumptions: + * char is 8 bits, short is 16 bits, int is 32 bits, long long is 64 bits, + * float is 32 bits IEEE754, double is 64 bits IEEE754. + * + * The use of fixed-length types in the casts enforces these. + * Both 32- and 64-bit systems with gcc are OK with this set. + * + * This file is Copyright (c)2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#ifndef _GPSD_BITS_H_ +#define _GPSD_BITS_H_ + +#include + +union int_float { + int32_t i; + float f; +}; + +union long_double { + int64_t l; + double d; +}; + +#ifndef GET_ORIGIN +#define GET_ORIGIN 0 +#endif +#ifndef PUT_ORIGIN +#define PUT_ORIGIN 0 +#endif + +/* these are independent of byte order */ +#define getsb(buf, off) ((int8_t)buf[(off)-(GET_ORIGIN)]) +#define getub(buf, off) ((uint8_t)buf[(off)-(GET_ORIGIN)]) +#define putbyte(buf,off,b) do {buf[(off)-(PUT_ORIGIN)] = (unsigned char)(b);} while (0) + +/* little-endian access */ +#define getlesw(buf, off) ((int16_t)(((uint16_t)getub((buf), (off)+1) << 8) | (uint16_t)getub((buf), (off)))) +#define getleuw(buf, off) ((uint16_t)(((uint16_t)getub((buf), (off)+1) << 8) | (uint16_t)getub((buf), (off)))) +#define getlesl(buf, off) ((int32_t)(((uint16_t)getleuw((buf), (off)+2) << 16) | (uint16_t)getleuw((buf), (off)))) +#define getleul(buf, off) ((uint32_t)(((uint16_t)getleuw((buf),(off)+2) << 16) | (uint16_t)getleuw((buf), (off)))) + +#define putleword(buf, off, w) do {putbyte(buf, (off)+1, (uint)(w) >> 8); putbyte(buf, (off), (w));} while (0) +#define putlelong(buf, off, l) do {putleword(buf, (off)+2, (uint)(l) >> 16); putleword(buf, (off), (l));} while (0) +#define getlesL(buf, off) ((int64_t)(((uint64_t)getleul(buf, (off)+4) << 32) | getleul(buf, (off)))) +#define getleuL(buf, off) ((uint64_t)(((uint64_t)getleul(buf, (off)+4) << 32) | getleul(buf, (off)))) + +#define getlef(buf, off) (i_f.i = getlesl(buf, off), i_f.f) +#define getled(buf, off) (l_d.l = getlesL(buf, off), l_d.d) + +/* SiRF and most other GPS protocols use big-endian (network byte order) */ +#define getbesw(buf, off) ((int16_t)(((uint16_t)getub(buf, (off)) << 8) | (uint16_t)getub(buf, (off)+1))) +#define getbeuw(buf, off) ((uint16_t)(((uint16_t)getub(buf, (off)) << 8) | (uint16_t)getub(buf, (off)+1))) +#define getbesl(buf, off) ((int32_t)(((uint16_t)getbeuw(buf, (off)) << 16) | getbeuw(buf, (off)+2))) +#define getbeul(buf, off) ((uint32_t)(((uint16_t)getbeuw(buf, (off)) << 16) | getbeuw(buf, (off)+2))) +#define getbesL(buf, off) ((int64_t)(((uint64_t)getbeul(buf, (off)) << 32) | getbeul(buf, (off)+4))) +#define getbeuL(buf, off) ((uint64_t)(((uint64_t)getbeul(buf, (off)) << 32) | getbeul(buf, (off)+4))) + +#define putbeword(buf,off,w) do {putbyte(buf, (off) ,(w) >> 8); putbyte(buf, (off)+1, (w));} while (0) +#define putbelong(buf,off,l) do {putbeword(buf, (off) ,(l) >> 16); putbeword(buf, (off)+2, (l));} while (0) + +#define getbef(buf, off) (i_f.i = getbesl(buf, off), i_f.f) +#define getbed(buf, off) (l_d.l = getbesL(buf, off), l_d.d) + + +/* Zodiac protocol description uses 1-origin indexing by little-endian word */ +#define getwordz(buf, n) ( (buf[2*(n)-2]) \ + | (buf[2*(n)-1] << 8)) +#define getlongz(buf, n) ( (buf[2*(n)-2]) \ + | (buf[2*(n)-1] << 8) \ + | (buf[2*(n)+0] << 16) \ + | (buf[2*(n)+1] << 24)) +#define getstringz(to, from, s, e) \ + (void)memcpy(to, from+2*(s)-2, 2*((e)-(s)+1)) + +/* bitfield extraction */ +extern unsigned long long ubits(char buf[], unsigned int, unsigned int); +extern signed long long sbits(char buf[], unsigned int, unsigned int); + +#endif /* _GPSD_BITS_H_ */ diff --git a/bsd-base64.c b/bsd-base64.c new file mode 100644 index 0000000..3ff88ab --- /dev/null +++ b/bsd-base64.c @@ -0,0 +1,315 @@ +/* $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 deraadt Exp $ */ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "gpsd_config.h" +#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) + +#include +#include +#include +#include +#include + +#include "bsd-base64.h" + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +/*@ +matchanyintegral -type @*/ +int +b64_ntop(unsigned char const *src, size_t srclength, char *target, + size_t targsize) +{ + size_t datalength = 0; + unsigned char input[3]; + unsigned char output[4]; + size_t i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/*@ -matchanyintegral +type @*/ + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +/*@ +matchanyintegral +charint @*/ +int b64_pton(char const *src, unsigned char *target, size_t targsize) +{ + size_t tarindex; + int state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + if ((pos = strchr(Base64, ch)) == NULL) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex + 1] = ((pos - Base64) & 0x0f) + << 4; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex + 1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + /*@ -casebreak @*/ + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target != 0 && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} + +/*@ +matchanyintegral -charint @*/ + +#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ diff --git a/bsd-base64.h b/bsd-base64.h new file mode 100644 index 0000000..8ff1217 --- /dev/null +++ b/bsd-base64.h @@ -0,0 +1,18 @@ +/* + * This file is Copyright (c)2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#ifndef _BSD_BASE64_H +#define _BSD_BASE64_H + +#ifndef HAVE___B64_NTOP +# ifndef HAVE_B64_NTOP +int b64_ntop(unsigned char const *src, size_t srclength, char *target, + size_t targsize); +int b64_pton(char const *src, unsigned char *target, size_t targsize); +# endif /* !HAVE_B64_NTOP */ +# define __b64_ntop b64_ntop +# define __b64_pton b64_pton +#endif /* HAVE___B64_NTOP */ + +#endif /* _BSD_BASE64_H */ diff --git a/cgps.c b/cgps.c new file mode 100644 index 0000000..46df222 --- /dev/null +++ b/cgps.c @@ -0,0 +1,932 @@ +/* + * Copyright (c) 2005 Jeff Francis + * BSD terms apply: see the filr COPYING in the distribution root for details. + */ + +/* + Jeff Francis + jeff@gritch.org + + Kind of a curses version of xgps for use with gpsd. +*/ + +/* + * The True North compass fails with current gpsd versions for reasons + * the dev team has been unable to diagnose due to not having test hardware. + * The sup[port for it is conditioned out in order to simplify moving + * to the new JSON-based oprotocol and reduce startup time. + */ +#undef TRUENORTH + +/* ================================================================== + These #defines should be modified if changing the number of fields + to be displayed. + ================================================================== */ + +/* This defines how much overhead is contained in the 'datawin' window + (eg, box around the window takes two lines). */ +#define DATAWIN_OVERHEAD 2 + +/* This defines how much overhead is contained in the 'satellites' + window (eg, box around the window takes two lines, plus the column + headers take another line). */ +#define SATWIN_OVERHEAD 3 + +/* This is how many display fields are output in the 'datawin' window + when in GPS mode. Change this value if you add or remove fields + from the 'datawin' window for the GPS mode. */ +#define DATAWIN_GPS_FIELDS 9 + +/* This is how many display fields are output in the 'datawin' window + when in COMPASS mode. Change this value if you add or remove fields + from the 'datawin' window for the COMPASS mode. */ +#define DATAWIN_COMPASS_FIELDS 6 + +/* This is how far over in the 'datawin' window to indent the field + descriptions. */ +#define DATAWIN_DESC_OFFSET 5 + +/* This is how far over in the 'datawin' window to indent the field + values. */ +#define DATAWIN_VALUE_OFFSET 17 + +/* This is the width of the 'datawin' window. It's recommended to + keep DATAWIN_WIDTH + SATELLITES_WIDTH <= 80 so it'll fit on a + "standard" 80x24 screen. */ +#define DATAWIN_WIDTH 45 + +/* This is the width of the 'satellites' window. It's recommended to + keep DATAWIN_WIDTH + SATELLITES_WIDTH <= 80 so it'll fit on a + "standard" 80x24 screen. */ +#define SATELLITES_WIDTH 35 + +/* ================================================================ + You shouldn't have to modify any #define values below this line. + ================================================================ */ + +/* This is the minimum size we'll accept for the 'datawin' window in + GPS mode. */ +#define MIN_GPS_DATAWIN_SIZE (DATAWIN_GPS_FIELDS + DATAWIN_OVERHEAD) + +/* This is the minimum size we'll accept for the 'datawin' window in + COMPASS mode. */ +#define MIN_COMPASS_DATAWIN_SIZE (DATAWIN_COMPASS_FIELDS + DATAWIN_OVERHEAD) + +/* This is the maximum number of satellites gpsd can track. */ +#define MAX_POSSIBLE_SATS (MAXCHANNELS - 2) + +/* This is the maximum size we need for the 'satellites' window. */ +#define MAX_SATWIN_SIZE (MAX_POSSIBLE_SATS + SATWIN_OVERHEAD) + +#include +#include +#ifndef S_SPLINT_S +#include +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gpsd_config.h" +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif /* HAVE_NCURSES_H */ + +#include "gps.h" +#include "gpsdclient.h" +#include "revision.h" + +static struct gps_data_t gpsdata; +static time_t status_timer; /* Time of last state change. */ +static int state = 0; /* or MODE_NO_FIX=1, MODE_2D=2, MODE_3D=3 */ +static float altfactor = METERS_TO_FEET; +static float speedfactor = MPS_TO_MPH; +static char *altunits = "ft"; +static char *speedunits = "mph"; +static struct fixsource_t source; +#ifdef CLIENTDEBUG_ENABLE +static int debug; +#endif /* CLIENTDEBUG_ENABLE */ + +static WINDOW *datawin, *satellites, *messages; + +static bool raw_flag = false; +static bool silent_flag = false; +static bool magnetic_flag = false; +static int window_length; +static int display_sats; +#ifdef TRUENORTH +static bool compass_flag = false; +#endif /* TRUENORTH */ + +/* pseudo-signals indicating reason for termination */ +#define CGPS_QUIT 0 /* voluntary yterminastion */ +#define GPS_GONE -1 /* GPS device went away */ +#define GPS_ERROR -2 /* low-level failure in GPS read */ + +/* Convert true heading to magnetic. Taken from the Aviation + Formulary v1.43. Valid to within two degrees within the + continiental USA except for the following airports: MO49 MO86 MO50 + 3K6 02K and KOOA. AK correct to better than one degree. Western + Europe correct to within 0.2 deg. + + If you're not in one of these areas, I apologize, I don't have the + math to compute your varation. This is obviously extremely + floating-point heavy, so embedded people, beware of using. + + Note that there are issues with using magnetic heading. This code + does not account for the possibility of travelling into or out of + an area of valid calculation beyond forcing the magnetic conversion + off. A better way to communicate this to the user is probably + desirable (in case the don't notice the subtle change from "(mag)" + to "(true)" on their display). + */ +static float true2magnetic(double lat, double lon, double heading) +{ + /* Western Europe */ + /*@ -evalorder +relaxtypes @*/ + if ((lat > 36.0) && (lat < 68.0) && (lon > -10.0) && (lon < 28.0)) { + heading = + (10.4768771667158 - (0.507385322418858 * lon) + + (0.00753170031703826 * pow(lon, 2)) + - (1.40596203924748e-05 * pow(lon, 3)) - + (0.535560699962353 * lat) + + (0.0154348808069955 * lat * lon) - + (8.07756425110592e-05 * lat * pow(lon, 2)) + + (0.00976887198864442 * pow(lat, 2)) - + (0.000259163929798334 * lon * pow(lat, 2)) + - (3.69056939266123e-05 * pow(lat, 3)) + heading); + } + /* USA */ + else if ((lat > 24.0) && (lat < 50.0) && (lon > 66.0) && (lon < 125.0)) { + lon = 0.0 - lon; + heading = + ((-65.6811) + (0.99 * lat) + (0.0128899 * pow(lat, 2)) - + (0.0000905928 * pow(lat, 3)) + (2.87622 * lon) + - (0.0116268 * lat * lon) - (0.00000603925 * lon * pow(lat, 2)) - + (0.0389806 * pow(lon, 2)) + - (0.0000403488 * lat * pow(lon, 2)) + + (0.000168556 * pow(lon, 3)) + heading); + } + /* AK */ + else if ((lat > 54.0) && (lon > 130.0) && (lon < 172.0)) { + lon = 0.0 - lon; + heading = + (618.854 + (2.76049 * lat) - (0.556206 * pow(lat, 2)) + + (0.00251582 * pow(lat, 3)) - (12.7974 * lon) + + (0.408161 * lat * lon) + (0.000434097 * lon * pow(lat, 2)) - + (0.00602173 * pow(lon, 2)) + - (0.00144712 * lat * pow(lon, 2)) + + (0.000222521 * pow(lon, 3)) + heading); + } else { + /* We don't know how to compute magnetic heading for this + * location. */ + magnetic_flag = false; + } + + /* No negative headings. */ + if (heading < 0.0) + heading += 360.0; + + return (heading); + /*@ +evalorder -relaxtypes @*/ +} + +/* Function to call when we're all done. Does a bit of clean-up. */ +static void die(int sig) +{ + /* Ignore signals. */ + (void)signal(SIGINT, SIG_IGN); + (void)signal(SIGHUP, SIG_IGN); + + /* Move the cursor to the bottom left corner. */ + (void)mvcur(0, COLS - 1, LINES - 1, 0); + + /* Put input attributes back the way they were. */ + (void)echo(); + + /* Done with curses. */ + (void)endwin(); + + /* We're done talking to gpsd. */ + (void)gps_close(&gpsdata); + + switch (sig) { + case CGPS_QUIT: + break; + case GPS_GONE: + (void)fprintf(stderr, "cgps: GPS hung up.\n"); + break; + case GPS_ERROR: + (void)fprintf(stderr, "cgps: GPS read returned error\n"); + break; + default: + (void)fprintf(stderr, "cgps: caught signal %d\n", sig); + } + + /* Bye! */ + exit(0); +} + + +static enum deg_str_type deg_type = deg_dd; + +/*@ -globstate @*/ +static void windowsetup(void) +{ + /* Set the window sizes per the following criteria: + * + * 1. Set the window size to display the maximum number of + * satellites possible, but not more than the size required to + * display the maximum number of satellites gpsd is capable of + * tracking (MAXCHANNELS - 2). + * + * 2. If the screen size will not allow for the full complement of + * satellites to be displayed, set the windows sizes smaller, but + * not smaller than the number of lines necessary to display all of + * the fields in the 'datawin'. The list of displayed satellites + * will be truncated to fit the available window size. (TODO: If + * the satellite list is truncated, omit the satellites not used to + * obtain the current fix.) + * + * 3. If the screen is large enough to display all possible + * satellites (MAXCHANNELS - 2) with space still left at the bottom, + * add a window at the bottom in which to scroll raw gpsd data. + */ + int xsize, ysize; + + getmaxyx(stdscr, ysize, xsize); + +#ifdef TRUENORTH + if (compass_flag) { + if (ysize == MIN_COMPASS_DATAWIN_SIZE) { + raw_flag = false; + window_length = MIN_COMPASS_DATAWIN_SIZE; + } else if (ysize > MIN_COMPASS_DATAWIN_SIZE) { + raw_flag = true; + window_length = MIN_COMPASS_DATAWIN_SIZE; + } else { + (void)mvprintw(0, 0, + "Your screen must be at least 80x%d to run cgps.", + MIN_COMPASS_DATAWIN_SIZE); + /*@ -nullpass @*/ + (void)refresh(); + /*@ +nullpass @*/ + (void)sleep(5); + die(0); + } + } else +#endif /* TRUENORTH */ + { + if (ysize == MAX_SATWIN_SIZE) { + raw_flag = false; + window_length = MAX_SATWIN_SIZE; + display_sats = MAX_POSSIBLE_SATS; + } else if (ysize == MAX_SATWIN_SIZE + 1) { + raw_flag = true; + window_length = MAX_SATWIN_SIZE; + display_sats = MAX_POSSIBLE_SATS; + } else if (ysize > MAX_SATWIN_SIZE + 2) { + raw_flag = true; + window_length = MAX_SATWIN_SIZE; + display_sats = MAX_POSSIBLE_SATS; + } else if (ysize > MIN_GPS_DATAWIN_SIZE) { + raw_flag = false; + window_length = ysize - (int)raw_flag; + display_sats = window_length - SATWIN_OVERHEAD - (int)raw_flag; + } else if (ysize == MIN_GPS_DATAWIN_SIZE) { + raw_flag = false; + window_length = MIN_GPS_DATAWIN_SIZE; + display_sats = window_length - SATWIN_OVERHEAD - 1; + } else { + (void)mvprintw(0, 0, + "Your screen must be at least 80x%d to run cgps.", + MIN_GPS_DATAWIN_SIZE); + /*@ -nullpass @*/ + (void)refresh(); + /*@ +nullpass @*/ + (void)sleep(5); + die(0); + } + } + +#ifdef TRUENORTH + /* Set up the screen for either a compass or a gps receiver. */ + if (compass_flag) { + /* We're a compass, set up accordingly. */ + + /*@ -onlytrans @*/ + datawin = newwin(window_length, DATAWIN_WIDTH, 0, 0); + (void)nodelay(datawin, (bool) TRUE); + if (raw_flag) { + messages = newwin(0, 0, window_length, 0); + + /*@ +onlytrans @*/ + (void)scrollok(messages, true); + (void)wsetscrreg(messages, 0, ysize - (window_length)); + } + + /*@ -nullpass @*/ + (void)refresh(); + /*@ +nullpass @*/ + + /* Do the initial field label setup. */ + (void)mvwprintw(datawin, 1, DATAWIN_DESC_OFFSET, "Time:"); + (void)mvwprintw(datawin, 2, DATAWIN_DESC_OFFSET, "Heading:"); + (void)mvwprintw(datawin, 3, DATAWIN_DESC_OFFSET, "Pitch:"); + (void)mvwprintw(datawin, 4, DATAWIN_DESC_OFFSET, "Roll:"); + (void)mvwprintw(datawin, 5, DATAWIN_DESC_OFFSET, "Dip:"); + (void)mvwprintw(datawin, 6, DATAWIN_DESC_OFFSET, "Rcvr Type:"); + (void)wborder(datawin, 0, 0, 0, 0, 0, 0, 0, 0); + + } else +#endif /* TRUENORTH */ + { + /* We're a GPS, set up accordingly. */ + + /*@ -onlytrans @*/ + datawin = newwin(window_length, DATAWIN_WIDTH, 0, 0); + satellites = + newwin(window_length, SATELLITES_WIDTH, 0, DATAWIN_WIDTH); + (void)nodelay(datawin, (bool) TRUE); + if (raw_flag) { + messages = + newwin(ysize - (window_length), xsize, window_length, 0); + + /*@ +onlytrans @*/ + (void)scrollok(messages, true); + (void)wsetscrreg(messages, 0, ysize - (window_length)); + } + + /*@ -nullpass @*/ + (void)refresh(); + /*@ +nullpass @*/ + + /* Do the initial field label setup. */ + (void)mvwprintw(datawin, 1, DATAWIN_DESC_OFFSET, "Time:"); + (void)mvwprintw(datawin, 2, DATAWIN_DESC_OFFSET, "Latitude:"); + (void)mvwprintw(datawin, 3, DATAWIN_DESC_OFFSET, "Longitude:"); + (void)mvwprintw(datawin, 4, DATAWIN_DESC_OFFSET, "Altitude:"); + (void)mvwprintw(datawin, 5, DATAWIN_DESC_OFFSET, "Speed:"); + (void)mvwprintw(datawin, 6, DATAWIN_DESC_OFFSET, "Heading:"); + (void)mvwprintw(datawin, 7, DATAWIN_DESC_OFFSET, "Climb:"); + (void)mvwprintw(datawin, 8, DATAWIN_DESC_OFFSET, "Status:"); + (void)mvwprintw(datawin, 9, DATAWIN_DESC_OFFSET, "GPS Type:"); + + /* Note that the following four fields are exceptions to the + * sizing rule. The minimum window size does not include these + * fields, if the window is too small, they get excluded. This + * may or may not change if/when the output for these fields is + * fixed and/or people request their permanance. They're only + * there in the first place because I arbitrarily thought they + * sounded interesting. ;^) */ + + if (window_length >= (MIN_GPS_DATAWIN_SIZE + 5)) { + (void)mvwprintw(datawin, 10, DATAWIN_DESC_OFFSET, + "Longitude Err:"); + (void)mvwprintw(datawin, 11, DATAWIN_DESC_OFFSET, + "Latitude Err:"); + (void)mvwprintw(datawin, 12, DATAWIN_DESC_OFFSET, + "Altitude Err:"); + (void)mvwprintw(datawin, 13, DATAWIN_DESC_OFFSET, "Course Err:"); + (void)mvwprintw(datawin, 14, DATAWIN_DESC_OFFSET, "Speed Err:"); + } + + (void)wborder(datawin, 0, 0, 0, 0, 0, 0, 0, 0); + (void)mvwprintw(satellites, 1, 1, "PRN: Elev: Azim: SNR: Used:"); + (void)wborder(satellites, 0, 0, 0, 0, 0, 0, 0, 0); + } +} + +/*@ +globstate @*/ + +#ifdef TRUENORTH +/* This gets called once for each new compass sentence. */ +static void update_compass_panel(struct gps_data_t *gpsdata, + char *message, size_t len UNUSED) +{ + char scr[128]; + /* Print time/date. */ + if (isnan(gpsdata->fix.time) == 0) { + (void)unix_to_iso8601(gpsdata->fix.time, scr, sizeof(scr)); + } else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 1, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in the heading. */ + if (isnan(gpsdata->fix.track) == 0) { + (void)snprintf(scr, sizeof(scr), "%.1f degrees", gpsdata->fix.track); + } else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 2, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in the pitch. */ + if (isnan(gpsdata->fix.climb) == 0) { + (void)snprintf(scr, sizeof(scr), "%.1f", gpsdata->fix.climb); + } else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 3, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in the roll. */ + if (isnan(gpsdata->fix.speed) == 0) + (void)snprintf(scr, sizeof(scr), "%.1f", gpsdata->fix.speed); + else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 4, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in the speed. */ + if (isnan(gpsdata->fix.altitude) == 0) + (void)snprintf(scr, sizeof(scr), "%.1f", gpsdata->fix.altitude); + else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 5, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* When we need to fill in receiver type again, do it here. */ + (void)mvwprintw(datawin, 6, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Be quiet if the user requests silence. */ + if (!silent_flag && raw_flag) { + (void)waddstr(messages, message); + } + + (void)wrefresh(datawin); + if (raw_flag) { + (void)wrefresh(messages); + } +} +#endif /* TRUENORTH */ + +/* This gets called once for each new GPS sentence. */ +static void update_gps_panel(struct gps_data_t *gpsdata, + char *message, size_t len UNUSED) +{ + int i, j, n; + int newstate; + char scr[128]; + bool usedflags[MAXCHANNELS]; + + /* this is where we implement source-device filtering */ + if (gpsdata->dev.path[0] != '\0' && source.device != NULL + && strcmp(source.device, gpsdata->dev.path) != 0) + return; + + /* must build bit vector of which statellites are used from list */ + for (i = 0; i < MAXCHANNELS; i++) { + usedflags[i] = false; + for (j = 0; j < gpsdata->satellites_used; j++) + if (gpsdata->used[j] == gpsdata->PRN[i]) + usedflags[i] = true; + } + + /* This is for the satellite status display. Originally lifted from + * xgps.c. Note that the satellite list may be truncated based on + * available screen size, or may only show satellites used for the + * fix. */ + if (gpsdata->satellites_visible != 0) { + if (display_sats >= MAX_POSSIBLE_SATS) { + for (i = 0; i < MAX_POSSIBLE_SATS; i++) { + if (i < gpsdata->satellites_visible) { + (void)snprintf(scr, sizeof(scr), + " %3d %02d %03d %02d %c", + gpsdata->PRN[i], + gpsdata->elevation[i], gpsdata->azimuth[i], + (int)gpsdata->ss[i], + usedflags[i] ? 'Y' : 'N'); + } else { + (void)strlcpy(scr, "", sizeof(scr)); + } + (void)mvwprintw(satellites, i + 2, 1, "%-*s", + SATELLITES_WIDTH - 3, scr); + } + } else { + n = 0; + for (i = 0; i < MAX_POSSIBLE_SATS; i++) { + if (n < display_sats) { + if ((i < gpsdata->satellites_visible) + && ((gpsdata->used[i] != 0) + || (gpsdata->satellites_visible <= display_sats))) { + (void)snprintf(scr, sizeof(scr), + " %3d %02d %03d %02d %c", + gpsdata->PRN[i], gpsdata->elevation[i], + gpsdata->azimuth[i], + (int)gpsdata->ss[i], + gpsdata->used[i] ? 'Y' : 'N'); + (void)mvwprintw(satellites, n + 2, 1, "%-*s", + SATELLITES_WIDTH - 3, scr); + n++; + } + } + } + + if (n < display_sats) { + for (i = n; i <= display_sats; i++) { + (void)mvwprintw(satellites, i + 2, 1, "%-*s", + SATELLITES_WIDTH - 3, ""); + } + } + + } + } + + /* Print time/date. */ + if (isnan(gpsdata->fix.time) == 0) { + (void)unix_to_iso8601(gpsdata->fix.time, scr, sizeof(scr)); + } else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 1, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + + /* Fill in the latitude. */ + if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.latitude) == 0) { + (void)snprintf(scr, sizeof(scr), "%s %c", + deg_to_str(deg_type, fabs(gpsdata->fix.latitude)), + (gpsdata->fix.latitude < 0) ? 'S' : 'N'); + } else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 2, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in the longitude. */ + if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.longitude) == 0) { + (void)snprintf(scr, sizeof(scr), "%s %c", + deg_to_str(deg_type, fabs(gpsdata->fix.longitude)), + (gpsdata->fix.longitude < 0) ? 'W' : 'E'); + } else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 3, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in the altitude. */ + if (gpsdata->fix.mode == MODE_3D && isnan(gpsdata->fix.altitude) == 0) + (void)snprintf(scr, sizeof(scr), "%.1f %s", + gpsdata->fix.altitude * altfactor, altunits); + else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 4, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in the speed. */ + if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track) == 0) + (void)snprintf(scr, sizeof(scr), "%.1f %s", + gpsdata->fix.speed * speedfactor, speedunits); + else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 5, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in the heading. */ + if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track) == 0) + if (!magnetic_flag) { + (void)snprintf(scr, sizeof(scr), "%.1f deg (true)", + gpsdata->fix.track); + } else { + (void)snprintf(scr, sizeof(scr), "%.1f deg (mag) ", + true2magnetic(gpsdata->fix.latitude, + gpsdata->fix.longitude, + gpsdata->fix.track)); + } else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 6, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in the rate of climb. */ + if (gpsdata->fix.mode == MODE_3D && isnan(gpsdata->fix.climb) == 0) + (void)snprintf(scr, sizeof(scr), "%.1f %s/min", + gpsdata->fix.climb * altfactor * 60, altunits); + else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 7, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in the GPS status and the time since the last state + * change. */ + if (gpsdata->online == 0) { + newstate = 0; + (void)snprintf(scr, sizeof(scr), "OFFLINE"); + } else { + newstate = gpsdata->fix.mode; + switch (gpsdata->fix.mode) { + case MODE_2D: + (void)snprintf(scr, sizeof(scr), "2D %sFIX (%d secs)", + (gpsdata->status == + STATUS_DGPS_FIX) ? "DIFF " : "", + (int)(time(NULL) - status_timer)); + break; + case MODE_3D: + (void)snprintf(scr, sizeof(scr), "3D %sFIX (%d secs)", + (gpsdata->status == + STATUS_DGPS_FIX) ? "DIFF " : "", + (int)(time(NULL) - status_timer)); + break; + default: + (void)snprintf(scr, sizeof(scr), "NO FIX (%d secs)", + (int)(time(NULL) - status_timer)); + break; + } + } + (void)mvwprintw(datawin, 8, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + + /* Fill in receiver type. */ + if (gpsdata->set & (DEVICE_SET | DEVICELIST_SET)) { +#ifdef CLIENTDEBUG_ENABLE + if (debug > 0) + (void)fprintf(stderr, "Device ID or list set.\n"); +#endif + if (gpsdata->set & DEVICE_SET) { + (void)snprintf(scr, sizeof(scr), "%s", gpsdata->dev.driver); + } else if (gpsdata->devices.ndevices == 1) { + (void)snprintf(scr, sizeof(scr), "%s", + gpsdata->devices.list[0].driver); + } else { + (void)snprintf(scr, sizeof(scr), "%d devices", + gpsdata->devices.ndevices); + } + (void)mvwprintw(datawin, 9, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); + } + /* Note that the following four fields are exceptions to the + * sizing rule. The minimum window size does not include these + * fields, if the window is too small, they get excluded. This + * may or may not change if/when the output for these fields is + * fixed and/or people request their permanance. They're only + * there in the first place because I arbitrarily thought they + * sounded interesting. ;^) */ + + if (window_length >= (MIN_GPS_DATAWIN_SIZE + 4)) { + + /* Fill in the estimated horizontal position error. */ + if (isnan(gpsdata->fix.epx) == 0) + (void)snprintf(scr, sizeof(scr), "+/- %d %s", + (int)(gpsdata->fix.epx * altfactor), altunits); + else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 10, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, + scr); + + if (isnan(gpsdata->fix.epy) == 0) + (void)snprintf(scr, sizeof(scr), "+/- %d %s", + (int)(gpsdata->fix.epy * altfactor), altunits); + else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 11, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, + scr); + + /* Fill in the estimated vertical position error. */ + if (isnan(gpsdata->fix.epv) == 0) + (void)snprintf(scr, sizeof(scr), "+/- %d %s", + (int)(gpsdata->fix.epv * altfactor), altunits); + else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 12, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, + scr); + + /* Fill in the estimated track error. */ + if (isnan(gpsdata->fix.epd) == 0) + (void)snprintf(scr, sizeof(scr), "+/- %d deg", + (int)(gpsdata->fix.epd)); + else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 13, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, + scr); + + /* Fill in the estimated speed error. */ + if (isnan(gpsdata->fix.eps) == 0) + (void)snprintf(scr, sizeof(scr), "+/- %d %s", + (int)(gpsdata->fix.eps * speedfactor), speedunits); + else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(datawin, 14, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, + scr); + } + + /* Be quiet if the user requests silence. */ + if (!silent_flag && raw_flag) { + (void)waddstr(messages, message); + } + + /* Reset the status_timer if the state has changed. */ + if (newstate != state) { + status_timer = time(NULL); + state = newstate; + } + + (void)wrefresh(datawin); + (void)wrefresh(satellites); + if (raw_flag) { + (void)wrefresh(messages); + } +} + +static void usage(char *prog) +{ + (void)fprintf(stderr, + "Usage: %s [-h] [-V] [-l {d|m|s}] [server[:port:[device]]]\n\n" + " -h Show this help, then exit\n" + " -V Show version, then exit\n" + " -s Be silent (don't print raw gpsd data)\n" + " -l {d|m|s} Select lat/lon format\n" + " d = DD.dddddd\n" + " m = DD MM.mmmm'\n" + " s = DD MM' SS.sss\"\n" + " -m Display heading as the estimated magnetic heading\n" + " Valid only for USA (Lower 48 + AK) and Western Europe.\n", + prog); + + exit(1); +} + +/* + * No protocol dependencies above this line + */ + +int main(int argc, char *argv[]) +{ + int option; + int c; + + struct timeval timeout; + fd_set rfds; + int data; + + /*@ -observertrans @*/ + switch (gpsd_units()) { + case imperial: + altfactor = METERS_TO_FEET; + altunits = "ft"; + speedfactor = MPS_TO_MPH; + speedunits = "mph"; + break; + case nautical: + altfactor = METERS_TO_FEET; + altunits = "ft"; + speedfactor = MPS_TO_KNOTS; + speedunits = "knots"; + break; + case metric: + altfactor = 1; + altunits = "m"; + speedfactor = MPS_TO_KPH; + speedunits = "kph"; + break; + default: + /* leave the default alone */ + break; + } + /*@ +observertrans @*/ + + /* Process the options. Print help if requested. */ + while ((option = getopt(argc, argv, "hVl:smuD:")) != -1) { + switch (option) { +#ifdef CLIENTDEBUG_ENABLE + case 'D': + debug = atoi(optarg); + gps_enable_debug(debug, stderr); + break; +#endif /* CLIENTDEBUG_ENABLE */ + case 'm': + magnetic_flag = true; + break; + case 's': + silent_flag = true; + break; + case 'u': + /*@ -observertrans @*/ + switch (optarg[0]) { + case 'i': + altfactor = METERS_TO_FEET; + altunits = "ft"; + speedfactor = MPS_TO_MPH; + speedunits = "mph"; + continue; + case 'n': + altfactor = METERS_TO_FEET; + altunits = "ft"; + speedfactor = MPS_TO_KNOTS; + speedunits = "knots"; + continue; + case 'm': + altfactor = 1; + altunits = "m"; + speedfactor = MPS_TO_KPH; + speedunits = "kph"; + continue; + default: + (void)fprintf(stderr, "Unknown -u argument: %s\n", optarg); + } + break; + /*@ +observertrans @*/ + case 'V': + (void)fprintf(stderr, "cgps: %s (revision %s)\n", + VERSION, REVISION); + exit(0); + case 'l': + switch (optarg[0]) { + case 'd': + deg_type = deg_dd; + continue; + case 'm': + deg_type = deg_ddmm; + continue; + case 's': + deg_type = deg_ddmmss; + continue; + default: + (void)fprintf(stderr, "Unknown -l argument: %s\n", optarg); + /*@ -casebreak @*/ + } + break; + case 'h': + default: + usage(argv[0]); + break; + } + } + + /* Grok the server, port, and device. */ + if (optind < argc) { + gpsd_source_spec(argv[optind], &source); + } else + gpsd_source_spec(NULL, &source); + + /* Open the stream to gpsd. */ + if (gps_open_r(source.server, source.port, &gpsdata) != 0) { + (void)fprintf(stderr, + "cgps: no gpsd running or network error: %d, %s\n", + errno, gps_errstr(errno)); + exit(2); + } + + /* Fire up curses. */ + (void)initscr(); + (void)noecho(); + (void)signal(SIGINT, die); + (void)signal(SIGHUP, die); + + windowsetup(); + + /* Here's where updates go now that things are established. */ +#ifdef TRUENORTH + if (compass_flag) { + gps_set_raw_hook(&gpsdata, update_compass_panel); + } else +#endif /* TRUENORTH */ + { + gps_set_raw_hook(&gpsdata, update_gps_panel); + } + + status_timer = time(NULL); + + (void)gps_stream(&gpsdata, WATCH_ENABLE, NULL); + + /* heart of the client */ + for (;;) { + + /* watch to see when it has input */ + FD_ZERO(&rfds); + FD_SET(gpsdata.gps_fd, &rfds); + + /* wait up to five seconds. */ + timeout.tv_sec = 5; + timeout.tv_usec = 0; + + /* check if we have new information */ + data = select(gpsdata.gps_fd + 1, &rfds, NULL, NULL, &timeout); + + if (data == -1) { + fprintf(stderr, "cgps: socket error 3\n"); + exit(2); + } else if (data) { + errno = 0; + if (gps_read(&gpsdata) == -1) { + fprintf(stderr, "cgps: socket error 4\n"); + die(errno == 0 ? GPS_GONE : GPS_ERROR); + } + } + + /* Check for user input. */ + c = wgetch(datawin); + + switch (c) { + /* Quit */ + case 'q': + die(CGPS_QUIT); + break; + + /* Toggle spewage of raw gpsd data. */ + case 's': + silent_flag = !silent_flag; + break; + + /* Clear the spewage area. */ + case 'c': + (void)werase(messages); + break; + + default: + break; + } + + } +} diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..e3a2116 --- /dev/null +++ b/config.guess @@ -0,0 +1,1533 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-06-10' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd | genuineintel) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..eb0389a --- /dev/null +++ b/config.sub @@ -0,0 +1,1693 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-06-11' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..b843a7c --- /dev/null +++ b/configure @@ -0,0 +1,21078 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.67. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$lt_ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +ECHO=${lt_ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<_LT_EOF +$* +_LT_EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$lt_ECHO"; then + if test "X${echo_test_string+set}" != Xset; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if { echo_test_string=`eval $cmd`; } 2>/dev/null && + { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null + then + break + fi + done + fi + + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : + else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$ECHO" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + ECHO='print -r' + elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + ECHO='printf %s\n' + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + ECHO="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + ECHO=echo + fi + fi + fi + fi + fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +lt_ECHO=$ECHO +if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +XMLPROCFLAGS +HTMLTARGET +MANTARGET +XMLPROC +XMLTOSTDOUT_FALSE +XMLTOSTDOUT_TRUE +HAVE_XSLT_PROCESSOR_FALSE +HAVE_XSLT_PROCESSOR_TRUE +WITH_XMLTO +WITH_XSLTPROC +IPV6_ENABLE_FALSE +IPV6_ENABLE_TRUE +QMAKE +LIB_Q_GPSMM_ENABLE_FALSE +LIB_Q_GPSMM_ENABLE_TRUE +QtNetwork_LIBS +QtNetwork_CFLAGS +LIBGPSMM_ENABLE_FALSE +LIBGPSMM_ENABLE_TRUE +HAVE_BLUEZ_FALSE +HAVE_BLUEZ_TRUE +HAVE_DBUS_FALSE +HAVE_DBUS_TRUE +DBUS_GLIB_LIBS +DBUS_GLIB_CFLAGS +DBUS_LIBS +DBUS_CFLAGS +BLUEZ_LIBS +BLUEZ_CFLAGS +CLIENTDEBUG_ENABLE_FALSE +CLIENTDEBUG_ENABLE_TRUE +HAVE_AIVDM_FALSE +HAVE_AIVDM_TRUE +HAVE_NTRIP_FALSE +HAVE_NTRIP_TRUE +HAVE_RTCM104V3_FALSE +HAVE_RTCM104V3_TRUE +HAVE_RTCM104V2_FALSE +HAVE_RTCM104V2_TRUE +HAVE_NCURSES_FALSE +HAVE_NCURSES_TRUE +NCURSES_LIBS +LIBUSB_LIBS +LIBUSB_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +LIBPTHREAD +LIBC +LIBM +LIBSOCKET +LIBNSL +ALLOCA +CXXCPP +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +lt_ECHO +RANLIB +AR +OBJDUMP +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +LN_S +HAVE_PYTHON_FALSE +HAVE_PYTHON_TRUE +PYTHON_LIBS +PYTHON_DISTUTILS_SCRIPTDIR +PYTHON_DISTUTILS_LIBDIR +PYTHON_CFLAGS +pkgpyexecdir +pyexecdir +pkgpythondir +pythondir +PYTHON_PLATFORM +PYTHON_EXEC_PREFIX +PYTHON_PREFIX +PYTHON_VERSION +PYTHON +EGREP +GREP +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +enable_libtool_lock +enable_nmea +enable_oncore +enable_sirf +enable_superstar2 +enable_tsip +enable_fv18 +enable_tripmate +enable_earthmate +enable_itrax +enable_ashtech +enable_navcom +enable_garmin +enable_garmintxt +enable_tnt +enable_oceanserver +enable_ubx +enable_evermore +enable_mtk3301 +enable_gpsclock +enable_rtcm104v2 +enable_rtcm104v3 +enable_ntrip +enable_aivdm +enable_timing +enable_clientdebug +enable_oldstyle +enable_profiling +enable_ntpshm +enable_pps +enable_pps_on_cts +enable_gpsd_user +enable_gpsd_group +enable_fixed_port_speed +enable_bluetooth +enable_dbus +enable_max_clients +enable_max_devices +enable_reconfigure +enable_controlsend +enable_raw +enable_squelch +enable_libgpsmm +enable_libQgpsmm +enable_ipv6 +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +CXX +CXXFLAGS +CCC +CXXCPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +LIBUSB_CFLAGS +LIBUSB_LIBS +QtNetwork_CFLAGS +QtNetwork_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-nmea disable NMEA support + --disable-oncore disable Motorola OnCore chipset support + --disable-sirf disable SiRF chipset support + --disable-superstar2 disable SuperStarII chipset support + --disable-tsip disable Trimble TSIP support + --disable-fv18 disable San Jose Navigation FV-18 support + --disable-tripmate disable DeLorme TripMate support + --disable-earthmate disable DeLorme EarthMate Zodiac support + --disable-itrax disable iTrax hardware support + --disable-ashtech disable Ashtech support + --disable-navcom disable Navcom support + --disable-garmin disable Garmin kernel driver support + --enable-garmintxt enable Garmin Simple Text support + --enable-tnt disable True North Technologies support + --disable-oceanserver disable OceanServer support + --disable-ubx disable UBX Protocol support + --disable-evermore disable EverMore binary support + --disable-mtk3301 disable MTK-3301 support + --disable-gpsclock disable GPSClock support + --disable-rtcm104v2 disable rtcm104v2 support + --disable-rtcm104v3 disable rtcm104v3 support + --disable-ntrip disable NTRIP support + --disable-aivdm disable Aivdm support + --disable-timing disable latency timing support + --disable-clientdebug disable client debugging support + --disable-oldstyle disable oldstyle (pre-JSON) protocol support + --enable-profiling enable profiling support + --disable-ntpshm disable NTP time hinting support + --disable-pps disable PPS time syncing support + --enable-pps-on-cts Enable PPS pulse on CTS rather than DCD + --enable-gpsd-user=username + GPSD privilege revocation user + --enable-gpsd-group=groupname + GPSD privilege revocation group, use if /dev/ttyS0 + not found + --enable-fixed-port-speed=nnn + compile with fixed serial port speed + --enable-bluetooth Enable support for Bluetooth GPS devices via BlueZ + (experimental) + --enable-dbus enable DBUS support + --enable-max-clients=nnn + compile with limited maximum clients + --enable-max-devices=nnn + compile with maximum allowed devices + --disable-reconfigure do not allow gpsd to change device settings + --disable-controlsend do not allow gpsctl/gpsmon to change device settings + --enable-raw enable raw measurement processing + --enable-squelch squelch gpsd_report and gpsd_hexdump to save cpu + --disable-libgpsmm don't build C++ bindings + --disable-libQgpsmm don't build QT bindings + --disable-ipv6 don't build IPv6 support + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + LIBUSB_CFLAGS + C compiler flags for LIBUSB, overriding pkg-config + LIBUSB_LIBS linker flags for LIBUSB, overriding pkg-config + QtNetwork_CFLAGS + C compiler flags for QtNetwork, overriding pkg-config + QtNetwork_LIBS + linker flags for QtNetwork, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.67 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval "test \"\${$3+set}\"" = set; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 &5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval "test \"\${$4+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_member + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_decl +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.67. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5 ; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +am__api_version='1.11' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5 ;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5 ;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=gpsd + VERSION=2.95 + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +ac_config_headers="$ac_config_headers gpsd_config.h" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# ACREQUIRE_BUGFIX +# ---------------- +# Due to a longstanding Autoconf bug (Autoconf 2.50 to at least 2.63), +# any macro that is AC_REQUIREd at any point must be AC_REQUIREd +# *before* it is directly expanded. The macros below were being +# directly expanded before being AC_REQUIREd, so we AC_REQUIRE them +# early to prevent out-of-order expansion problems. See the threads +# at: +# http://lists.gnu.org/archive/html/bug-autoconf/2008-12/msg00039.html +# http://lists.gnu.org/archive/html/autoconf-patches/2008-12/msg00058.html +# http://lists.gnu.org/archive/html/bug-autoconf/2009-01/msg00019.html +# http://lists.gnu.org/archive/html/bug-gnulib/2009-01/msg00247.html + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5 ; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5 ; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5 ; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5 ; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5 ; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5 ; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + + + + + + +# ACREQUIRE_BUGFIX done + + + + + + + if test -n "$PYTHON"; then + # If the user set $PYTHON, use it and don't search something else. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version >= 2.4" >&5 +$as_echo_n "checking whether $PYTHON version >= 2.4... " >&6; } + prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '2.4'.split('.'))) + [0, 0, 0] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] +sys.exit(sys.hexversion < minverhex)" + if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 + ($PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + as_fn_error $? "too old" "$LINENO" 5 +fi + am_display_PYTHON=$PYTHON + else + # Otherwise, try each interpreter until we find one that satisfies + # VERSION. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 2.4" >&5 +$as_echo_n "checking for a Python interpreter with version >= 2.4... " >&6; } +if test "${am_cv_pathless_PYTHON+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + + for am_cv_pathless_PYTHON in python2.6 python2.5 python2.4 python none; do + test "$am_cv_pathless_PYTHON" = none && break + prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '2.4'.split('.'))) + [0, 0, 0] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] +sys.exit(sys.hexversion < minverhex)" + if { echo "$as_me:$LINENO: $am_cv_pathless_PYTHON -c "$prog"" >&5 + ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then : + break +fi + done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 +$as_echo "$am_cv_pathless_PYTHON" >&6; } + # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. + if test "$am_cv_pathless_PYTHON" = none; then + PYTHON=: + else + # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args. +set dummy $am_cv_pathless_PYTHON; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_PYTHON+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $PYTHON in + [\\/]* | ?:[\\/]*) + ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PYTHON=$ac_cv_path_PYTHON +if test -n "$PYTHON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 +$as_echo "$PYTHON" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi + am_display_PYTHON=$am_cv_pathless_PYTHON + fi + + + if test "$PYTHON" = :; then + as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5 + else + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 +$as_echo_n "checking for $am_display_PYTHON version... " >&6; } +if test "${am_cv_python_version+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 +$as_echo "$am_cv_python_version" >&6; } + PYTHON_VERSION=$am_cv_python_version + + + + PYTHON_PREFIX='${prefix}' + + PYTHON_EXEC_PREFIX='${exec_prefix}' + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 +$as_echo_n "checking for $am_display_PYTHON platform... " >&6; } +if test "${am_cv_python_platform+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 +$as_echo "$am_cv_python_platform" >&6; } + PYTHON_PLATFORM=$am_cv_python_platform + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5 +$as_echo_n "checking for $am_display_PYTHON script directory... " >&6; } +if test "${am_cv_python_pythondir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$prefix" = xNONE + then + am_py_prefix=$ac_default_prefix + else + am_py_prefix=$prefix + fi + am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null || + echo "$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages"` + case $am_cv_python_pythondir in + $am_py_prefix*) + am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` + am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` + ;; + *) + case $am_py_prefix in + /usr|/System*) ;; + *) + am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 +$as_echo "$am_cv_python_pythondir" >&6; } + pythondir=$am_cv_python_pythondir + + + + pkgpythondir=\${pythondir}/$PACKAGE + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5 +$as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; } +if test "${am_cv_python_pyexecdir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$exec_prefix" = xNONE + then + am_py_exec_prefix=$am_py_prefix + else + am_py_exec_prefix=$exec_prefix + fi + am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null || + echo "$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages"` + case $am_cv_python_pyexecdir in + $am_py_exec_prefix*) + am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` + am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` + ;; + *) + case $am_py_exec_prefix in + /usr|/System*) ;; + *) + am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 +$as_echo "$am_cv_python_pyexecdir" >&6; } + pyexecdir=$am_cv_python_pyexecdir + + + + pkgpyexecdir=\${pyexecdir}/$PACKAGE + + + + fi + + +ac_python=yes +if test "x$PYTHON" = "x"; then + # Extract the first word of "python", so it can be a program name with args. +set dummy python; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_PYTHON+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $PYTHON in + [\\/]* | ?:[\\/]*) + ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_PYTHON" && ac_cv_path_PYTHON="none" + ;; +esac +fi +PYTHON=$ac_cv_path_PYTHON +if test -n "$PYTHON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 +$as_echo "$PYTHON" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi + +if test "x$PYTHON" = "xnone"; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Python interpreter not found, Python support disabled." >&5 +$as_echo "$as_me: WARNING: *** Python interpreter not found, Python support disabled." >&2;} + ac_python=no +fi + +if test "x$ac_python" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking Python version and location" >&5 +$as_echo_n "checking Python version and location... " >&6; } + PYTHON_PREFIX=`$PYTHON -c "import sys; print(sys.prefix)"` + PYTHON_VERSION_MAJOR=`$PYTHON -c "import sys; print('%d' % (sys.version_info[0]));"` + PYTHON_VERSION_MINOR=`$PYTHON -c "import sys; print('%d' % (sys.version_info[1]));"` + PYTHON_VERSION="${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON, $PYTHON_VERSION, $PYTHON_PREFIX" >&5 +$as_echo "$PYTHON, $PYTHON_VERSION, $PYTHON_PREFIX" >&6; } + + PYTHON_CFLAGS="-DHAVE_PYTHON -I$PYTHON_PREFIX/include/python$PYTHON_VERSION" + + # Define the directories we ask setup.py to install the + # modules/extensions and scripts to. The way chosen here reproduces + # the internal behaviour of distutils. Unfortunately distutils does + # not export the pre-defined/configured directories, so we have to + # define them on our own. For default installations of distutils the + # chosen values here will match what distutils uses. + # See Makefile.am to see how they're used with setup.py. + PYTHON_DISTUTILS_LIBDIR=`$PYTHON -c 'import distutils.util; import sys; print ("build/lib.%s-%s" %(distutils.util.get_platform(), sys.version[0:3]))'` + PYTHON_DISTUTILS_SCRIPTDIR=`$PYTHON -c 'import sys; print ("build/scripts-%s" %(sys.version[0:3], ))'` + + OLD_CPPFLAGS="$CPPFLAGS" + OLD_CXXFLAGS="$CXXFLAGS" + CPPFLAGS="$CPPFLAGS $PYTHON_CFLAGS" + CXXFLAGS="$CXXFLAGS $PYTHON_CFLAGS" + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in Python.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "Python.h" "ac_cv_header_Python_h" "$ac_includes_default" +if test "x$ac_cv_header_Python_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PYTHON_H 1 +_ACEOF + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Python include files not found! You should install the Python development package. Python support disabled" >&5 +$as_echo "$as_me: WARNING: *** Python include files not found! You should install the Python development package. Python support disabled" >&2;}; ac_python=no +fi + +done + + CPPFLAGS="$OLD_CPPFLAGS" + CXXFLAGS="$OLD_CXXFLAGS" + + if test "x$ac_python" = "xyes"; then + + + + + ac_python=no + for pylibpath in '/usr/lib' $PYTHON_PREFIX/lib $PYTHON_PREFIX/lib/python$PYTHON_VERSION/config; do + eval `echo unset ac_cv_lib_python$PYTHON_VERSION'___'Py_Finalize | tr '.' '_'` + + save_LIBS=$LIBS + LIBS="$LIBS -L$pylibpath $PYTHON_LIBS" + as_ac_Lib=`$as_echo "ac_cv_lib_python$PYTHON_VERSION''_Py_Finalize" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Py_Finalize in -lpython$PYTHON_VERSION" >&5 +$as_echo_n "checking for Py_Finalize in -lpython$PYTHON_VERSION... " >&6; } +if eval "test \"\${$as_ac_Lib+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpython$PYTHON_VERSION $PYTHON_DEPS $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char Py_Finalize (); +int +main () +{ +return Py_Finalize (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + PYTHON_LIBS="-L$pylibpath -lpython$PYTHON_VERSION $PYTHON_DEPS"; ac_python=yes +fi + + LIBS=$save_LIBS + if test "x$ac_python" = "xyes"; then + break + fi + done + + if test "x$ac_python" != "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Python development libraries required" >&5 +$as_echo "$as_me: WARNING: *** Python development libraries required" >&2;} + fi + + + + if test "x$python_install" = "xyes"; then + pkgpythondir=$PYTHON_PREFIX"/lib/python"$PYTHON_VERSION"/site-packages/gpsd" + fi + fi +fi + if test x"$ac_python" = xyes; then + HAVE_PYTHON_TRUE= + HAVE_PYTHON_FALSE='#' +else + HAVE_PYTHON_TRUE='#' + HAVE_PYTHON_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.2.6b' +macro_revision='1.3017' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if test "${ac_cv_path_SED+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if test "${ac_cv_path_FGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if test "${lt_cv_path_NM+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$ac_tool_prefix"; then + for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DUMPBIN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in "dumpbin -symbols" "link -dump -symbols" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if test "${lt_cv_nm_interface+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:5800: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:5803: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:5806: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if test "${lt_cv_sys_max_cmd_len+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ + = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if test "${lt_cv_ld_reload_flag+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if test "${lt_cv_deplibs_check_method+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + + + + + + + + + + + + + + + + + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 7000 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if test "${lt_cv_cc_needs_belf+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DSYMUTIL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_NMEDIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_LIPO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if test "${lt_cv_apple_cc_single_mod+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if test "${lt_cv_ld_exported_symbols_list+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if test "${lt_cv_objdir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + + + + + + + + + + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:8258: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:8262: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl*) + # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 +$as_echo "$lt_prog_compiler_pic" >&6; } + + + + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test "${lt_cv_prog_compiler_pic_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:8597: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:8601: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test "${lt_cv_prog_compiler_static_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:8702: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:8706: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:8757: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:8761: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag= + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo(void) {} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 +$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = x""yes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if test "${ac_cv_lib_dld_shl_load+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = x""yes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if test "${ac_cv_lib_svld_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if test "${ac_cv_lib_dld_dld_link+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = x""yes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 11141 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self_static+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 11237 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +_lt_caught_CXX_error=yes; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5]* | *pgcpp\ [1-5]*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 will use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + xl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=echo + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC*) + # IBM XL 8.0 on PPC + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_prog_compiler_pic_CXX" >&6; } + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14123: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:14127: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14222: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:14226: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14274: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:14278: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + linux* | k*bsd*-gnu) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + archive_cmds_need_lc_CXX=no + else + archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc_CXX" >&5 +$as_echo "$archive_cmds_need_lc_CXX" >&6; } + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if test "${ac_cv_c_bigendian+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + +type_error="no" +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 +$as_echo_n "checking size of char... " >&6; } +if test "${ac_cv_sizeof_char+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_char" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (char) +See \`config.log' for more details" "$LINENO" 5 ; } + else + ac_cv_sizeof_char=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 +$as_echo "$ac_cv_sizeof_char" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR $ac_cv_sizeof_char +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +$as_echo_n "checking size of short... " >&6; } +if test "${ac_cv_sizeof_short+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (short) +See \`config.log' for more details" "$LINENO" 5 ; } + else + ac_cv_sizeof_short=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +$as_echo "$ac_cv_sizeof_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +$as_echo_n "checking size of int... " >&6; } +if test "${ac_cv_sizeof_int+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5 ; } + else + ac_cv_sizeof_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +$as_echo "$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if test "${ac_cv_sizeof_long+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5 ; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 +$as_echo_n "checking size of long long... " >&6; } +if test "${ac_cv_sizeof_long_long+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long long) +See \`config.log' for more details" "$LINENO" 5 ; } + else + ac_cv_sizeof_long_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 +$as_echo "$ac_cv_sizeof_long_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of float" >&5 +$as_echo_n "checking size of float... " >&6; } +if test "${ac_cv_sizeof_float+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (float))" "ac_cv_sizeof_float" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_float" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (float) +See \`config.log' for more details" "$LINENO" 5 ; } + else + ac_cv_sizeof_float=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_float" >&5 +$as_echo "$ac_cv_sizeof_float" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_FLOAT $ac_cv_sizeof_float +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5 +$as_echo_n "checking size of double... " >&6; } +if test "${ac_cv_sizeof_double+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_double" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (double) +See \`config.log' for more details" "$LINENO" 5 ; } + else + ac_cv_sizeof_double=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5 +$as_echo "$ac_cv_sizeof_double" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_DOUBLE $ac_cv_sizeof_double +_ACEOF + + +if test x"$ac_cv_sizeof_char" != "x1" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gpsd requires sizeof(char)==1" >&5 +$as_echo "$as_me: WARNING: gpsd requires sizeof(char)==1" >&2;}; + type_error="yes" +fi +if test x"$ac_cv_sizeof_short" != "x2" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gpsd requires sizeof(short)==2" >&5 +$as_echo "$as_me: WARNING: gpsd requires sizeof(short)==2" >&2;}; + type_error="yes" +fi +if test x"$ac_cv_sizeof_int" != "x4" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gpsd requires sizeof(int)==4" >&5 +$as_echo "$as_me: WARNING: gpsd requires sizeof(int)==4" >&2;}; + type_error="yes" +fi +if test x"$ac_cv_sizeof_long_long" != "x8" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gpsd requires sizeof(long long)==8" >&5 +$as_echo "$as_me: WARNING: gpsd requires sizeof(long long)==8" >&2;}; + type_error="yes" +fi +if test x"$ac_cv_sizeof_float" != "x4" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gpsd requires sizeof(float)==4" >&5 +$as_echo "$as_me: WARNING: gpsd requires sizeof(float)==4" >&2;}; + type_error="yes" +fi +if test x"$ac_cv_sizeof_double" != "x8" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gpsd requires sizeof(double)==8" >&5 +$as_echo "$as_me: WARNING: gpsd requires sizeof(double)==8" >&2;}; + type_error="yes" +fi +if test x"$type_error" = "xyes" ; then + as_fn_error $? "Your system does not provide all required data types" "$LINENO" 5 ; +fi + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 +$as_echo_n "checking for working alloca.h... " >&6; } +if test "${ac_cv_working_alloca_h+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_working_alloca_h=yes +else + ac_cv_working_alloca_h=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 +$as_echo "$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 +$as_echo_n "checking for alloca... " >&6; } +if test "${ac_cv_func_alloca_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_alloca_works=yes +else + ac_cv_func_alloca_works=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 +$as_echo "$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext + +$as_echo "#define C_ALLOCA 1" >>confdefs.h + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 +$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } +if test "${ac_cv_os_cray+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined CRAY && ! defined CRAY2 +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then : + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 +$as_echo "$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 +$as_echo_n "checking stack direction for C alloca... " >&6; } +if test "${ac_cv_c_stack_direction+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_c_stack_direction=0 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} + +int +main () +{ + return find_stack_direction () < 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_stack_direction=1 +else + ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 +$as_echo "$ac_cv_c_stack_direction" >&6; } +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if test "${ac_cv_c_const+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for properly working floating point implementation" >&5 +$as_echo_n "checking for properly working floating point implementation... " >&6; } +if test "x$build" = "x$host"; then + if eval "$CC $CFLAGS -o test_float ${srcdir}/test_float.c"; then + if ./test_float > /dev/null; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: We strongly recommend you manually examine the test_float results" >&5 +$as_echo "$as_me: WARNING: We strongly recommend you manually examine the test_float results" >&2;} + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failure compiling test_float" >&5 +$as_echo "failure compiling test_float" >&6; } + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: skipped test (cross-compiling)" >&5 +$as_echo "skipped test (cross-compiling)" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: We are cross-compiling, and thus cannot run the floating point test now. +We strongly recommend running test_float on the target platform." >&5 +$as_echo "$as_me: WARNING: We are cross-compiling, and thus cannot run the floating point test now. +We strongly recommend running test_float on the target platform." >&2;} +fi + + +if eval "test x$GCC = xyes"; then + CFLAGS="$CFLAGS -Wall -Wcast-align -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith -Wreturn-type -D_GNU_SOURCE" + fi + +for ac_header in sys/termios.h sys/select.h sys/time.h sys/modem.h sys/ipc.h sys/shm.h sys/stat.h sys/socket.h sys/ioctl.h sys/un.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in arpa/inet.h netinet/in_systm.h netinet/in.h netinet/tcp.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in netinet/ip.h +do : + ac_fn_c_check_header_compile "$LINENO" "netinet/ip.h" "ac_cv_header_netinet_ip_h" "#if HAVE_NETINET_IN_SYSTM_H && HAVE_NETINET_IN_H +#include netinet/ip.h +#endif + +" +if test "x$ac_cv_header_netinet_ip_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NETINET_IP_H 1 +_ACEOF + +fi + +done + +for ac_header in termios.h strings.h getopt.h netdb.h syslog.h pwd.h grp.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_func in round +do : + ac_fn_c_check_func "$LINENO" "round" "ac_cv_func_round" +if test "x$ac_cv_func_round" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ROUND 1 +_ACEOF + roundf +fi +done + +for ac_func in strlcpy +do : + ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" +if test "x$ac_cv_func_strlcpy" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRLCPY 1 +_ACEOF + +fi +done + +for ac_func in strlcat +do : + ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat" +if test "x$ac_cv_func_strlcat" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRLCAT 1 +_ACEOF + +fi +done + +for ac_func in strtonum +do : + ac_fn_c_check_func "$LINENO" "strtonum" "ac_cv_func_strtonum" +if test "x$ac_cv_func_strtonum" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRTONUM 1 +_ACEOF + +fi +done + +for ac_func in setlocale +do : + ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" +if test "x$ac_cv_func_setlocale" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SETLOCALE 1 +_ACEOF + +fi +done + +for ac_func in vsnprintf +do : + ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" +if test "x$ac_cv_func_vsnprintf" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VSNPRINTF 1 +_ACEOF + +fi +done + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if test "${ac_cv_header_time+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if test "${ac_cv_struct_tm+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_struct_tm=time.h +else + ac_cv_struct_tm=sys/time.h +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +$as_echo "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include +#include <$ac_cv_struct_tm> + +" +if test "x$ac_cv_member_struct_tm_tm_zone" = x""yes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_TM_TM_ZONE 1 +_ACEOF + + +fi + +if test "$ac_cv_member_struct_tm_tm_zone" = yes; then + +$as_echo "#define HAVE_TM_ZONE 1" >>confdefs.h + +else + ac_fn_c_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include +" +if test "x$ac_cv_have_decl_tzname" = x""yes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TZNAME $ac_have_decl +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5 +$as_echo_n "checking for tzname... " >&6; } +if test "${ac_cv_var_tzname+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#if !HAVE_DECL_TZNAME +extern char *tzname[]; +#endif + +int +main () +{ +return tzname[0][0]; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_var_tzname=yes +else + ac_cv_var_tzname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5 +$as_echo "$ac_cv_var_tzname" >&6; } + if test $ac_cv_var_tzname = yes; then + +$as_echo "#define HAVE_TZNAME 1" >>confdefs.h + + fi +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for timezone variable" >&5 +$as_echo_n "checking for timezone variable... " >&6; } +if test "${ac_cv_var_timezone+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + + timezone = 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_var_timezone=yes +else + ac_cv_var_timezone=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_timezone" >&5 +$as_echo "$ac_cv_var_timezone" >&6; } +if test $ac_cv_var_timezone = yes; then + +$as_echo "#define HAVE_TIMEZONE /**/" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tm_gmtoff in struct tm" >&5 +$as_echo_n "checking for tm_gmtoff in struct tm... " >&6; } +if test "${ac_cv_struct_tm_gmtoff+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + + struct tm tm; + tm.tm_gmtoff = 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_struct_tm_gmtoff=yes +else + ac_cv_struct_tm_gmtoff=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm_gmtoff" >&5 +$as_echo "$ac_cv_struct_tm_gmtoff" >&6; } + if test $ac_cv_struct_tm_gmtoff = yes; then + +$as_echo "#define HAVE_TM_GMTOFF /**/" >>confdefs.h + + else + as_fn_error $? "unable to find a way to determine timezone" "$LINENO" 5 + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for daylight external" >&5 +$as_echo_n "checking for daylight external... " >&6; } +if test "${mb_cv_var_daylight+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +return (int)daylight; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + mb_cv_var_daylight=yes +else + mb_cv_var_daylight=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mb_cv_var_daylight" >&5 +$as_echo "$mb_cv_var_daylight" >&6; } +if test $mb_cv_var_daylight = yes; then + +$as_echo "#define HAVE_DAYLIGHT 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_gethostbyname=yes +else + ac_cv_lib_nsl_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : + LIBNSL="-lnsl" +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 +$as_echo_n "checking for socket in -lsocket... " >&6; } +if test "${ac_cv_lib_socket_socket+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_socket=yes +else + ac_cv_lib_socket_socket=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 +$as_echo "$ac_cv_lib_socket_socket" >&6; } +if test "x$ac_cv_lib_socket_socket" = x""yes; then : + LIBSOCKET="-lsocket" +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rint in -lm" >&5 +$as_echo_n "checking for rint in -lm... " >&6; } +if test "${ac_cv_lib_m_rint+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char rint (); +int +main () +{ +return rint (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_m_rint=yes +else + ac_cv_lib_m_rint=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_rint" >&5 +$as_echo "$ac_cv_lib_m_rint" >&6; } +if test "x$ac_cv_lib_m_rint" = x""yes; then : + LIBM="-lm" +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for open in -lc" >&5 +$as_echo_n "checking for open in -lc... " >&6; } +if test "${ac_cv_lib_c_open+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char open (); +int +main () +{ +return open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_open=yes +else + ac_cv_lib_c_open=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_open" >&5 +$as_echo "$ac_cv_lib_c_open" >&6; } +if test "x$ac_cv_lib_c_open" = x""yes; then : + LIBC="-lc" +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setcancelstate in -lpthread" >&5 +$as_echo_n "checking for pthread_setcancelstate in -lpthread... " >&6; } +if test "${ac_cv_lib_pthread_pthread_setcancelstate+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_setcancelstate (); +int +main () +{ +return pthread_setcancelstate (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthread_pthread_setcancelstate=yes +else + ac_cv_lib_pthread_pthread_setcancelstate=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_setcancelstate" >&5 +$as_echo "$ac_cv_lib_pthread_pthread_setcancelstate" >&6; } +if test "x$ac_cv_lib_pthread_pthread_setcancelstate" = x""yes; then : + LIBPTHREAD="-lpthread" + +$as_echo "#define HAVE_LIBPTHREAD /**/" >>confdefs.h + +fi + + + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBUSB" >&5 +$as_echo_n "checking for LIBUSB... " >&6; } + +if test -n "$LIBUSB_CFLAGS"; then + pkg_cv_LIBUSB_CFLAGS="$LIBUSB_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0 >= 1.0.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libusb-1.0 >= 1.0.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUSB_CFLAGS=`$PKG_CONFIG --cflags "libusb-1.0 >= 1.0.0" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBUSB_LIBS"; then + pkg_cv_LIBUSB_LIBS="$LIBUSB_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0 >= 1.0.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libusb-1.0 >= 1.0.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUSB_LIBS=`$PKG_CONFIG --libs "libusb-1.0 >= 1.0.0" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBUSB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libusb-1.0 >= 1.0.0" 2>&1` + else + LIBUSB_PKG_ERRORS=`$PKG_CONFIG --print-errors "libusb-1.0 >= 1.0.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBUSB_PKG_ERRORS" >&5 + + ac_libusb=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ac_libusb=no +else + LIBUSB_CFLAGS=$pkg_cv_LIBUSB_CFLAGS + LIBUSB_LIBS=$pkg_cv_LIBUSB_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + ac_libusb=yes +fi + + +if test x"$ac_libusb" = x"yes" ; then + +$as_echo "#define HAVE_LIBUSB 1" >>confdefs.h + +fi + + + + + +for ac_header in ncurses.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "ncurses.h" "ac_cv_header_ncurses_h" "$ac_includes_default" +if test "x$ac_cv_header_ncurses_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NCURSES_H 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5 +$as_echo_n "checking for initscr in -lncurses... " >&6; } +if test "${ac_cv_lib_ncurses_initscr+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char initscr (); +int +main () +{ +return initscr (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncurses_initscr=yes +else + ac_cv_lib_ncurses_initscr=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5 +$as_echo "$ac_cv_lib_ncurses_initscr" >&6; } +if test "x$ac_cv_lib_ncurses_initscr" = x""yes; then : + NCURSES_LIBS="-lncurses" +fi + + +if test x"$NCURSES_LIBS" = x"" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Not including curses support" >&5 +$as_echo "$as_me: WARNING: Not including curses support" >&2;} + if false; then + HAVE_NCURSES_TRUE= + HAVE_NCURSES_FALSE='#' +else + HAVE_NCURSES_TRUE='#' + HAVE_NCURSES_FALSE= +fi + + ac_ncurses="no" +else + if true; then + HAVE_NCURSES_TRUE= + HAVE_NCURSES_FALSE='#' +else + HAVE_NCURSES_TRUE='#' + HAVE_NCURSES_FALSE= +fi + + ac_ncurses="yes" +fi + +# Check whether --enable-nmea was given. +if test "${enable_nmea+set}" = set; then : + enableval=$enable_nmea; ac_nmea=$enableval +else + ac_nmea=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NMEA support" >&5 +$as_echo_n "checking for NMEA support... " >&6; } +if test x"$ac_nmea" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define NMEA_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-oncore was given. +if test "${enable_oncore+set}" = set; then : + enableval=$enable_oncore; ac_oncore=$enableval +else + ac_oncore=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Motorola OnCore support" >&5 +$as_echo_n "checking for Motorola OnCore support... " >&6; } +if test x"$ac_oncore" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define ONCORE_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-sirf was given. +if test "${enable_sirf+set}" = set; then : + enableval=$enable_sirf; ac_sirf=$enableval +else + ac_sirf=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SiRF support" >&5 +$as_echo_n "checking for SiRF support... " >&6; } +if test x"$ac_sirf" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define SIRF_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-superstar2 was given. +if test "${enable_superstar2+set}" = set; then : + enableval=$enable_superstar2; ac_superstar2=$enableval +else + ac_superstar2=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SuperStarII support" >&5 +$as_echo_n "checking for SuperStarII support... " >&6; } +if test x"$ac_superstar2" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define SUPERSTAR2_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-tsip was given. +if test "${enable_tsip+set}" = set; then : + enableval=$enable_tsip; ac_tsip=$enableval +else + ac_tsip=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Trimble TSIP support" >&5 +$as_echo_n "checking for Trimble TSIP support... " >&6; } +if test x"$ac_tsip" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define TSIP_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-fv18 was given. +if test "${enable_fv18+set}" = set; then : + enableval=$enable_fv18; ac_fv18=$enableval +else + ac_fv18=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FV-18 support" >&5 +$as_echo_n "checking for FV-18 support... " >&6; } +if test x"$ac_fv18" = "xyes"; then + ac_nmea=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define FV18_ENABLE 1" >>confdefs.h + + +$as_echo "#define NMEA_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-tripmate was given. +if test "${enable_tripmate+set}" = set; then : + enableval=$enable_tripmate; ac_tripmate=$enableval +else + ac_tripmate=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tripmate support" >&5 +$as_echo_n "checking for Tripmate support... " >&6; } +if test x"$ac_tripmate" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define TRIPMATE_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-earthmate was given. +if test "${enable_earthmate+set}" = set; then : + enableval=$enable_earthmate; ac_earthmate=$enableval +else + ac_earthmate=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EarthMate support" >&5 +$as_echo_n "checking for EarthMate support... " >&6; } +if test x"$ac_earthmate" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define EARTHMATE_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-itrax was given. +if test "${enable_itrax+set}" = set; then : + enableval=$enable_itrax; ac_itrax=$enableval +else + ac_itrax=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for iTrax support" >&5 +$as_echo_n "checking for iTrax support... " >&6; } +if test x"$ac_itrax" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define ITRAX_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-ashtech was given. +if test "${enable_ashtech+set}" = set; then : + enableval=$enable_ashtech; ac_ashtech=$enableval +else + ac_ashtech=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Ashtech support" >&5 +$as_echo_n "checking for Ashtech support... " >&6; } +if test x"$ac_ashtech" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define ASHTECH_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-navcom was given. +if test "${enable_navcom+set}" = set; then : + enableval=$enable_navcom; ac_navcom=$enableval +else + ac_navcom=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Navcom support" >&5 +$as_echo_n "checking for Navcom support... " >&6; } +if test x"$ac_navcom" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define NAVCOM_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-garmin was given. +if test "${enable_garmin+set}" = set; then : + enableval=$enable_garmin; ac_garmin=$enableval +else + ac_garmin=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Garmin support" >&5 +$as_echo_n "checking for Garmin support... " >&6; } +if test x"$ac_garmin" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define GARMIN_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-garmintxt was given. +if test "${enable_garmintxt+set}" = set; then : + enableval=$enable_garmintxt; ac_garmintxt=$enableval +else + ac_garmintxt=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Garmin Simple Text support" >&5 +$as_echo_n "checking for Garmin Simple Text support... " >&6; } +if test x"$ac_garmintxt" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define GARMINTXT_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-tnt was given. +if test "${enable_tnt+set}" = set; then : + enableval=$enable_tnt; ac_tnt=$enableval +else + ac_tnt=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for True North support" >&5 +$as_echo_n "checking for True North support... " >&6; } +if test x"$ac_tnt" = "xyes"; then + ac_nmea=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define TNT_ENABLE 1" >>confdefs.h + + +$as_echo "#define NMEA_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-oceanserver was given. +if test "${enable_oceanserver+set}" = set; then : + enableval=$enable_oceanserver; ac_oceanserver=$enableval +else + ac_oceanserver=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OceanServer support" >&5 +$as_echo_n "checking for OceanServer support... " >&6; } +if test x"$ac_oceanserver" = "xyes"; then + ac_nmea=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define OCEANSERVER_ENABLE 1" >>confdefs.h + + +$as_echo "#define NMEA_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-ubx was given. +if test "${enable_ubx+set}" = set; then : + enableval=$enable_ubx; ac_ubx=$enableval +else + ac_ubx=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for UBX support" >&5 +$as_echo_n "checking for UBX support... " >&6; } +if test x"$ac_ubx" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define UBX_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-evermore was given. +if test "${enable_evermore+set}" = set; then : + enableval=$enable_evermore; ac_evermore=$enableval +else + ac_evermore=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EverMore support" >&5 +$as_echo_n "checking for EverMore support... " >&6; } +if test x"$ac_evermore" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define EVERMORE_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-mtk3301 was given. +if test "${enable_mtk3301+set}" = set; then : + enableval=$enable_mtk3301; ac_mtk3301=$enableval +else + ac_mtk3301=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MTK-3301 support" >&5 +$as_echo_n "checking for MTK-3301 support... " >&6; } +if test x"$ac_mtk3301" = "xyes"; then + ac_nmea=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define MTK3301_ENABLE 1" >>confdefs.h + + +$as_echo "#define NMEA_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-gpsclock was given. +if test "${enable_gpsclock+set}" = set; then : + enableval=$enable_gpsclock; ac_gpsclock=$enableval +else + ac_gpsclock=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GPSClock support" >&5 +$as_echo_n "checking for GPSClock support... " >&6; } +if test x"$ac_gpsclock" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define GPSCLOCK_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-rtcm104v2 was given. +if test "${enable_rtcm104v2+set}" = set; then : + enableval=$enable_rtcm104v2; ac_rtcm104v2=$enableval +else + ac_rtcm104v2=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rtcm104v2 support" >&5 +$as_echo_n "checking for rtcm104v2 support... " >&6; } +if test x"$ac_earthmate" = "xno" -a x"$ac_evermore" = "xno" -a x"$ac_garmin" = "xno" -a x"$ac_itrax" = "xno" -a x"$ac_sirf" = "xno" -a x"$ac_superstar2" = "xno" -a x"$ac_tsip" = "xno" -a x"$ac_navcom" = "xno"; then + ac_rtcm104v2=no +fi +if test x"$ac_rtcm104v2" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define RTCM104V2_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "$ac_rtcm104v2" = "yes"; then + HAVE_RTCM104V2_TRUE= + HAVE_RTCM104V2_FALSE='#' +else + HAVE_RTCM104V2_TRUE='#' + HAVE_RTCM104V2_FALSE= +fi + + +# Check whether --enable-rtcm104v3 was given. +if test "${enable_rtcm104v3+set}" = set; then : + enableval=$enable_rtcm104v3; ac_rtcm104v3=$enableval +else + ac_rtcm104v3=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rtcm104v3 support" >&5 +$as_echo_n "checking for rtcm104v3 support... " >&6; } +if test x"$ac_earthmate" = "xno" -a x"$ac_evermore" = "xno" -a x"$ac_garmin" = "xno" -a x"$ac_itrax" = "xno" -a x"$ac_sirf" = "xno" -a x"$ac_tsip" = "xno" -a x"$ac_navcom" = "xno"; then + ac_rtcm104v3=no +fi +if test x"$ac_rtcm104v3" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define RTCM104V3_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "$ac_rtcm104v3" = "yes"; then + HAVE_RTCM104V3_TRUE= + HAVE_RTCM104V3_FALSE='#' +else + HAVE_RTCM104V3_TRUE='#' + HAVE_RTCM104V3_FALSE= +fi + + +# Check whether --enable-ntrip was given. +if test "${enable_ntrip+set}" = set; then : + enableval=$enable_ntrip; ac_ntrip=$enableval +else + ac_ntrip=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NTRIP support" >&5 +$as_echo_n "checking for NTRIP support... " >&6; } +if test x"$ac_ntrip" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define NTRIP_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "$ac_ntrip" = "yes"; then + HAVE_NTRIP_TRUE= + HAVE_NTRIP_FALSE='#' +else + HAVE_NTRIP_TRUE='#' + HAVE_NTRIP_FALSE= +fi + + +# Check whether --enable-aivdm was given. +if test "${enable_aivdm+set}" = set; then : + enableval=$enable_aivdm; ac_aivdm=$enableval +else + ac_aivdm=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AIVDM support" >&5 +$as_echo_n "checking for AIVDM support... " >&6; } +if test x"$ac_aivdm" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define AIVDM_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + if test "$ac_aivdm" = "yes"; then + HAVE_AIVDM_TRUE= + HAVE_AIVDM_FALSE='#' +else + HAVE_AIVDM_TRUE='#' + HAVE_AIVDM_FALSE= +fi + + +# Check whether --enable-timing was given. +if test "${enable_timing+set}" = set; then : + enableval=$enable_timing; ac_timing=$enableval +else + ac_timing=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for latency timing support" >&5 +$as_echo_n "checking for latency timing support... " >&6; } +if test x"$ac_timing" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define TIMING_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-clientdebug was given. +if test "${enable_clientdebug+set}" = set; then : + enableval=$enable_clientdebug; ac_clientdebug=$enableval +else + ac_clientdebug=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for client debugging support" >&5 +$as_echo_n "checking for client debugging support... " >&6; } +if test x"$ac_clientdebug" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define CLIENTDEBUG_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test x"$ac_clientdebug" = x"yes"; then + CLIENTDEBUG_ENABLE_TRUE= + CLIENTDEBUG_ENABLE_FALSE='#' +else + CLIENTDEBUG_ENABLE_TRUE='#' + CLIENTDEBUG_ENABLE_FALSE= +fi + + +# Check whether --enable-oldstyle was given. +if test "${enable_oldstyle+set}" = set; then : + enableval=$enable_oldstyle; ac_oldstyle=$enableval +else + ac_oldstyle=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for oldstyle support" >&5 +$as_echo_n "checking for oldstyle support... " >&6; } +if test x"$ac_oldstyle" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define OLDSTYLE_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-profiling was given. +if test "${enable_profiling+set}" = set; then : + enableval=$enable_profiling; ac_profiling=$enableval +else + ac_profiling=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for profiling support" >&5 +$as_echo_n "checking for profiling support... " >&6; } +if test x"$ac_profiling" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define PROFILING 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-ntpshm was given. +if test "${enable_ntpshm+set}" = set; then : + enableval=$enable_ntpshm; ac_ntpshm=$enableval +else + ac_ntpshm=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NTP time hinting support" >&5 +$as_echo_n "checking for NTP time hinting support... " >&6; } +if test x"$ac_ntpshm" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define NTPSHM_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-pps was given. +if test "${enable_pps+set}" = set; then : + enableval=$enable_pps; ac_pps=$enableval +else + ac_pps=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PPS time syncing support" >&5 +$as_echo_n "checking for PPS time syncing support... " >&6; } +if test x"$ac_pps" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define PPS_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-pps-on-cts was given. +if test "${enable_pps_on_cts+set}" = set; then : + enableval=$enable_pps_on_cts; ac_ppsoncts=$enableval +else + ac_ppsoncts=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PPS pulse on CTS rather than DCD" >&5 +$as_echo_n "checking for PPS pulse on CTS rather than DCD... " >&6; } +if test x"$ac_ppsoncts" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define PPS_ON_CTS 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-gpsd-user was given. +if test "${enable_gpsd_user+set}" = set; then : + enableval=$enable_gpsd_user; ac_user=$enableval +else + ac_user=nobody +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking privilege revocation user" >&5 +$as_echo_n "checking privilege revocation user... " >&6; } +if test x"$ac_user" != "xnobody"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_user" >&5 +$as_echo "$ac_user" >&6; } + +cat >>confdefs.h <<_ACEOF +#define GPSD_USER "$ac_user" +_ACEOF + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: nobody" >&5 +$as_echo "nobody" >&6; } +fi + +# Check whether --enable-gpsd-group was given. +if test "${enable_gpsd_group+set}" = set; then : + enableval=$enable_gpsd_group; ac_group=$enableval +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking privilege revokation group" >&5 +$as_echo_n "checking privilege revokation group... " >&6; } +if test x"$ac_user" != "xnobody"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_group" >&5 +$as_echo "$ac_group" >&6; } + +cat >>confdefs.h <<_ACEOF +#define GPSD_GROUP "$ac_group" +_ACEOF + +fi + +# Check whether --enable-fixed-port-speed was given. +if test "${enable_fixed_port_speed+set}" = set; then : + enableval=$enable_fixed_port_speed; ac_baud=$enableval +else + ac_baud=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fixed port speed" >&5 +$as_echo_n "checking for fixed port speed... " >&6; } +if test x"$ac_baud" != "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_baud" >&5 +$as_echo "$ac_baud" >&6; } + +cat >>confdefs.h <<_ACEOF +#define FIXED_PORT_SPEED $ac_baud +_ACEOF + + FIXED_PORT_SPEED="-DSPEEDFLAGS=$ac_baud" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-bluetooth was given. +if test "${enable_bluetooth+set}" = set; then : + enableval=$enable_bluetooth; ac_bluetooth=$enableval +else + ac_bluetooth=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BlueZ support" >&5 +$as_echo_n "checking for BlueZ support... " >&6; } +if test x"$ac_bluetooth" = x"yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_BLUEZ 1" >>confdefs.h + + # Older versions of autotools barf and die on this. + #PKG_CHECK_MODULES(BLUEZ, bluez ) + BLUEZ_CFLAGS=`pkg-config --cflags bluez` + BLUEZ_LIBS=`pkg-config --libs bluez` + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +# Check whether --enable-dbus was given. +if test "${enable_dbus+set}" = set; then : + enableval=$enable_dbus; ac_dbus=$enableval +else + ac_dbus=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBUS support" >&5 +$as_echo_n "checking for DBUS support... " >&6; } +if test x"$ac_dbus" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define DBUS_ENABLE 1" >>confdefs.h + + # Older versions of autotools barf and die on this. + #PKG_CHECK_MODULES(DBUS, dbus-1 >= 0.23.4 ) + DBUS_CFLAGS=`pkg-config --cflags dbus-glib-1` + DBUS_LIBS=`pkg-config --libs dbus-1` + + + #PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1 >= 0.22 ) + DBUS_GLIB_LIBS=`pkg-config --libs dbus-glib-1` + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-max-clients was given. +if test "${enable_max_clients+set}" = set; then : + enableval=$enable_max_clients; ac_maxclients=$enableval +else + ac_maxclients=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for limited max clients" >&5 +$as_echo_n "checking for limited max clients... " >&6; } +if test x"$ac_maxclients" != "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_maxclients" >&5 +$as_echo "$ac_maxclients" >&6; } + +cat >>confdefs.h <<_ACEOF +#define LIMITED_MAX_CLIENTS $ac_maxclients +_ACEOF + + LIMITED_MAX_CLIENTS="-DLIMITED_MAX_CLIENTS=$ac_maxclients" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-max-devices was given. +if test "${enable_max_devices+set}" = set; then : + enableval=$enable_max_devices; ac_maxdevices=$enableval +else + ac_maxdevices=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for max devices" >&5 +$as_echo_n "checking for max devices... " >&6; } +if test x"$ac_maxdevices" != "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_maxdevices" >&5 +$as_echo "$ac_maxdevices" >&6; } + +cat >>confdefs.h <<_ACEOF +#define LIMITED_MAX_DEVICES $ac_maxdevices +_ACEOF + + LIMITED_MAX_DEVICES="-DLIMITED_MAX_DEVICES=$ac_maxdevices" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-reconfigure was given. +if test "${enable_reconfigure+set}" = set; then : + enableval=$enable_reconfigure; ac_reconfigure=$enableval +else + ac_reconfigure=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if device reconfiguration is allowed" >&5 +$as_echo_n "checking if device reconfiguration is allowed... " >&6; } +if test x"$ac_reconfigure" != "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_reconfigure" >&5 +$as_echo "$ac_reconfigure" >&6; } + +$as_echo "#define ALLOW_RECONFIGURE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-controlsend was given. +if test "${enable_controlsend+set}" = set; then : + enableval=$enable_controlsend; ac_controlsend=$enableval +else + ac_controlsend=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if control sending is allowed" >&5 +$as_echo_n "checking if control sending is allowed... " >&6; } +if test x"$ac_controlsend" != "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_controlsend" >&5 +$as_echo "$ac_controlsend" >&6; } + +$as_echo "#define ALLOW_CONTROLSEND 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-raw was given. +if test "${enable_raw+set}" = set; then : + enableval=$enable_raw; ac_raw=$enableval +else + ac_raw=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Raw Measurement support" >&5 +$as_echo_n "checking for Raw Measurement support... " >&6; } +if test x"$ac_raw" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define RAW_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test x"$ac_dbus" = x"yes"; then + HAVE_DBUS_TRUE= + HAVE_DBUS_FALSE='#' +else + HAVE_DBUS_TRUE='#' + HAVE_DBUS_FALSE= +fi + + if test x"$ac_bluetooth" = x"yes"; then + HAVE_BLUEZ_TRUE= + HAVE_BLUEZ_FALSE='#' +else + HAVE_BLUEZ_TRUE='#' + HAVE_BLUEZ_FALSE= +fi + + +# Check whether --enable-squelch was given. +if test "${enable_squelch+set}" = set; then : + enableval=$enable_squelch; ac_squelch=$enableval +else + ac_squelch=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for disabled logging" >&5 +$as_echo_n "checking for disabled logging... " >&6; } +if test x"$ac_squelch" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define SQUELCH_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ISCXX="yes" +else + ISCXX="no" +fi + +# Check whether --enable-libgpsmm was given. +if test "${enable_libgpsmm+set}" = set; then : + enableval=$enable_libgpsmm; ac_libgpsmm=$enableval +else + ac_libgpsmm=$ISCXX +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ support" >&5 +$as_echo_n "checking for C++ support... " >&6; } +if test x"$ac_libgpsmm" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define LIBGPSMM_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test x"$ac_libgpsmm" = x"yes"; then + LIBGPSMM_ENABLE_TRUE= + LIBGPSMM_ENABLE_FALSE='#' +else + LIBGPSMM_ENABLE_TRUE='#' + LIBGPSMM_ENABLE_FALSE= +fi + + + + +# Check whether --enable-libQgpsmm was given. +if test "${enable_libQgpsmm+set}" = set; then : + enableval=$enable_libQgpsmm; ac_libQgpsmm=$enableval +else + ac_libQgpsmm=$ISCXX +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for QT support" >&5 +$as_echo_n "checking for QT support... " >&6; } +if test x"$ac_libQgpsmm" = "xyes"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for QtNetwork" >&5 +$as_echo_n "checking for QtNetwork... " >&6; } + +if test -n "$QtNetwork_CFLAGS"; then + pkg_cv_QtNetwork_CFLAGS="$QtNetwork_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"QtNetwork >= 4.4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "QtNetwork >= 4.4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_QtNetwork_CFLAGS=`$PKG_CONFIG --cflags "QtNetwork >= 4.4" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$QtNetwork_LIBS"; then + pkg_cv_QtNetwork_LIBS="$QtNetwork_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"QtNetwork >= 4.4\""; } >&5 + ($PKG_CONFIG --exists --print-errors "QtNetwork >= 4.4") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_QtNetwork_LIBS=`$PKG_CONFIG --libs "QtNetwork >= 4.4" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + QtNetwork_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "QtNetwork >= 4.4" 2>&1` + else + QtNetwork_PKG_ERRORS=`$PKG_CONFIG --print-errors "QtNetwork >= 4.4" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$QtNetwork_PKG_ERRORS" >&5 + + ac_qt="no" +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ac_qt="no" +else + QtNetwork_CFLAGS=$pkg_cv_QtNetwork_CFLAGS + QtNetwork_LIBS=$pkg_cv_QtNetwork_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + ac_qt="yes" +fi + if test x"$ac_qt" != "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: QtNetwork library not found. Not including QT support" >&5 +$as_echo "$as_me: WARNING: QtNetwork library not found. Not including QT support" >&2;} + ac_libQgpsmm="no" + if false; then + LIB_Q_GPSMM_ENABLE_TRUE= + LIB_Q_GPSMM_ENABLE_FALSE='#' +else + LIB_Q_GPSMM_ENABLE_TRUE='#' + LIB_Q_GPSMM_ENABLE_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + else + for ac_prog in qmake-qt4 qmake +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_QMAKE+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$QMAKE"; then + ac_cv_prog_QMAKE="$QMAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_QMAKE="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +QMAKE=$ac_cv_prog_QMAKE +if test -n "$QMAKE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $QMAKE" >&5 +$as_echo "$QMAKE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$QMAKE" && break +done +test -n "$QMAKE" || QMAKE="no" + + if test x"$QMAKE" != "xno"; then + if true; then + LIB_Q_GPSMM_ENABLE_TRUE= + LIB_Q_GPSMM_ENABLE_FALSE='#' +else + LIB_Q_GPSMM_ENABLE_TRUE='#' + LIB_Q_GPSMM_ENABLE_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: qmake not found. Not including QT support" >&5 +$as_echo "$as_me: WARNING: qmake not found. Not including QT support" >&2;} + ac_libQgpsmm="no" + if false; then + LIB_Q_GPSMM_ENABLE_TRUE= + LIB_Q_GPSMM_ENABLE_FALSE='#' +else + LIB_Q_GPSMM_ENABLE_TRUE='#' + LIB_Q_GPSMM_ENABLE_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + if false; then + LIB_Q_GPSMM_ENABLE_TRUE= + LIB_Q_GPSMM_ENABLE_FALSE='#' +else + LIB_Q_GPSMM_ENABLE_TRUE='#' + LIB_Q_GPSMM_ENABLE_FALSE= +fi + +fi + + + +# Check whether --enable-ipv6 was given. +if test "${enable_ipv6+set}" = set; then : + enableval=$enable_ipv6; ac_ipv6=$enableval +else + ac_ipv6=$ISCXX +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for IPv6 support" >&5 +$as_echo_n "checking for IPv6 support... " >&6; } +if test x"$ac_ipv6" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define IPV6_ENABLE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test x"$ac_ipv6" = x"yes"; then + IPV6_ENABLE_TRUE= + IPV6_ENABLE_FALSE='#' +else + IPV6_ENABLE_TRUE='#' + IPV6_ENABLE_FALSE= +fi + + +# Extract the first word of "xsltproc", so it can be a program name with args. +set dummy xsltproc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_WITH_XSLTPROC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$WITH_XSLTPROC"; then + ac_cv_prog_WITH_XSLTPROC="$WITH_XSLTPROC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_WITH_XSLTPROC="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_WITH_XSLTPROC" && ac_cv_prog_WITH_XSLTPROC="no" +fi +fi +WITH_XSLTPROC=$ac_cv_prog_WITH_XSLTPROC +if test -n "$WITH_XSLTPROC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WITH_XSLTPROC" >&5 +$as_echo "$WITH_XSLTPROC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +XMLPROC= +MANTARGET= +XMLPROCFLAGS= +if test "x$WITH_XSLTPROC" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xsltproc knows about docbook xsl" >&5 +$as_echo_n "checking whether xsltproc knows about docbook xsl... " >&6; } + DOCBOOK_MAN_URI='http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' + DOCBOOK_HTML_URI='http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl' + cat >conftest.xml <<_EOF + + + foo + 1 + 9 Aug 2004 + + + foo + check man page generation from docbook source + + +_EOF + if xsltproc --nonet --noout "$DOCBOOK_MAN_URI" conftest.xml >/dev/null 2>&1; then + XMLPROC=xsltproc + MANTARGET="$DOCBOOK_MAN_URI" + HTMLTARGET="$DOCBOOK_HTML_URI" + XMLPROCFLAGS="--nonet" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + rm -f conftest.xml foo.1 +fi +if test x"$XMLPROC" = x; then + # Extract the first word of "xmlto", so it can be a program name with args. +set dummy xmlto; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_WITH_XMLTO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$WITH_XMLTO"; then + ac_cv_prog_WITH_XMLTO="$WITH_XMLTO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_WITH_XMLTO="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_WITH_XMLTO" && ac_cv_prog_WITH_XMLTO="no" +fi +fi +WITH_XMLTO=$ac_cv_prog_WITH_XMLTO +if test -n "$WITH_XMLTO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WITH_XMLTO" >&5 +$as_echo "$WITH_XMLTO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$WITH_XMLTO" = "xyes"; then + XMLPROC=xmlto + MANTARGET=man + HTMLTARGET=xhtml-nochunks + XMLPROCFLAGS= + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Neither xsltproc nor xmlto works: I will not build man pages." >&5 +$as_echo "$as_me: WARNING: Neither xsltproc nor xmlto works: I will not build man pages." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: To build man pages, install xsltproc/xsltlib or xmlto and run autogen.sh again." >&5 +$as_echo "$as_me: WARNING: To build man pages, install xsltproc/xsltlib or xmlto and run autogen.sh again." >&2;} + fi +fi + if test x"$XMLPROC" != x; then + HAVE_XSLT_PROCESSOR_TRUE= + HAVE_XSLT_PROCESSOR_FALSE='#' +else + HAVE_XSLT_PROCESSOR_TRUE='#' + HAVE_XSLT_PROCESSOR_FALSE= +fi + + if test x"$XMLPROC" = x"xsltproc"; then + XMLTOSTDOUT_TRUE= + XMLTOSTDOUT_FALSE='#' +else + XMLTOSTDOUT_TRUE='#' + XMLTOSTDOUT_FALSE= +fi + + + + + + +if test -e /etc/gentoo-release; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: This is a Gentoo system." >&5 +$as_echo "$as_me: WARNING: This is a Gentoo system." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Adjust your PYTHONPATH to see library directories under /usr/local/lib" >&5 +$as_echo "$as_me: WARNING: Adjust your PYTHONPATH to see library directories under /usr/local/lib" >&2;} +fi + +echo "" +echo "==========================================" +echo "$PACKAGE $VERSION" +echo "------------------------------------------" +echo " Protocols" +echo " ---------" +echo "Ashtech : $ac_ashtech" +echo "Earthmate : $ac_earthmate" +echo "EverMore : $ac_evermore" +echo "FV-18 : $ac_fv18" +echo "Garmin : $ac_garmin" +echo "Garmin Simple Text : $ac_garmintxt" +echo "iTrax : $ac_itrax" +echo "NMEA : $ac_nmea" +echo "NTRIP : $ac_ntrip" +echo "Navcom : $ac_navcom" +echo "OnCore : $ac_oncore" +echo "RTCM104V2 : $ac_rtcm104v2" +echo "RTCM104V3 : $ac_rtcm104v3" +echo "SiRF : $ac_sirf" +echo "SuperStarII : $ac_superstar2" +echo "Trimble TSIP : $ac_tsip" +echo "Tripmate : $ac_tripmate" +echo "True North : $ac_tnt" +echo "OceanServer : $ac_oceanserver" +echo "UBX : $ac_ubx" +echo "GPSclock : $ac_gpsclock" +echo "AIVDM support : $ac_aivdm" +echo "Timing support : $ac_timing" +echo "Client debugging support: $ac_clientdebug" +echo "MTK-3301 : $ac_mtk3301" +echo " Daemon Features" +echo " ---------------" +echo "NTP SHM : $ac_ntpshm" +echo "NTP PPS : $ac_pps" +echo -n "PPS input on : " ; case $ac_ppsoncts in yes) echo "CTS" ;; no) echo "DCD" ;; *) echo "Not defined" ;; esac +echo "Fixed port speed : $ac_baud" +echo "Priv-drop user : $ac_user" +echo "Enable shared libraries : $enable_shared" +echo "Enable DBUS support : $ac_dbus" +echo "Enable BlueZ support : $ac_bluetooth" +echo "Enable IPv6 support : $ac_ipv6" +echo "Limited max clients : $ac_maxclients" +echo "Limited max devices : $ac_maxdevices" +echo "Allow device reconfig : $ac_reconfigure" +echo "Allow control send : $ac_controlsend" +echo "Squelch logging/hexdump : $ac_squelch" +echo "Raw Measurements : $ac_raw" +echo "libusb device discovery : $ac_libusb" +echo " Client Features" +echo " ---------------" +echo "Old protocol in libgps : $ac_oldstyle" +echo "Build ncurses programs : $ac_ncurses" +echo "Enable Python support : $ac_python" +echo "Enable C++ support : $ac_libgpsmm" +echo "Enable Qt support : $ac_libQgpsmm" +echo "------------------------------------------" +echo "" + +if test "xdummy" = "xdummy" -a \ + x"$ac_earthmate" = "xno" -a \ + x"$ac_evermore" = "xno" -a \ + x"$ac_fv18" = "xno" -a \ + x"$ac_garmin" = "xno" -a \ + x"$ac_garmintxt" = "xno" -a \ + x"$ac_itrax" = "xno" -a \ + x"$ac_navcom" = "xno" -a \ + x"$ac_nmea" = "xno" -a \ + x"$ac_ntrip" = "xno" -a \ + x"$ac_oncore" = "xno" -a \ + x"$ac_rtcm104v2" = "xno" -a \ + x"$ac_sirf" = "xno" -a \ + x"$ac_superstar2" = "xno" -a \ + x"$ac_tnt" = "xno" -a \ + x"$ac_oceanserver" = "xno" -a \ + x"$ac_tripmate" = "xno" -a \ + x"$ac_tsip" = "xno" -a \ + x"$ac_ubx" = "xno"; then + as_fn_error $? "Can't build gpsd with no protocols enabled" "$LINENO" 5 +fi +ac_config_files="$ac_config_files Makefile packaging/rpm/gpsd.spec libgps.pc libgpsd.pc jsongen.py maskaudit.py valgrind-audit" + +ac_config_commands="$ac_config_commands default" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_PYTHON_TRUE}" && test -z "${HAVE_PYTHON_FALSE}"; then + as_fn_error $? "conditional \"HAVE_PYTHON\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +if test -z "${HAVE_NCURSES_TRUE}" && test -z "${HAVE_NCURSES_FALSE}"; then + as_fn_error $? "conditional \"HAVE_NCURSES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_NCURSES_TRUE}" && test -z "${HAVE_NCURSES_FALSE}"; then + as_fn_error $? "conditional \"HAVE_NCURSES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_RTCM104V2_TRUE}" && test -z "${HAVE_RTCM104V2_FALSE}"; then + as_fn_error $? "conditional \"HAVE_RTCM104V2\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_RTCM104V3_TRUE}" && test -z "${HAVE_RTCM104V3_FALSE}"; then + as_fn_error $? "conditional \"HAVE_RTCM104V3\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_NTRIP_TRUE}" && test -z "${HAVE_NTRIP_FALSE}"; then + as_fn_error $? "conditional \"HAVE_NTRIP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_AIVDM_TRUE}" && test -z "${HAVE_AIVDM_FALSE}"; then + as_fn_error $? "conditional \"HAVE_AIVDM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CLIENTDEBUG_ENABLE_TRUE}" && test -z "${CLIENTDEBUG_ENABLE_FALSE}"; then + as_fn_error $? "conditional \"CLIENTDEBUG_ENABLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_DBUS_TRUE}" && test -z "${HAVE_DBUS_FALSE}"; then + as_fn_error $? "conditional \"HAVE_DBUS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_BLUEZ_TRUE}" && test -z "${HAVE_BLUEZ_FALSE}"; then + as_fn_error $? "conditional \"HAVE_BLUEZ\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBGPSMM_ENABLE_TRUE}" && test -z "${LIBGPSMM_ENABLE_FALSE}"; then + as_fn_error $? "conditional \"LIBGPSMM_ENABLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIB_Q_GPSMM_ENABLE_TRUE}" && test -z "${LIB_Q_GPSMM_ENABLE_FALSE}"; then + as_fn_error $? "conditional \"LIB_Q_GPSMM_ENABLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIB_Q_GPSMM_ENABLE_TRUE}" && test -z "${LIB_Q_GPSMM_ENABLE_FALSE}"; then + as_fn_error $? "conditional \"LIB_Q_GPSMM_ENABLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIB_Q_GPSMM_ENABLE_TRUE}" && test -z "${LIB_Q_GPSMM_ENABLE_FALSE}"; then + as_fn_error $? "conditional \"LIB_Q_GPSMM_ENABLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIB_Q_GPSMM_ENABLE_TRUE}" && test -z "${LIB_Q_GPSMM_ENABLE_FALSE}"; then + as_fn_error $? "conditional \"LIB_Q_GPSMM_ENABLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${IPV6_ENABLE_TRUE}" && test -z "${IPV6_ENABLE_FALSE}"; then + as_fn_error $? "conditional \"IPV6_ENABLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_XSLT_PROCESSOR_TRUE}" && test -z "${HAVE_XSLT_PROCESSOR_FALSE}"; then + as_fn_error $? "conditional \"HAVE_XSLT_PROCESSOR\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${XMLTOSTDOUT_TRUE}" && test -z "${XMLTOSTDOUT_FALSE}"; then + as_fn_error $? "conditional \"XMLTOSTDOUT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.67. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.67, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' +macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' +enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' +pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' +host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' +host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' +host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' +build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' +build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' +build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' +SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' +Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' +GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' +EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' +FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' +LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' +NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' +LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' +ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' +exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' +lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' +reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' +AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' +STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' +RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' +CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' +compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' +GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' +objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' +SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' +ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' +need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' +LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' +OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' +libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' +module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' +fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' +need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' +version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' +runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' +libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' +soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' +finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' +old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' +striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "X$compiler_lib_search_dirs" | $Xsed -e "$delay_single_quote_subst"`' +predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`' +predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`' +postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "X$LD_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "X$old_archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "X$compiler_CXX" | $Xsed -e "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "X$GCC_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "X$lt_prog_compiler_no_builtin_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "X$lt_prog_compiler_wl_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "X$lt_prog_compiler_pic_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "X$lt_prog_compiler_static_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "X$lt_cv_prog_compiler_c_o_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "X$archive_cmds_need_lc_CXX" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "X$enable_shared_with_static_runtimes_CXX" | $Xsed -e "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "X$export_dynamic_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "X$whole_archive_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "X$compiler_needs_object_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "X$old_archive_from_new_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "X$old_archive_from_expsyms_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "X$archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "X$archive_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "X$module_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "X$module_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "X$with_gnu_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "X$allow_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "X$no_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "X$hardcode_libdir_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld_CXX='`$ECHO "X$hardcode_libdir_flag_spec_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "X$hardcode_libdir_separator_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "X$hardcode_direct_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "X$hardcode_direct_absolute_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "X$hardcode_minus_L_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "X$hardcode_shlibpath_var_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "X$hardcode_automatic_CXX" | $Xsed -e "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "X$inherit_rpath_CXX" | $Xsed -e "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "X$link_all_deplibs_CXX" | $Xsed -e "$delay_single_quote_subst"`' +fix_srcfile_path_CXX='`$ECHO "X$fix_srcfile_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "X$always_export_symbols_CXX" | $Xsed -e "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "X$export_symbols_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "X$exclude_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "X$include_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "X$prelink_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "X$file_list_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "X$hardcode_action_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "X$compiler_lib_search_dirs_CXX" | $Xsed -e "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "X$predep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "X$postdep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "X$predeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "X$postdeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "X$compiler_lib_search_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# Quote evaled strings. +for var in SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +AR \ +AR_FLAGS \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +SHELL \ +ECHO \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_wl \ +lt_prog_compiler_pic \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +fix_srcfile_path \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_flag_spec_ld_CXX \ +hardcode_libdir_separator_CXX \ +fix_srcfile_path_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX; do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Fix-up fallback echo if it was mangled by the above quoting rules. +case \$lt_ECHO in +*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` + ;; +esac + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "gpsd_config.h") CONFIG_HEADERS="$CONFIG_HEADERS gpsd_config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "packaging/rpm/gpsd.spec") CONFIG_FILES="$CONFIG_FILES packaging/rpm/gpsd.spec" ;; + "libgps.pc") CONFIG_FILES="$CONFIG_FILES libgps.pc" ;; + "libgpsd.pc") CONFIG_FILES="$CONFIG_FILES libgpsd.pc" ;; + "jsongen.py") CONFIG_FILES="$CONFIG_FILES jsongen.py" ;; + "maskaudit.py") CONFIG_FILES="$CONFIG_FILES maskaudit.py" ;; + "valgrind-audit") CONFIG_FILES="$CONFIG_FILES valgrind-audit" ;; + "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that does not interpret backslashes. +ECHO=$lt_ECHO + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $* )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[^=]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$@"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1+=\$2" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1=\$$1\$2" +} + +_LT_EOF + ;; + esac + + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + "default":C) chmod +x jsongen.py maskaudit.py gpscat gpsfake gpsprof xgps valgrind-audit ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + +echo "Configure finished, type 'make' to build." + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..6a01ada --- /dev/null +++ b/configure.ac @@ -0,0 +1,1120 @@ +dnl This file is Copyright (c)2010 by the GPSD project +dnl BSD terms apply: see the file COPYING in the distribution root for details. + +AC_INIT +AM_INIT_AUTOMAKE(gpsd, 2.95) +dnl AC_PREFIX_PROGRAM(gcc) +AM_CONFIG_HEADER(gpsd_config.h) +AC_LANG([C]) + +# ACREQUIRE_BUGFIX +# ---------------- +# Due to a longstanding Autoconf bug (Autoconf 2.50 to at least 2.63), +# any macro that is AC_REQUIREd at any point must be AC_REQUIREd +# *before* it is directly expanded. The macros below were being +# directly expanded before being AC_REQUIREd, so we AC_REQUIRE them +# early to prevent out-of-order expansion problems. See the threads +# at: +# http://lists.gnu.org/archive/html/bug-autoconf/2008-12/msg00039.html +# http://lists.gnu.org/archive/html/autoconf-patches/2008-12/msg00058.html +# http://lists.gnu.org/archive/html/bug-autoconf/2009-01/msg00019.html +# http://lists.gnu.org/archive/html/bug-gnulib/2009-01/msg00247.html +AC_DEFUN_ONCE([ACREQUIRE_BUGFIX], +[ + AC_REQUIRE([AC_PROG_CPP]) + AC_REQUIRE([AC_PROG_EGREP]) + AC_REQUIRE([AC_PROG_CC]) +]) +ACREQUIRE_BUGFIX +# ACREQUIRE_BUGFIX done + +dnl AM_PATH_PYTHON provided with automake can be too old. Look +dnl for newer python first, and include 2.6 on the list. +m4_define([_AM_PYTHON_INTERPRETER_LIST], + [python2.6 python2.5 python2.4 python]) +AM_PATH_PYTHON([2.4]) +ac_python=yes +if test "x$PYTHON" = "x"; then + AC_PATH_PROG(PYTHON, python, none) +fi + +if test "x$PYTHON" = "xnone"; then +AC_MSG_WARN([*** Python interpreter not found, Python support disabled.]) + ac_python=no +fi + +if test "x$ac_python" = "xyes"; then + AC_MSG_CHECKING(Python version and location) + PYTHON_PREFIX=`$PYTHON -c "import sys; print(sys.prefix)"` + PYTHON_VERSION_MAJOR=[`$PYTHON -c "import sys; print('%d' % (sys.version_info[0]));"`] + PYTHON_VERSION_MINOR=[`$PYTHON -c "import sys; print('%d' % (sys.version_info[1]));"`] + PYTHON_VERSION="${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" + AC_MSG_RESULT([$PYTHON, $PYTHON_VERSION, $PYTHON_PREFIX]) + + PYTHON_CFLAGS="-DHAVE_PYTHON -I$PYTHON_PREFIX/include/python$PYTHON_VERSION" + + # Define the directories we ask setup.py to install the + # modules/extensions and scripts to. The way chosen here reproduces + # the internal behaviour of distutils. Unfortunately distutils does + # not export the pre-defined/configured directories, so we have to + # define them on our own. For default installations of distutils the + # chosen values here will match what distutils uses. + # See Makefile.am to see how they're used with setup.py. + PYTHON_DISTUTILS_LIBDIR=[`$PYTHON -c 'import distutils.util; import sys; print ("build/lib.%s-%s" %(distutils.util.get_platform(), sys.version[0:3]))'`] + PYTHON_DISTUTILS_SCRIPTDIR=[`$PYTHON -c 'import sys; print ("build/scripts-%s" %(sys.version[0:3], ))'`] + + OLD_CPPFLAGS="$CPPFLAGS" + OLD_CXXFLAGS="$CXXFLAGS" + CPPFLAGS="$CPPFLAGS $PYTHON_CFLAGS" + CXXFLAGS="$CXXFLAGS $PYTHON_CFLAGS" + + AC_CHECK_HEADERS([Python.h], + [], + [AC_MSG_WARN([*** Python include files not found! You should install the Python development package. Python support disabled]); ac_python=no]) + CPPFLAGS="$OLD_CPPFLAGS" + CXXFLAGS="$OLD_CXXFLAGS" + + if test "x$ac_python" = "xyes"; then + AC_SUBST([PYTHON_CFLAGS]) + AC_SUBST([PYTHON_DISTUTILS_LIBDIR]) + AC_SUBST([PYTHON_DISTUTILS_SCRIPTDIR]) + + ac_python=no + for pylibpath in '/usr/lib' $PYTHON_PREFIX/lib $PYTHON_PREFIX/lib/python$PYTHON_VERSION/config; do + eval `echo unset ac_cv_lib_python$PYTHON_VERSION'___'Py_Finalize | tr '.' '_'` + + save_LIBS=$LIBS + LIBS="$LIBS -L$pylibpath $PYTHON_LIBS" + AC_CHECK_LIB(python$PYTHON_VERSION, Py_Finalize, PYTHON_LIBS="-L$pylibpath -lpython$PYTHON_VERSION $PYTHON_DEPS"; ac_python=yes,,$PYTHON_DEPS) + LIBS=$save_LIBS + if test "x$ac_python" = "xyes"; then + break + fi + done + + if test "x$ac_python" != "xyes"; then + AC_MSG_WARN(*** Python development libraries required, Python support disabled) + fi + AC_SUBST([PYTHON_LIBS]) + + AC_SUBST(pkgpythondir) + if test "x$python_install" = "xyes"; then + pkgpythondir=$PYTHON_PREFIX"/lib/python"$PYTHON_VERSION"/site-packages/gpsd" + fi + fi +fi +AM_CONDITIONAL([HAVE_PYTHON], [test x"$ac_python" = xyes]) + +AC_PROG_LN_S +AC_PROG_MAKE_SET +AC_PROG_INSTALL +AC_PROG_LIBTOOL +AC_PROG_CXX +AC_C_BIGENDIAN +type_error="no" +AC_CHECK_SIZEOF([char]) +AC_CHECK_SIZEOF([short]) +AC_CHECK_SIZEOF([int]) +AC_CHECK_SIZEOF([long]) +AC_CHECK_SIZEOF([long long]) +AC_CHECK_SIZEOF([float]) +AC_CHECK_SIZEOF([double]) +if test x"$ac_cv_sizeof_char" != "x1" ; then + AC_MSG_WARN(gpsd requires sizeof(char)==1); + type_error="yes" +fi +if test x"$ac_cv_sizeof_short" != "x2" ; then + AC_MSG_WARN(gpsd requires sizeof(short)==2); + type_error="yes" +fi +if test x"$ac_cv_sizeof_int" != "x4" ; then + AC_MSG_WARN(gpsd requires sizeof(int)==4); + type_error="yes" +fi +if test x"$ac_cv_sizeof_long_long" != "x8" ; then + AC_MSG_WARN(gpsd requires sizeof(long long)==8); + type_error="yes" +fi +if test x"$ac_cv_sizeof_float" != "x4" ; then + AC_MSG_WARN(gpsd requires sizeof(float)==4); + type_error="yes" +fi +if test x"$ac_cv_sizeof_double" != "x8" ; then + AC_MSG_WARN(gpsd requires sizeof(double)==8); + type_error="yes" +fi +if test x"$type_error" = "xyes" ; then + AC_ERROR(Your system does not provide all required data types); +fi + +AC_FUNC_ALLOCA +AC_STDC_HEADERS +AC_C_CONST + +AC_MSG_CHECKING([for properly working floating point implementation]) +if test "x$build" = "x$host"; then + if eval "$CC $CFLAGS -o test_float ${srcdir}/test_float.c"; then + if ./test_float > /dev/null; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_WARN([We strongly recommend you manually examine the test_float results]) + fi + else + AC_MSG_RESULT([failure compiling test_float]) + fi +else + AC_MSG_RESULT([skipped test (cross-compiling)]) + AC_MSG_WARN([We are cross-compiling, and thus cannot run the floating point test now. +We strongly recommend running test_float on the target platform.]) +fi + + +if eval "test x$GCC = xyes"; then + CFLAGS="$CFLAGS -Wall -Wcast-align -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith -Wreturn-type -D_GNU_SOURCE" + dnl -Wcast-qual -W +fi + +AC_CHECK_HEADERS(sys/termios.h sys/select.h sys/time.h sys/modem.h sys/ipc.h sys/shm.h sys/stat.h sys/socket.h sys/ioctl.h sys/un.h) +AC_CHECK_HEADERS(arpa/inet.h netinet/in_systm.h netinet/in.h netinet/tcp.h) +AC_CHECK_HEADERS([netinet/ip.h], [], [], +[[#if HAVE_NETINET_IN_SYSTM_H && HAVE_NETINET_IN_H +#include netinet/ip.h +#endif +]]) +AC_CHECK_HEADERS(termios.h strings.h getopt.h netdb.h syslog.h pwd.h grp.h) + +AC_CHECK_FUNCS(round, roundf) +AC_CHECK_FUNCS(strlcpy) +AC_CHECK_FUNCS(strlcat) +AC_CHECK_FUNCS(strtonum) +AC_CHECK_FUNCS(setlocale) +AC_CHECK_FUNCS(vsnprintf) + +AC_HEADER_TIME +AC_STRUCT_TIMEZONE + +AC_CACHE_CHECK(for timezone variable, ac_cv_var_timezone, + AC_TRY_COMPILE([ +#include + ], [ + timezone = 1; + ], ac_cv_var_timezone=yes, ac_cv_var_timezone=no)) +if test $ac_cv_var_timezone = yes; then + AC_DEFINE(HAVE_TIMEZONE, [], [Have timezone variable]) +else + AC_CACHE_CHECK(for tm_gmtoff in struct tm, ac_cv_struct_tm_gmtoff, + AC_TRY_COMPILE([ +#include + ], [ + struct tm tm; + tm.tm_gmtoff = 1; + ], ac_cv_struct_tm_gmtoff=yes, ac_cv_struct_tm_gmtoff=no +)) + if test $ac_cv_struct_tm_gmtoff = yes; then + AC_DEFINE(HAVE_TM_GMTOFF, [], [struct tm has tm_gmtoff]) + else + AC_ERROR(unable to find a way to determine timezone) + fi +fi +AC_CACHE_CHECK(for daylight external, mb_cv_var_daylight, +[ AC_TRY_LINK([#include ], [return (int)daylight;], + mb_cv_var_daylight=yes, + mb_cv_var_daylight=no) +]) +if test $mb_cv_var_daylight = yes; then + AC_DEFINE([HAVE_DAYLIGHT], 1, + [Define if you have the external 'daylight' variable.]) +fi + +AC_CHECK_LIB(nsl, gethostbyname, LIBNSL="-lnsl") +AC_SUBST(LIBNSL) +AC_CHECK_LIB(socket, socket, LIBSOCKET="-lsocket") +AC_SUBST(LIBSOCKET) +AC_CHECK_LIB(m, rint, LIBM="-lm") +AC_SUBST(LIBM) +AC_CHECK_LIB(c, open, LIBC="-lc") +AC_SUBST(LIBC) +AC_CHECK_LIB(pthread, pthread_setcancelstate, + [LIBPTHREAD="-lpthread" + AC_DEFINE([HAVE_LIBPTHREAD], [], [pthread libraries are present])]) +AC_SUBST(LIBPTHREAD) + +PKG_CHECK_MODULES(LIBUSB, libusb-1.0 >= 1.0.0, [ac_libusb=yes], [ac_libusb=no]) +AC_SUBST(LIBUSB_LIBS) +AC_SUBST(LIBUSB_CFLAGS) +if test x"$ac_libusb" = x"yes" ; then + AC_DEFINE([HAVE_LIBUSB], 1, [libusb support]) +fi + +AH_VERBATIM([_GNU_SOURCE], + [/* Some libc's don't have strlcat/strlcpy. Local copies are provided */ +#ifndef HAVE_STRLCAT +# ifdef __cplusplus +extern "C" { +# endif +size_t strlcat(/*@out@*/char *dst, /*@in@*/const char *src, size_t size); +# ifdef __cplusplus +} +# endif +#endif +#ifndef HAVE_STRLCPY +# ifdef __cplusplus +extern "C" { +# endif +size_t strlcpy(/*@out@*/char *dst, /*@in@*/const char *src, size_t size); +# ifdef __cplusplus +} +# endif +#endif + +#define GPSD_CONFIG_H]) + + + +dnl Check for curses headers and libraries. The presence of the +dnl library is used to decide whether or not to build some programs. +dnl Those programs use ncurses.h if found, and otherwise use curses.h. +dnl TODO: give an example of what system uses curses.h with +dnl libncurses. We define our own variables to reduce the risk of +dnl breaking if autoconf changes (private) variable names. +AC_CHECK_HEADERS(ncurses.h) +AC_CHECK_LIB(ncurses, initscr, NCURSES_LIBS="-lncurses") +AC_SUBST(NCURSES_LIBS) +if test x"$NCURSES_LIBS" = x"" ; then + AC_MSG_WARN([Not including curses support]) + AM_CONDITIONAL([HAVE_NCURSES],false) + ac_ncurses="no" +else + AM_CONDITIONAL([HAVE_NCURSES],true) + ac_ncurses="yes" +fi + +dnl check for NMEA support +AC_ARG_ENABLE(nmea, + AC_HELP_STRING([--disable-nmea], + [disable NMEA support]), + [ac_nmea=$enableval], [ac_nmea=yes]) +AC_MSG_CHECKING([for NMEA support]) +if test x"$ac_nmea" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([NMEA_ENABLE], 1, [NMEA chipset support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for OnCore support +AC_ARG_ENABLE(oncore, + AC_HELP_STRING([--disable-oncore], + [disable Motorola OnCore chipset support]), + [ac_oncore=$enableval], [ac_oncore=yes]) +AC_MSG_CHECKING([for Motorola OnCore support]) +if test x"$ac_oncore" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([ONCORE_ENABLE], 1, [Motorola OnCore chipset support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for SiRF support +AC_ARG_ENABLE(sirf, + AC_HELP_STRING([--disable-sirf], + [disable SiRF chipset support]), + [ac_sirf=$enableval], [ac_sirf=yes]) +AC_MSG_CHECKING([for SiRF support]) +if test x"$ac_sirf" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([SIRF_ENABLE], 1, [SiRF chipset support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for Novatel SuperStarII support +AC_ARG_ENABLE(superstar2, + AC_HELP_STRING([--disable-superstar2], + [disable SuperStarII chipset support]), + [ac_superstar2=$enableval], [ac_superstar2=yes]) +AC_MSG_CHECKING([for SuperStarII support]) +if test x"$ac_superstar2" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([SUPERSTAR2_ENABLE], 1, [SuperStarII chipset support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for Trimble TSIP support +AC_ARG_ENABLE(tsip, + AC_HELP_STRING([--disable-tsip], + [disable Trimble TSIP support]), + [ac_tsip=$enableval], [ac_tsip=yes]) +AC_MSG_CHECKING([for Trimble TSIP support]) +if test x"$ac_tsip" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([TSIP_ENABLE], 1, [Trimble TSIP support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for FV-18 support +AC_ARG_ENABLE(fv18, + AC_HELP_STRING([--disable-fv18], + [disable San Jose Navigation FV-18 support]), + [ac_fv18=$enableval], [ac_fv18=yes]) +AC_MSG_CHECKING([for FV-18 support]) +if test x"$ac_fv18" = "xyes"; then + ac_nmea=yes + AC_MSG_RESULT([yes]) + AC_DEFINE([FV18_ENABLE], 1, [San Jose Navigation FV-18 support]) + AC_DEFINE([NMEA_ENABLE], 1, [San Jose Navigation FV-18 requires NMEA support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for Tripmate support +AC_ARG_ENABLE(tripmate, + AC_HELP_STRING([--disable-tripmate], + [disable DeLorme TripMate support]), + [ac_tripmate=$enableval], [ac_tripmate=yes]) +AC_MSG_CHECKING([for Tripmate support]) +if test x"$ac_tripmate" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([TRIPMATE_ENABLE], 1, [DeLorme TripMate support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for EarthMate support +AC_ARG_ENABLE(earthmate, + AC_HELP_STRING([--disable-earthmate], + [disable DeLorme EarthMate Zodiac support]), + [ac_earthmate=$enableval], [ac_earthmate=yes]) +AC_MSG_CHECKING([for EarthMate support]) +if test x"$ac_earthmate" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([EARTHMATE_ENABLE], 1, [DeLorme EarthMate Zodiac support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for iTrax support +AC_ARG_ENABLE(itrax, + AC_HELP_STRING([--disable-itrax], + [disable iTrax hardware support]), + [ac_itrax=$enableval], [ac_itrax=yes]) +AC_MSG_CHECKING([for iTrax support]) +if test x"$ac_itrax" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([ITRAX_ENABLE], 1, [iTrax chipset support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for Ashtech support +AC_ARG_ENABLE(ashtech, + AC_HELP_STRING([--disable-ashtech], + [disable Ashtech support]), + [ac_ashtech=$enableval], [ac_ashtech=yes]) +AC_MSG_CHECKING([for Ashtech support]) +if test x"$ac_ashtech" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([ASHTECH_ENABLE], 1, [Ashtech chipset support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for Navcom support +AC_ARG_ENABLE(navcom, + AC_HELP_STRING([--disable-navcom], + [disable Navcom support]), + [ac_navcom=$enableval], [ac_navcom=yes]) +AC_MSG_CHECKING([for Navcom support]) +if test x"$ac_navcom" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([NAVCOM_ENABLE], 1, [Navcom support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for Garmin support +AC_ARG_ENABLE(garmin, + AC_HELP_STRING([--disable-garmin], + [disable Garmin kernel driver support]), + [ac_garmin=$enableval], [ac_garmin=yes]) +AC_MSG_CHECKING([for Garmin support]) +if test x"$ac_garmin" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([GARMIN_ENABLE], 1, [Garmin support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for Garmin Simple Text support +AC_ARG_ENABLE(garmintxt, + AC_HELP_STRING([--enable-garmintxt], + [enable Garmin Simple Text support]), + [ac_garmintxt=$enableval], [ac_garmintxt=yes]) +AC_MSG_CHECKING([for Garmin Simple Text support]) +if test x"$ac_garmintxt" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([GARMINTXT_ENABLE], 1, [Garmin Simple Text support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for True North support +AC_ARG_ENABLE(tnt, + AC_HELP_STRING([--enable-tnt], + [disable True North Technologies support]), + [ac_tnt=$enableval], [ac_tnt=yes]) +AC_MSG_CHECKING([for True North support]) +if test x"$ac_tnt" = "xyes"; then + ac_nmea=yes + AC_MSG_RESULT([yes]) + AC_DEFINE([TNT_ENABLE], 1, [True North Technologies support]) + AC_DEFINE([NMEA_ENABLE], 1, [True North requires NMEA support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for OceanServer support +AC_ARG_ENABLE(oceanserver, + AC_HELP_STRING([--disable-oceanserver], + [disable OceanServer support]), + [ac_oceanserver=$enableval], [ac_oceanserver=yes]) +AC_MSG_CHECKING([for OceanServer support]) +if test x"$ac_oceanserver" = "xyes"; then + ac_nmea=yes + AC_MSG_RESULT([yes]) + AC_DEFINE([OCEANSERVER_ENABLE], 1, [OceanServer support]) + AC_DEFINE([NMEA_ENABLE], 1, [OceanServer requires NMEA support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for UBX support +AC_ARG_ENABLE(ubx, + AC_HELP_STRING([--disable-ubx], + [disable UBX Protocol support]), + [ac_ubx=$enableval], [ac_ubx=yes]) +AC_MSG_CHECKING([for UBX support]) +if test x"$ac_ubx" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([UBX_ENABLE], 1, [UBX Protocol support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for EverMore support +AC_ARG_ENABLE(evermore, + AC_HELP_STRING([--disable-evermore], + [disable EverMore binary support]), + [ac_evermore=$enableval], [ac_evermore=yes]) +AC_MSG_CHECKING([for EverMore support]) +if test x"$ac_evermore" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([EVERMORE_ENABLE], 1, [EverMore binary support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for MTK-3301 support +AC_ARG_ENABLE(mtk3301, + AC_HELP_STRING([--disable-mtk3301], + [disable MTK-3301 support]), + [ac_mtk3301=$enableval], [ac_mtk3301=yes]) +AC_MSG_CHECKING([for MTK-3301 support]) +if test x"$ac_mtk3301" = "xyes"; then + ac_nmea=yes + AC_MSG_RESULT([yes]) + AC_DEFINE([MTK3301_ENABLE], 1, [MTK-3301 support]) + AC_DEFINE([NMEA_ENABLE], 1, [MTK-3301 requires NMEA support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for GPSClock support +AC_ARG_ENABLE(gpsclock, + AC_HELP_STRING([--disable-gpsclock], + [disable GPSClock support]), + [ac_gpsclock=$enableval], [ac_gpsclock=yes]) +AC_MSG_CHECKING([for GPSClock support]) +if test x"$ac_gpsclock" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([GPSCLOCK_ENABLE], 1, [GPSclock chipset support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for RTCM104V2 support +AC_ARG_ENABLE(rtcm104v2, + AC_HELP_STRING([--disable-rtcm104v2], + [disable rtcm104v2 support]), + [ac_rtcm104v2=$enableval], [ac_rtcm104v2=yes]) +AC_MSG_CHECKING([for rtcm104v2 support]) +if test x"$ac_earthmate" = "xno" -a x"$ac_evermore" = "xno" -a x"$ac_garmin" = "xno" -a x"$ac_itrax" = "xno" -a x"$ac_sirf" = "xno" -a x"$ac_superstar2" = "xno" -a x"$ac_tsip" = "xno" -a x"$ac_navcom" = "xno"; then + ac_rtcm104v2=no +fi +if test x"$ac_rtcm104v2" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([RTCM104V2_ENABLE], 1, [rtcm104v2 binary support]) +else + AC_MSG_RESULT([no]) +fi + +AM_CONDITIONAL([HAVE_RTCM104V2], [test "$ac_rtcm104v2" = "yes"]) + +dnl check for RTCM104V3 support +AC_ARG_ENABLE(rtcm104v3, + AC_HELP_STRING([--disable-rtcm104v3], + [disable rtcm104v3 support]), + [ac_rtcm104v3=$enableval], [ac_rtcm104v3=yes]) +AC_MSG_CHECKING([for rtcm104v3 support]) +if test x"$ac_earthmate" = "xno" -a x"$ac_evermore" = "xno" -a x"$ac_garmin" = "xno" -a x"$ac_itrax" = "xno" -a x"$ac_sirf" = "xno" -a x"$ac_tsip" = "xno" -a x"$ac_navcom" = "xno"; then + ac_rtcm104v3=no +fi +if test x"$ac_rtcm104v3" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([RTCM104V3_ENABLE], 1, [rtcm104v3 binary support]) +else + AC_MSG_RESULT([no]) +fi + +AM_CONDITIONAL([HAVE_RTCM104V3], [test "$ac_rtcm104v3" = "yes"]) + +dnl check for NTRIP support +AC_ARG_ENABLE(ntrip, + AC_HELP_STRING([--disable-ntrip], + [disable NTRIP support]), + [ac_ntrip=$enableval], [ac_ntrip=yes]) +AC_MSG_CHECKING([for NTRIP support]) +if test x"$ac_ntrip" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([NTRIP_ENABLE], 1, [NTRIP support]) +else + AC_MSG_RESULT([no]) +fi + +AM_CONDITIONAL([HAVE_NTRIP], [test "$ac_ntrip" = "yes"]) + +dnl check for AIVDM support +AC_ARG_ENABLE(aivdm, + AC_HELP_STRING([--disable-aivdm], + [disable Aivdm support]), + [ac_aivdm=$enableval], [ac_aivdm=yes]) +AC_MSG_CHECKING([for AIVDM support]) +if test x"$ac_aivdm" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([AIVDM_ENABLE], 1, [AIVDM protocol support)]) +else + AC_MSG_RESULT([no]) +fi +AM_CONDITIONAL([HAVE_AIVDM], [test "$ac_aivdm" = "yes"]) + +dnl check for latency timing support +AC_ARG_ENABLE(timing, + AC_HELP_STRING([--disable-timing], + [disable latency timing support]), + [ac_timing=$enableval], [ac_timing=yes]) +AC_MSG_CHECKING([for latency timing support]) +if test x"$ac_timing" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([TIMING_ENABLE], 1, [latency timing support)]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for client debugging support +AC_ARG_ENABLE(clientdebug, + AC_HELP_STRING([--disable-clientdebug], + [disable client debugging support]), + [ac_clientdebug=$enableval], [ac_clientdebug=yes]) +AC_MSG_CHECKING([for client debugging support]) +if test x"$ac_clientdebug" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([CLIENTDEBUG_ENABLE], 1, [client debugging support)]) +else + AC_MSG_RESULT([no]) +fi + +AM_CONDITIONAL([CLIENTDEBUG_ENABLE], [test x"$ac_clientdebug" = x"yes"]) + +dnl check for support for oldstyle protocol +AC_ARG_ENABLE(oldstyle, + AC_HELP_STRING([--disable-oldstyle], + [disable oldstyle (pre-JSON) protocol support]), + [ac_oldstyle=$enableval], [ac_oldstyle=yes]) +AC_MSG_CHECKING([for oldstyle support]) +if test x"$ac_oldstyle" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([OLDSTYLE_ENABLE], 1, [oldstyle (pre-JSON) protocol support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for profiling support +AC_ARG_ENABLE(profiling, + AC_HELP_STRING([--enable-profiling], + [enable profiling support]), + [ac_profiling=$enableval], [ac_profiling=no]) +AC_MSG_CHECKING([for profiling support]) +if test x"$ac_profiling" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([PROFILING], 1, [profiling support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for NTP time hinting support +AC_ARG_ENABLE(ntpshm, + AC_HELP_STRING([--disable-ntpshm], + [disable NTP time hinting support]), + [ac_ntpshm=$enableval], [ac_ntpshm=yes]) +AC_MSG_CHECKING([for NTP time hinting support]) +if test x"$ac_ntpshm" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([NTPSHM_ENABLE], 1, [NTP time hinting support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for PPS time syncing support +AC_ARG_ENABLE(pps, + AC_HELP_STRING([--disable-pps], + [disable PPS time syncing support]), + [ac_pps=$enableval], [ac_pps=yes]) +AC_MSG_CHECKING([for PPS time syncing support]) +if test x"$ac_pps" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([PPS_ENABLE], 1, [PPS time syncing support]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for PPS input on CTS line +AC_ARG_ENABLE(pps-on-cts, + AC_HELP_STRING([--enable-pps-on-cts], + [Enable PPS pulse on CTS rather than DCD]), + [ac_ppsoncts=$enableval], [ac_ppsoncts=no]) +AC_MSG_CHECKING([for PPS pulse on CTS rather than DCD]) +if test x"$ac_ppsoncts" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([PPS_ON_CTS], 1, [PPS on CTS rather than DCD]) +else + AC_MSG_RESULT([no]) +fi + +dnl check for privilege revocation user at compile-time +AC_ARG_ENABLE(gpsd-user, + AC_HELP_STRING([--enable-gpsd-user=username], + [GPSD privilege revocation user]), + [ac_user=$enableval], [ac_user=nobody]) +AC_MSG_CHECKING([privilege revocation user]) +if test x"$ac_user" != "xnobody"; then + AC_MSG_RESULT([$ac_user]) + AC_DEFINE_UNQUOTED([GPSD_USER], "$ac_user", [GPSD privilege revocation user]) +else + AC_MSG_RESULT([nobody]) +fi + +dnl check for privilege revocation group at compile-time +AC_ARG_ENABLE(gpsd-group, + AC_HELP_STRING([--enable-gpsd-group=groupname], + [GPSD privilege revocation group, use if /dev/ttyS0 not found]), + [ac_group=$enableval]) +AC_MSG_CHECKING([privilege revokation group]) +if test x"$ac_user" != "xnobody"; then + AC_MSG_RESULT([$ac_group]) + AC_DEFINE_UNQUOTED([GPSD_GROUP], "$ac_group", [GPSD privilege revokation group]) +fi + +dnl check for port speed fixed at compile-time +AC_ARG_ENABLE(fixed-port-speed, + AC_HELP_STRING([--enable-fixed-port-speed=nnn], + [compile with fixed serial port speed]), + [ac_baud=$enableval], [ac_baud=no]) +AC_MSG_CHECKING([for fixed port speed]) +if test x"$ac_baud" != "xno"; then + AC_MSG_RESULT([$ac_baud]) + AC_DEFINE_UNQUOTED([FIXED_PORT_SPEED], $ac_baud, [Fixed port speed]) + FIXED_PORT_SPEED="-DSPEEDFLAGS=$ac_baud" +else + AC_MSG_RESULT([no]) +fi + +dnl Check for BlueZ support +AC_ARG_ENABLE(bluetooth, AC_HELP_STRING([--enable-bluetooth], [Enable support for Bluetooth GPS devices via BlueZ (experimental)]), + [ac_bluetooth=$enableval], [ac_bluetooth=no]) +AC_MSG_CHECKING([for BlueZ support]) +if test x"$ac_bluetooth" = x"yes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_BLUEZ,1,[Define if we have Bluez]) + # Older versions of autotools barf and die on this. + #PKG_CHECK_MODULES(BLUEZ, bluez ) + BLUEZ_CFLAGS=`pkg-config --cflags bluez` + BLUEZ_LIBS=`pkg-config --libs bluez` + AC_SUBST(BLUEZ_CFLAGS) + AC_SUBST(BLUEZ_LIBS) +else + AC_MSG_RESULT([no]) +fi + + + +dnl Manually configure DBUS until we figure out a +dnl distro-independent was to check for both libraries and headers +AC_ARG_ENABLE(dbus, + AC_HELP_STRING([--enable-dbus], + [enable DBUS support]), + [ac_dbus=$enableval], [ac_dbus=no]) +AC_MSG_CHECKING([for DBUS support]) +if test x"$ac_dbus" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([DBUS_ENABLE], 1, [DBUS support]) + # Older versions of autotools barf and die on this. + #PKG_CHECK_MODULES(DBUS, dbus-1 >= 0.23.4 ) + DBUS_CFLAGS=`pkg-config --cflags dbus-glib-1` + DBUS_LIBS=`pkg-config --libs dbus-1` + AC_SUBST(DBUS_CFLAGS) + AC_SUBST(DBUS_LIBS) + #PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1 >= 0.22 ) + DBUS_GLIB_LIBS=`pkg-config --libs dbus-glib-1` + AC_SUBST(DBUS_GLIB_CFLAGS) + AC_SUBST(DBUS_GLIB_LIBS) +else + AC_MSG_RESULT([no]) +fi + +dnl check for limited maximum clients +AC_ARG_ENABLE(max-clients, + AC_HELP_STRING([--enable-max-clients=nnn], + [compile with limited maximum clients]), + [ac_maxclients=$enableval], [ac_maxclients=no]) +AC_MSG_CHECKING([for limited max clients]) +if test x"$ac_maxclients" != "xno"; then + AC_MSG_RESULT([$ac_maxclients]) + AC_DEFINE_UNQUOTED([LIMITED_MAX_CLIENTS], $ac_maxclients, [Limited maximum clients]) + LIMITED_MAX_CLIENTS="-DLIMITED_MAX_CLIENTS=$ac_maxclients" +else + AC_MSG_RESULT([no]) +fi + +dnl check for max number of GPS devices +AC_ARG_ENABLE(max-devices, + AC_HELP_STRING([--enable-max-devices=nnn], + [compile with maximum allowed devices]), + [ac_maxdevices=$enableval], [ac_maxdevices=no]) +AC_MSG_CHECKING([for max devices]) +if test x"$ac_maxdevices" != "xno"; then + AC_MSG_RESULT([$ac_maxdevices]) + AC_DEFINE_UNQUOTED([LIMITED_MAX_DEVICES], $ac_maxdevices, [Maximum gps devices]) + LIMITED_MAX_DEVICES="-DLIMITED_MAX_DEVICES=$ac_maxdevices" +else + AC_MSG_RESULT([no]) +fi + +dnl allow gpsd to reconfigure gps receiver +AC_ARG_ENABLE(reconfigure, + AC_HELP_STRING([--disable-reconfigure], + [do not allow gpsd to change device settings]), + [ac_reconfigure=$enableval], [ac_reconfigure=yes]) +AC_MSG_CHECKING([if device reconfiguration is allowed]) +if test x"$ac_reconfigure" != "xno"; then + AC_MSG_RESULT([$ac_reconfigure]) + AC_DEFINE([ALLOW_RECONFIGURE], 1, [Allow gpsd to reconfigure device]) +else + AC_MSG_RESULT([no]) +fi + +dnl allow tools to use control_send method +AC_ARG_ENABLE(controlsend, + AC_HELP_STRING([--disable-controlsend], + [do not allow gpsctl/gpsmon to change device settings]), + [ac_controlsend=$enableval], [ac_controlsend=yes]) +AC_MSG_CHECKING([if control sending is allowed]) +if test x"$ac_controlsend" != "xno"; then + AC_MSG_RESULT([$ac_controlsend]) + AC_DEFINE([ALLOW_CONTROLSEND], 1, [Allow gpsd to controlsend device]) +else + AC_MSG_RESULT([no]) +fi + +dnl enable raw measurements +AC_ARG_ENABLE(raw, + AC_HELP_STRING([--enable-raw], + [enable raw measurement processing]), + [ac_raw=$enableval], [ac_raw=yes]) +AC_MSG_CHECKING([for Raw Measurement support]) +if test x"$ac_raw" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([RAW_ENABLE], 1, [Raw Measurement support]) +else + AC_MSG_RESULT([no]) +fi + +dnl Automatic check for DBUS. +dnl It's broken -- leads to bad compiles on systems with DBUS libraies +dnl but no DBUS headers. +dnl ac_dbus=no +dnl AC_CHECK_LIB(dbus-1, dbus_bus_get, [true], [false]) # do not update $LIBS +dnl if test x"yes" = x"$ac_cv_lib_dbus_1_dbus_bus_get" ; then +dnl # Found dbus library, check for required versions and enable it +dnl +dnl AC_MSG_CHECKING([for DBUS support]) +dnl PKG_CHECK_MODULES(DBUS, dbus-1 >= 0.23.4, +dnl [ac_dbus=yes],[ac_dbus=no]) +dnl AC_MSG_RESULT([$ac_dbus]) +dnl AC_SUBST(DBUS_CFLAGS) +dnl AC_SUBST(DBUS_LIBS) +dnl +dnl if test x"ac_dbus" = x"yes" ; then +dnl AC_DEFINE([DBUS_ENABLE],1,[Found DBUS libraries]) +dnl fi +dnl +dnl # Check for glib and dbus-glib, used by gpxlogger +dnl PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.2.0 ) +dnl AC_SUBST(GLIB_CFLAGS) +dnl AC_SUBST(GLIB_LIBS) +dnl +dnl PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1 >= 0.22) +dnl AC_SUBST(DBUS_GLIB_CFLAGS) +dnl AC_SUBST(DBUS_GLIB_LIBS) +dnl fi +AM_CONDITIONAL([HAVE_DBUS], [test x"$ac_dbus" = x"yes"]) +AM_CONDITIONAL([HAVE_BLUEZ], [test x"$ac_bluetooth" = x"yes"]) + +dnl mute logging functions? +AC_ARG_ENABLE(squelch, + AC_HELP_STRING([--enable-squelch], + [squelch gpsd_report and gpsd_hexdump to save cpu]), + [ac_squelch=$enableval], [ac_squelch=no]) +AC_MSG_CHECKING([for disabled logging]) +if test x"$ac_squelch" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([SQUELCH_ENABLE], 1, [Squelch logging and hexdumps]) +else + AC_MSG_RESULT([no]) +fi + +dnl C++ bindings +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ISCXX="yes" +else + ISCXX="no" +fi + +AC_ARG_ENABLE(libgpsmm, + AC_HELP_STRING([--disable-libgpsmm], + [don't build C++ bindings]), + [ac_libgpsmm=$enableval], [ac_libgpsmm=$ISCXX]) +AC_MSG_CHECKING([for C++ support]) +if test x"$ac_libgpsmm" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([LIBGPSMM_ENABLE], 1, [C++ support]) +else + AC_MSG_RESULT([no]) +fi + +AM_CONDITIONAL([LIBGPSMM_ENABLE], [test x"$ac_libgpsmm" = x"yes"]) + + + +dnl Check for QtNetwork library and qmake. Both are necessary +dnl to build libQgpsmm. We use pkgconfig to check for the library +dnl and AC_CHECK_PROGS to search for qmake. As it is possible to +dnl install qmake from qt and qt4 in parallel, check for qmake-qt4 +dnl first as this ensures we're using qmake for qt4. +AC_ARG_ENABLE(libQgpsmm, + AC_HELP_STRING([--disable-libQgpsmm], + [don't build QT bindings]), + [ac_libQgpsmm=$enableval], [ac_libQgpsmm=$ISCXX]) +AC_MSG_CHECKING([for QT support]) +if test x"$ac_libQgpsmm" = "xyes"; then + PKG_CHECK_MODULES(QtNetwork, [QtNetwork >= 4.4], ac_qt="yes", ac_qt="no") + if test x"$ac_qt" != "xyes"; then + AC_MSG_WARN([QtNetwork library not found. Not including QT support]) + ac_libQgpsmm="no" + AM_CONDITIONAL([LIB_Q_GPSMM_ENABLE], false) + AC_MSG_RESULT([no]) + else + AC_CHECK_PROGS(QMAKE, [qmake-qt4 qmake], [no]) + if test x"$QMAKE" != "xno"; then + AM_CONDITIONAL([LIB_Q_GPSMM_ENABLE], true) + AC_MSG_RESULT([yes]) + else + AC_MSG_WARN([qmake not found. Not including QT support]) + ac_libQgpsmm="no" + AM_CONDITIONAL([LIB_Q_GPSMM_ENABLE], false) + AC_MSG_RESULT([no]) + fi + fi +else + AC_MSG_RESULT([no]) + AM_CONDITIONAL([LIB_Q_GPSMM_ENABLE], false) +fi + + + +AC_ARG_ENABLE(ipv6, + AC_HELP_STRING([--disable-ipv6], + [don't build IPv6 support]), + [ac_ipv6=$enableval], [ac_ipv6=$ISCXX]) +AC_MSG_CHECKING([for IPv6 support]) +if test x"$ac_ipv6" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([IPV6_ENABLE], 1, [IPv6 support]) +else + AC_MSG_RESULT([no]) +fi + +AM_CONDITIONAL([IPV6_ENABLE], [test x"$ac_ipv6" = x"yes"]) + +dnl Test for XSLT processor (xsltproc or xmlto) +AC_CHECK_PROG(WITH_XSLTPROC,[xsltproc],[yes],[no]) +XMLPROC= +MANTARGET= +XMLPROCFLAGS= +if test "x$WITH_XSLTPROC" = "xyes"; then + AC_MSG_CHECKING([whether xsltproc knows about docbook xsl]) + DOCBOOK_MAN_URI='http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' + DOCBOOK_HTML_URI='http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl' + cat >conftest.xml <<_EOF + + + foo + 1 + 9 Aug 2004 + + + foo + check man page generation from docbook source + + +_EOF + if xsltproc --nonet --noout "$DOCBOOK_MAN_URI" conftest.xml >/dev/null 2>&1; then + XMLPROC=xsltproc + MANTARGET="$DOCBOOK_MAN_URI" + HTMLTARGET="$DOCBOOK_HTML_URI" + XMLPROCFLAGS="--nonet" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + rm -f conftest.xml foo.1 +fi +if test x"$XMLPROC" = x; then + AC_CHECK_PROG(WITH_XMLTO,[xmlto],[yes],[no]) + if test "x$WITH_XMLTO" = "xyes"; then + XMLPROC=xmlto + MANTARGET=man + HTMLTARGET=xhtml-nochunks + XMLPROCFLAGS= + else + AC_MSG_WARN([Neither xsltproc nor xmlto works: I will not build man pages.]) + AC_MSG_WARN([To build man pages, install xsltproc/xsltlib or xmlto and run autogen.sh again.]) + fi +fi +AM_CONDITIONAL([HAVE_XSLT_PROCESSOR], + [test x"$XMLPROC" != x]) +AM_CONDITIONAL([XMLTOSTDOUT], [test x"$XMLPROC" = x"xsltproc"]) +AC_SUBST(XMLPROC) +AC_SUBST(MANTARGET) +AC_SUBST(HTMLTARGET) +AC_SUBST(XMLPROCFLAGS) + +dnl Gentoo systems can have a problem with the Python path +if test -e /etc/gentoo-release; then + AC_MSG_WARN([This is a Gentoo system.]) + AC_MSG_WARN([Adjust your PYTHONPATH to see library directories under /usr/local/lib]) +fi + +dnl Output the configuration summary +echo "" +echo "==========================================" +echo "$PACKAGE $VERSION" +echo "------------------------------------------" +dnl When you add a protocol here, don't forget the null-set check below +echo " Protocols" +echo " ---------" +echo "Ashtech : $ac_ashtech" +echo "Earthmate : $ac_earthmate" +echo "EverMore : $ac_evermore" +echo "FV-18 : $ac_fv18" +echo "Garmin : $ac_garmin" +echo "Garmin Simple Text : $ac_garmintxt" +echo "iTrax : $ac_itrax" +echo "NMEA : $ac_nmea" +echo "NTRIP : $ac_ntrip" +echo "Navcom : $ac_navcom" +echo "OnCore : $ac_oncore" +echo "RTCM104V2 : $ac_rtcm104v2" +echo "RTCM104V3 : $ac_rtcm104v3" +echo "SiRF : $ac_sirf" +echo "SuperStarII : $ac_superstar2" +echo "Trimble TSIP : $ac_tsip" +echo "Tripmate : $ac_tripmate" +echo "True North : $ac_tnt" +echo "OceanServer : $ac_oceanserver" +echo "UBX : $ac_ubx" +echo "GPSclock : $ac_gpsclock" +echo "AIVDM support : $ac_aivdm" +echo "Timing support : $ac_timing" +echo "Client debugging support: $ac_clientdebug" +echo "MTK-3301 : $ac_mtk3301" +dnl Below this line are non-protocol switches +echo " Daemon Features" +echo " ---------------" +echo "NTP SHM : $ac_ntpshm" +echo "NTP PPS : $ac_pps" +echo -n "PPS input on : " ; case $ac_ppsoncts in yes) echo "CTS" ;; no) echo "DCD" ;; *) echo "Not defined" ;; esac +echo "Fixed port speed : $ac_baud" +echo "Priv-drop user : $ac_user" +echo "Enable shared libraries : $enable_shared" +echo "Enable DBUS support : $ac_dbus" +echo "Enable BlueZ support : $ac_bluetooth" +echo "Enable IPv6 support : $ac_ipv6" +echo "Limited max clients : $ac_maxclients" +echo "Limited max devices : $ac_maxdevices" +echo "Allow device reconfig : $ac_reconfigure" +echo "Allow control send : $ac_controlsend" +echo "Squelch logging/hexdump : $ac_squelch" +echo "Raw Measurements : $ac_raw" +echo "libusb device discovery : $ac_libusb" +echo " Client Features" +echo " ---------------" +echo "Old protocol in libgps : $ac_oldstyle" +echo "Build ncurses programs : $ac_ncurses" +echo "Enable Python support : $ac_python" +echo "Enable C++ support : $ac_libgpsmm" +echo "Enable Qt support : $ac_libQgpsmm" +echo "------------------------------------------" +echo "" + +if test "xdummy" = "xdummy" -a \ + x"$ac_earthmate" = "xno" -a \ + x"$ac_evermore" = "xno" -a \ + x"$ac_fv18" = "xno" -a \ + x"$ac_garmin" = "xno" -a \ + x"$ac_garmintxt" = "xno" -a \ + x"$ac_itrax" = "xno" -a \ + x"$ac_navcom" = "xno" -a \ + x"$ac_nmea" = "xno" -a \ + x"$ac_ntrip" = "xno" -a \ + x"$ac_oncore" = "xno" -a \ + x"$ac_rtcm104v2" = "xno" -a \ + x"$ac_sirf" = "xno" -a \ + x"$ac_superstar2" = "xno" -a \ + x"$ac_tnt" = "xno" -a \ + x"$ac_oceanserver" = "xno" -a \ + x"$ac_tripmate" = "xno" -a \ + x"$ac_tsip" = "xno" -a \ + x"$ac_ubx" = "xno"; then + AC_MSG_ERROR(Can't build gpsd with no protocols enabled) +fi +AC_OUTPUT(Makefile packaging/rpm/gpsd.spec libgps.pc libgpsd.pc + jsongen.py maskaudit.py + valgrind-audit, + [chmod +x jsongen.py maskaudit.py gpscat gpsfake gpsprof xgps valgrind-audit]) +echo "Configure finished, type 'make' to build." + diff --git a/crc24q.c b/crc24q.c new file mode 100644 index 0000000..7d65db4 --- /dev/null +++ b/crc24q.c @@ -0,0 +1,177 @@ +/* + * This is an implementation of the CRC-24Q cyclic redundancy checksum + * used by Qualcomm, RTCM104V3, and PGP 6.5.1. According to the RTCM104V3 + * standard, it uses the error polynomial + * + * x^24+ x^23+ x^18+ x^17+ x^14+ x^11+ x^10+ x^7+ x^6+ x^5+ x^4+ x^3+ x+1 + * + * This corresponds to a mask of 0x1864CFB. For a primer on CRC theory, + * including detailed discussion of how and why the error polynomial is + * expressed by this mask, see . + * + * 1) It detects all single bit errors per 24-bit code word. + * 2) It detects all double bit error combinations in a code word. + * 3) It detects any odd number of errors. + * 4) It detects any burst error for which the length of the burst is less than + * or equal to 24 bits. + * 5) It detects most large error bursts with length greater than 24 bits; + * the odds of a false positive are at most 2^-23. + * + * This hash should not be considered cryptographically secure, but it + * is extremely good at detecting noise errors. + * + * Note that this version has a seed of 0 wired in. The RTCM104V3 standard + * requires this. + * + * This file is Copyright (c) 2008,2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include + +#include "crc24q.h" + +#ifdef REBUILD_CRC_TABLE +/* + * The crc24q code table below can be regenerated with the following code: + */ +#include +#include + +unsigned table[256]; + +#define CRCSEED 0 /* could be NZ to detect leading zeros */ +#define CRCPOLY 0x1864CFB /* encodes all info about the polynomial */ + +static void crc_init(unsigned table[256]) +{ + unsigned i, j; + unsigned h; + + table[0] = CRCSEED; + table[1] = h = CRCPOLY; + + for (i = 2; i < 256; i *= 2) { + if ((h <<= 1) & 0x1000000) + h ^= CRCPOLY; + for (j = 0; j < i; j++) + table[i + j] = table[j] ^ h; + } +} + +int main(int argc, char *argv[]) +{ + int i; + + crc_init(table); + + for (i = 0; i < 256; i++) { + printf("0x%08X, ", table[i]); + if ((i % 4) == 3) + putchar('\n'); + } + + exit(0); +} +#endif + +static const unsigned crc24q[256] = { + 0x00000000, 0x01864CFB, 0x028AD50D, 0x030C99F6, + 0x0493E6E1, 0x0515AA1A, 0x061933EC, 0x079F7F17, + 0x08A18139, 0x0927CDC2, 0x0A2B5434, 0x0BAD18CF, + 0x0C3267D8, 0x0DB42B23, 0x0EB8B2D5, 0x0F3EFE2E, + 0x10C54E89, 0x11430272, 0x124F9B84, 0x13C9D77F, + 0x1456A868, 0x15D0E493, 0x16DC7D65, 0x175A319E, + 0x1864CFB0, 0x19E2834B, 0x1AEE1ABD, 0x1B685646, + 0x1CF72951, 0x1D7165AA, 0x1E7DFC5C, 0x1FFBB0A7, + 0x200CD1E9, 0x218A9D12, 0x228604E4, 0x2300481F, + 0x249F3708, 0x25197BF3, 0x2615E205, 0x2793AEFE, + 0x28AD50D0, 0x292B1C2B, 0x2A2785DD, 0x2BA1C926, + 0x2C3EB631, 0x2DB8FACA, 0x2EB4633C, 0x2F322FC7, + 0x30C99F60, 0x314FD39B, 0x32434A6D, 0x33C50696, + 0x345A7981, 0x35DC357A, 0x36D0AC8C, 0x3756E077, + 0x38681E59, 0x39EE52A2, 0x3AE2CB54, 0x3B6487AF, + 0x3CFBF8B8, 0x3D7DB443, 0x3E712DB5, 0x3FF7614E, + 0x4019A3D2, 0x419FEF29, 0x429376DF, 0x43153A24, + 0x448A4533, 0x450C09C8, 0x4600903E, 0x4786DCC5, + 0x48B822EB, 0x493E6E10, 0x4A32F7E6, 0x4BB4BB1D, + 0x4C2BC40A, 0x4DAD88F1, 0x4EA11107, 0x4F275DFC, + 0x50DCED5B, 0x515AA1A0, 0x52563856, 0x53D074AD, + 0x544F0BBA, 0x55C94741, 0x56C5DEB7, 0x5743924C, + 0x587D6C62, 0x59FB2099, 0x5AF7B96F, 0x5B71F594, + 0x5CEE8A83, 0x5D68C678, 0x5E645F8E, 0x5FE21375, + 0x6015723B, 0x61933EC0, 0x629FA736, 0x6319EBCD, + 0x648694DA, 0x6500D821, 0x660C41D7, 0x678A0D2C, + 0x68B4F302, 0x6932BFF9, 0x6A3E260F, 0x6BB86AF4, + 0x6C2715E3, 0x6DA15918, 0x6EADC0EE, 0x6F2B8C15, + 0x70D03CB2, 0x71567049, 0x725AE9BF, 0x73DCA544, + 0x7443DA53, 0x75C596A8, 0x76C90F5E, 0x774F43A5, + 0x7871BD8B, 0x79F7F170, 0x7AFB6886, 0x7B7D247D, + 0x7CE25B6A, 0x7D641791, 0x7E688E67, 0x7FEEC29C, + 0x803347A4, 0x81B50B5F, 0x82B992A9, 0x833FDE52, + 0x84A0A145, 0x8526EDBE, 0x862A7448, 0x87AC38B3, + 0x8892C69D, 0x89148A66, 0x8A181390, 0x8B9E5F6B, + 0x8C01207C, 0x8D876C87, 0x8E8BF571, 0x8F0DB98A, + 0x90F6092D, 0x917045D6, 0x927CDC20, 0x93FA90DB, + 0x9465EFCC, 0x95E3A337, 0x96EF3AC1, 0x9769763A, + 0x98578814, 0x99D1C4EF, 0x9ADD5D19, 0x9B5B11E2, + 0x9CC46EF5, 0x9D42220E, 0x9E4EBBF8, 0x9FC8F703, + 0xA03F964D, 0xA1B9DAB6, 0xA2B54340, 0xA3330FBB, + 0xA4AC70AC, 0xA52A3C57, 0xA626A5A1, 0xA7A0E95A, + 0xA89E1774, 0xA9185B8F, 0xAA14C279, 0xAB928E82, + 0xAC0DF195, 0xAD8BBD6E, 0xAE872498, 0xAF016863, + 0xB0FAD8C4, 0xB17C943F, 0xB2700DC9, 0xB3F64132, + 0xB4693E25, 0xB5EF72DE, 0xB6E3EB28, 0xB765A7D3, + 0xB85B59FD, 0xB9DD1506, 0xBAD18CF0, 0xBB57C00B, + 0xBCC8BF1C, 0xBD4EF3E7, 0xBE426A11, 0xBFC426EA, + 0xC02AE476, 0xC1ACA88D, 0xC2A0317B, 0xC3267D80, + 0xC4B90297, 0xC53F4E6C, 0xC633D79A, 0xC7B59B61, + 0xC88B654F, 0xC90D29B4, 0xCA01B042, 0xCB87FCB9, + 0xCC1883AE, 0xCD9ECF55, 0xCE9256A3, 0xCF141A58, + 0xD0EFAAFF, 0xD169E604, 0xD2657FF2, 0xD3E33309, + 0xD47C4C1E, 0xD5FA00E5, 0xD6F69913, 0xD770D5E8, + 0xD84E2BC6, 0xD9C8673D, 0xDAC4FECB, 0xDB42B230, + 0xDCDDCD27, 0xDD5B81DC, 0xDE57182A, 0xDFD154D1, + 0xE026359F, 0xE1A07964, 0xE2ACE092, 0xE32AAC69, + 0xE4B5D37E, 0xE5339F85, 0xE63F0673, 0xE7B94A88, + 0xE887B4A6, 0xE901F85D, 0xEA0D61AB, 0xEB8B2D50, + 0xEC145247, 0xED921EBC, 0xEE9E874A, 0xEF18CBB1, + 0xF0E37B16, 0xF16537ED, 0xF269AE1B, 0xF3EFE2E0, + 0xF4709DF7, 0xF5F6D10C, 0xF6FA48FA, 0xF77C0401, + 0xF842FA2F, 0xF9C4B6D4, 0xFAC82F22, 0xFB4E63D9, + 0xFCD11CCE, 0xFD575035, 0xFE5BC9C3, 0xFFDD8538, +}; + +unsigned crc24q_hash(unsigned char *data, int len) +{ + int i; + unsigned crc = 0; + + for (i = 0; i < len; i++) { + crc = (crc << 8) ^ crc24q[data[i] ^ (unsigned char)(crc >> 16)]; + } + + crc = (crc & 0x00ffffff); + + return crc; +} + +#define LO(x) (unsigned char)((x) & 0xff) +#define MID(x) (unsigned char)(((x) >> 8) & 0xff) +#define HI(x) (unsigned char)(((x) >> 16) & 0xff) + +void crc24q_sign(unsigned char *data, int len) +{ + unsigned crc = crc24q_hash(data, len); + + data[len] = HI(crc); + data[len + 1] = MID(crc); + data[len + 2] = LO(crc); +} + +bool crc24q_check(unsigned char *data, int len) +{ + unsigned crc = crc24q_hash(data, len - 3); + + return (((data[len - 3] == HI(crc)) && + (data[len - 2] == MID(crc)) && (data[len - 1] == LO(crc)))); +} diff --git a/crc24q.h b/crc24q.h new file mode 100644 index 0000000..8ad6f0c --- /dev/null +++ b/crc24q.h @@ -0,0 +1,15 @@ +/* Interface for CRC-24Q cyclic redundancy chercksum code + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#ifndef _CRC24Q_H_ +#define _CRC24Q_H_ + + +extern void crc24q_sign(unsigned char *data, int len); + +extern bool crc24q_check(unsigned char *data, int len); + +extern unsigned crc24q_hash(unsigned char *data, int len); +#endif /* _CRC24Q_H_ */ diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..bd80b5a --- /dev/null +++ b/debian/changelog @@ -0,0 +1,65 @@ +gpsd (2.95-4slp3) unstable; urgency=low + + * remove wrong copyright file. + * Git: unmodified/gpsd + * Tag: gpsd_2.95-4slp3 + + -- Yunhan Kim Thu, 22 Dec 2011 19:14:18 +0900 + +gpsd (2.95-4slp2) unstable; urgency=low + + * change owenership. + * Git: unmodified/gpsd + * Tag: gpsd_2.95-4slp2 + + -- Yunhan Kim Wed, 07 Dec 2011 13:13:55 +0900 + +gpsd (2.95-3slp2) unstable; urgency=low + + * delete obsolete files + * Git: unmodified/gpsd + * Tag: gpsd_2.95-3slp2 + + -- sangho park Mon, 29 Nov 2010 13:29:28 +0900 + +gpsd (2.95-2slp2) unstable; urgency=low + + * Add debug package + * Git: unmodified/gpsd + * Tag: gpsd_2.95-2slp2 + + -- Tae-Hwan Kim Wed, 24 Nov 2010 23:33:19 +0900 + +gpsd (2.95-1slp2) unstable; urgency=low + + * upgrade to 2.95 + * Git: unmodified/gpsd.git + * Tag: gpsd_2.95-1slp2 + + -- sangho park Fri, 20 Aug 2010 22:16:42 +0900 + +gpsd (2.92-4slp2) unstable; urgency=low + + * force revision for upload + + -- sangho park Fri, 20 Aug 2010 22:16:42 +0900 + +gpsd (2.92-3slp2) unstable; urgency=low + + * fix i386 build break + + -- sangho park Fri, 20 Aug 2010 21:10:55 +0900 + +gpsd (2.92-2slp2) unstable; urgency=low + + * fix strlcat undefined symbols error. + * fix gpsd.so not installed. + * rename libgps17 to libgps19 + + -- sangho park Thu, 19 Aug 2010 10:11:51 +0900 + +gpsd (2.92-1slp2) unstable; urgency=low + + * The first release. + + -- sangho park Thu, 18 Aug 2010 16:51:21 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..1495459 --- /dev/null +++ b/debian/control @@ -0,0 +1,59 @@ +Source: gpsd +Section: misc +Priority: optional +Maintainer: Youngae Kang , Yunhan Kim , Genie Kim , Minjune Kim +Build-Depends: debhelper (>= 5.0.61), po-debconf, dpkg-dev (>= 1.14.8), + dpatch, autotools-dev, + xsltproc, docbook-xsl, docbook-xml, + libxt-dev, libxaw7-dev, libncurses-dev, + libdbus-1-dev, libglib2.0-dev, libdbus-glib-1-dev +Standards-Version: 3.7.2 + +Package: gpsd +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: GPS (Global Positioning System) daemon + gpsd is a service daemon that monitors one or more GPSes attached to a host + computer through serial or USB ports, making all data on the location/course/ + velocity of the sensors available to be queried on TCP port 2947 of the host + computer. + . + With gpsd, multiple GPS client applications can share access to GPSes without + contention or loss of data. Also, gpsd responds to queries with a format that + is substantially easier to parse than the NMEA 0183 emitted by most GPSes. + + +Package: libgps19 +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: C library for communicating with GPS devices + libgps is a service library for querying GPS devices. There are two + interfaces supported by it: + * A high-level interface that goes through gpsd, a service daemon that + monitors one or more GPS devices. It is intended for concurrent use by + several applications. + * A low-level interface that speaks directly with the serial or USB + device to which the GPS is attached. + +Package: libgps-dev +Architecture: any +Section: libdevel +Depends: libgps19 (= ${binary:Version}), ${misc:Depends} +Description: C library for communicating with GPS devices (development files) + libgps is a service library for querying GPS devices. There are two + interfaces supported by it: + * A high-level interface that goes through gpsd, a service daemon that + monitors one or more GPS devices. It is intended for concurrent use by + several applications. + * A low-level interface that speaks directly with the serial or USB + device to which the GPS is attached. + . + This package contains the header and development files needed to build + programs and packages using libgps. + +Package: libgps-dbg +Architecture: any +Section: debug +Depends: ${shlibs:Depends}, ${misc:Depends}, libgps19 (= ${Source-Version}), gpsd +Description: debug package for libgps and gpsd diff --git a/debian/gpsd.install b/debian/gpsd.install new file mode 100644 index 0000000..dde41c6 --- /dev/null +++ b/debian/gpsd.install @@ -0,0 +1 @@ +usr/sbin/* diff --git a/debian/gpsd.postinst b/debian/gpsd.postinst new file mode 100644 index 0000000..2af7145 --- /dev/null +++ b/debian/gpsd.postinst @@ -0,0 +1,21 @@ +#! /bin/sh +# postinst script for gpsd + +set -e + +if [ "$1" = "configure" ] ; then + +mkdir -p /etc/init.d +cat < /etc/init.d/gpsd +# Default settings for gpsd. +# Please do not edit this file directly - use \`dpkg-reconfigure gpsd' to +# change the options. +START_DAEMON="$START_DAEMON" +DAEMON_OPTS="$OPTS" +DEVICES="$DEVICES" +USBAUTO="$USBAUTO" +EOF + +fi + +exit 0 diff --git a/debian/gpsd.preinst b/debian/gpsd.preinst new file mode 100644 index 0000000..532f488 --- /dev/null +++ b/debian/gpsd.preinst @@ -0,0 +1,38 @@ +#! /bin/sh +# preinst script for gpsd +# +# see: dh_installdeb(1) + +set -e + +case "$1" in + install) + ;; + + upgrade) + if dpkg --compare-versions "$2" lt 2.34; then + dpkg-divert --package gpsd --remove --rename \ + --divert /usr/bin/gpsd.gpsdrive /usr/bin/gpsd || true + dpkg-divert --package gpsd --remove --rename \ + --divert /usr/share/man/man1/gpsd.gpsdrive.1.gz \ + /usr/share/man/man1/gpsd.1.gz || true + fi + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/debian/libgps-dev.install b/debian/libgps-dev.install new file mode 100644 index 0000000..c177a1f --- /dev/null +++ b/debian/libgps-dev.install @@ -0,0 +1,4 @@ +usr/include/* +usr/lib/pkgconfig/* +usr/lib/libgps.la +usr/lib/libgps.a diff --git a/debian/libgps19.install b/debian/libgps19.install new file mode 100644 index 0000000..d34bd90 --- /dev/null +++ b/debian/libgps19.install @@ -0,0 +1 @@ +usr/lib/*.so* diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..6b003f3 --- /dev/null +++ b/debian/rules @@ -0,0 +1,122 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +CFLAGS ?= -Wall -g +CXXFLAGS ?= -Wall -g +LDFLAGS ?= +PREFIX ?= /usr +DATADIR ?= /opt + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 + CXXFLAGS += -O0 +else + CFLAGS += -O2 + CXXFLAGS += -O2 +endif + +LDFLAGS += -Wl,-z,defs + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + ./autogen.sh + ./configure --prefix=/usr --disable-python + + touch configure-stamp + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + cat $$f > $${f%.in}; \ + sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ + sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ + done + + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + - $(MAKE) clean + + rm -rf CMakeCache.txt + rm -rf CMakeFiles + rm -rf cmake_install.cmake + rm -rf Makefile + rm -rf install_manifest.txt + rm -rf *.so + rm -f pkgconfig/lbs-location.pc + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + rm -f $${f%.in}; \ + done + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/wavplayer. + $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs +# dh_installdocs + dh_installexamples + dh_install --sourcedir=debian/tmp +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link + dh_strip --dbg-package=libgps-dbg + dh_compress + dh_fixperms +# dh_perl + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..df8eea7 --- /dev/null +++ b/depcomp @@ -0,0 +1,630 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free +# Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/dgpsip-servers b/dgpsip-servers new file mode 100644 index 0000000..00d28aa --- /dev/null +++ b/dgpsip-servers @@ -0,0 +1,10 @@ +# Publicly available DGPS correction servers +# Three fields are: Latitude, longitude, server name[:port] +# Degree fractional parts are decimal, not mmss. They can be approximate, +# as they are only used to find the closest server. +# Some of the data in this file is from the EUREF project page at +# http://www.epncb.oma.be/_organisation/projects/euref_IP/ +# +37.19 -122.39 dgps.wsrcc.com # Pt. Blunt, CA USA +39.14 8.97 glonass.ca.astro.it # Cagliari, Italy +50.01 19.92 gps1.geod.agh.edu.pl # Krakow, Poland diff --git a/do-tests b/do-tests new file mode 100755 index 0000000..0e59945 --- /dev/null +++ b/do-tests @@ -0,0 +1,3 @@ +#!/bin/sh + +${MAKE} testregress PYTHON="$PYTHON" diff --git a/driver_aivdm.c b/driver_aivdm.c new file mode 100644 index 0000000..af0c890 --- /dev/null +++ b/driver_aivdm.c @@ -0,0 +1,842 @@ +/* + * Driver for AIS/AIVDM messages. + * + * See the file AIVDM.txt on the GPSD website for documentation and references. + * + * Code for message types 1-15, 18-21, and 24 has been tested against + * live data with known-good decodings. Code for message types 16-17, + * 22-23, and 25-26 has not. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include + +#include "gpsd.h" +#include "bits.h" + +/** + * Parse the data from the device + */ + +static void from_sixbit(char *bitvec, uint start, int count, char *to) +{ + /*@ +type @*/ +#ifdef S_SPLINT_S + /* the real string causes a splint internal error */ + const char sixchr[] = "abcd"; +#else + const char sixchr[64] = + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^- !\"#$%&'()*+,-./0123456789:;<=>?"; +#endif /* S_SPLINT_S */ + int i; + char newchar; + + /* six-bit to ASCII */ + for (i = 0; i < count - 1; i++) { + newchar = sixchr[ubits(bitvec, start + 6 * i, 6U)]; + if (newchar == '@') + break; + else + to[i] = newchar; + } + to[i] = '\0'; + /* trim spaces on right end */ + for (i = count - 2; i >= 0; i--) + if (to[i] == ' ' || to[i] == '@') + to[i] = '\0'; + else + break; + /*@ -type @*/ +} + +/*@ +charint -fixedformalarray -usedef -branchstate @*/ +bool aivdm_decode(const char *buf, size_t buflen, + struct aivdm_context_t ais_contexts[AIVDM_CHANNELS], + struct ais_t *ais) +{ +#ifdef __UNUSED_DEBUG__ + char *sixbits[64] = { + "000000", "000001", "000010", "000011", "000100", + "000101", "000110", "000111", "001000", "001001", + "001010", "001011", "001100", "001101", "001110", + "001111", "010000", "010001", "010010", "010011", + "010100", "010101", "010110", "010111", "011000", + "011001", "011010", "011011", "011100", "011101", + "011110", "011111", "100000", "100001", "100010", + "100011", "100100", "100101", "100110", "100111", + "101000", "101001", "101010", "101011", "101100", + "101101", "101110", "101111", "110000", "110001", + "110010", "110011", "110100", "110101", "110110", + "110111", "111000", "111001", "111010", "111011", + "111100", "111101", "111110", "111111", + }; +#endif /* __UNUSED_DEBUG__ */ + int nfrags, ifrag, nfields = 0; + unsigned char *field[NMEA_MAX*2]; + unsigned char fieldcopy[NMEA_MAX*2+1]; + unsigned char *data, *cp = fieldcopy; + unsigned char ch, pad; + struct aivdm_context_t *ais_context; + int i; + + if (buflen == 0) + return false; + + /* we may need to dump the raw packet */ + gpsd_report(LOG_PROG, "AIVDM packet length %zd: %s\n", buflen, buf); + + /* first clear the result, making sure we don't return garbage */ + memset(ais, 0, sizeof(*ais)); + + /* discard overlong sentences */ + if (strlen(buf) > sizeof(fieldcopy)-1) { + gpsd_report(LOG_ERROR, "overlong AIVDM packet.\n"); + return false; + } + + /* extract packet fields */ + (void)strlcpy((char *)fieldcopy, buf, sizeof(fieldcopy)); + field[nfields++] = (unsigned char *)buf; + for (cp = fieldcopy; + cp < fieldcopy + buflen; cp++) + if (*cp == ',') { + *cp = '\0'; + field[nfields++] = cp + 1; + } + + /* discard sentences with exiguous commas; catches run-ons */ + if (nfields < 7) { + gpsd_report(LOG_ERROR, "malformed AIVDM packet.\n"); + return false; + } + + switch (field[4][0]) { + /* FIXME: if fields[4] == "12", it doesn't detect the error */ + case '\0': + case '1': + gpsd_report(LOG_ERROR, "invalid AIS channel '%c'. Assuming 'A'\n", + field[4][0]); + /*@fallthrough@*/ + case 'A': + ais_context = &ais_contexts[0]; + break; + case '2': + gpsd_report(LOG_ERROR, "invalid AIS channel '2'. Assuming 'B'.\n"); + /*@fallthrough@*/ + case 'B': + ais_context = &ais_contexts[1]; + break; + default: + gpsd_report(LOG_ERROR, "invalid AIS channel.\n"); + return false; + } + + nfrags = atoi((char *)field[1]); /* number of fragments to expect */ + ifrag = atoi((char *)field[2]); /* fragment id */ + data = field[5]; + pad = field[6][0]; /* number of padding bits */ + gpsd_report(LOG_PROG, "nfrags=%d, ifrag=%d, decoded_frags=%d, data=%s\n", + nfrags, ifrag, ais_context->decoded_frags, data); + + /* assemble the binary data */ + + /* check fragment ordering */ + if (ifrag != ais_context->decoded_frags + 1) { + gpsd_report(LOG_ERROR, "invalid fragment #%d received, expected #%d.\n", + ifrag, ais_context->decoded_frags + 1); + if (ifrag != 1) + return false; + /* else, ifrag==1: Just discard all that was previously decoded and + * simply handle that packet */ + ais_context->decoded_frags = 0; + } + if (ifrag == 1) { + (void)memset(ais_context->bits, '\0', sizeof(ais_context->bits)); + ais_context->bitlen = 0; + } + + /* wacky 6-bit encoding, shades of FIELDATA */ + /*@ +charint @*/ + for (cp = data; cp < data + strlen((char *)data); cp++) { + ch = *cp; + ch -= 48; + if (ch >= 40) + ch -= 8; +#ifdef __UNUSED_DEBUG__ + gpsd_report(LOG_RAW, "%c: %s\n", *cp, sixbits[ch]); +#endif /* __UNUSED_DEBUG__ */ + /*@ -shiftnegative @*/ + for (i = 5; i >= 0; i--) { + if ((ch >> i) & 0x01) { + ais_context->bits[ais_context->bitlen / 8] |= + (1 << (7 - ais_context->bitlen % 8)); + } + ais_context->bitlen++; + } + /*@ +shiftnegative @*/ + } + if (isdigit(pad)) + ais_context->bitlen -= (pad - '0'); /* ASCII assumption */ + /*@ -charint @*/ + + /* time to pass buffered-up data to where it's actually processed? */ + if (ifrag == nfrags) { + size_t clen = (ais_context->bitlen + 7) / 8; + gpsd_report(LOG_INF, "AIVDM payload is %zd bits, %zd chars: %s\n", + ais_context->bitlen, clen, + gpsd_hexdump_wrapper(ais_context->bits, clen, LOG_INF)); + + /* clear waiting fragments count */ + ais_context->decoded_frags = 0; + +#define BITS_PER_BYTE 8 +#define UBITS(s, l) ubits((char *)ais_context->bits, s, l) +#define SBITS(s, l) sbits((char *)ais_context->bits, s, l) +#define UCHARS(s, to) from_sixbit((char *)ais_context->bits, s, sizeof(to), to) + ais->type = UBITS(0, 6); + ais->repeat = UBITS(6, 2); + ais->mmsi = UBITS(8, 30); + gpsd_report(LOG_INF, "AIVDM message type %d, MMSI %09d:\n", + ais->type, ais->mmsi); + /* + * Something about the shape of this switch statement confuses + * GNU indent so badly that there is no point in trying to be + * finer-grained than leaving it all alone. + */ + /* *INDENT-OFF* */ + switch (ais->type) { + case 1: /* Position Report */ + case 2: + case 3: + if (ais_context->bitlen != 168) { + gpsd_report(LOG_WARN, "AIVDM message type %d size not 168 bits (%zd).\n", + ais->type, + ais_context->bitlen); + return false; + } + ais->type1.status = UBITS(38, 4); + ais->type1.turn = SBITS(42, 8); + ais->type1.speed = UBITS(50, 10); + ais->type1.accuracy = (bool)UBITS(60, 1); + ais->type1.lon = SBITS(61, 28); + ais->type1.lat = SBITS(89, 27); + ais->type1.course = UBITS(116, 12); + ais->type1.heading = UBITS(128, 9); + ais->type1.second = UBITS(137, 6); + ais->type1.maneuver = UBITS(143, 2); + //ais->type1.spare = UBITS(145, 3); + ais->type1.raim = UBITS(148, 1)!=0; + ais->type1.radio = UBITS(149, 20); + gpsd_report(LOG_INF, + "Nav=%d TURN=%d SPEED=%d Q=%d Lon=%d Lat=%d COURSE=%d TH=%d Sec=%d\n", + ais->type1.status, + ais->type1.turn, + ais->type1.speed, + (uint)ais->type1.accuracy, + ais->type1.lon, + ais->type1.lat, + ais->type1.course, + ais->type1.heading, + ais->type1.second); + break; + case 4: /* Base Station Report */ + case 11: /* UTC/Date Response */ + if (ais_context->bitlen != 168) { + gpsd_report(LOG_WARN, "AIVDM message type %d size not 168 bits (%zd).\n", + ais->type, + ais_context->bitlen); + return false; + } + ais->type4.year = UBITS(38, 14); + ais->type4.month = UBITS(52, 4); + ais->type4.day = UBITS(56, 5); + ais->type4.hour = UBITS(61, 5); + ais->type4.minute = UBITS(66, 6); + ais->type4.second = UBITS(72, 6); + ais->type4.accuracy = UBITS(78, 1)!=0; + ais->type4.lon = SBITS(79, 28); + ais->type4.lat = SBITS(107, 27); + ais->type4.epfd = UBITS(134, 4); + //ais->type4.spare = UBITS(138, 10); + ais->type4.raim = UBITS(148, 1)!=0; + ais->type4.radio = UBITS(149, 19); + gpsd_report(LOG_INF, + "Date: %4d:%02d:%02dT%02d:%02d:%02d Q=%d Lat=%d Lon=%d epfd=%d\n", + ais->type4.year, + ais->type4.month, + ais->type4.day, + ais->type4.hour, + ais->type4.minute, + ais->type4.second, + (uint)ais->type4.accuracy, + ais->type4.lat, + ais->type4.lon, + ais->type4.epfd); + break; + case 5: /* Ship static and voyage related data */ + if (ais_context->bitlen != 424) { + gpsd_report(LOG_WARN, "AIVDM message type 5 size not 424 bits (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type5.ais_version = UBITS(38, 2); + ais->type5.imo = UBITS(40, 30); + UCHARS(70, ais->type5.callsign); + UCHARS(112, ais->type5.shipname); + ais->type5.shiptype = UBITS(232, 8); + ais->type5.to_bow = UBITS(240, 9); + ais->type5.to_stern = UBITS(249, 9); + ais->type5.to_port = UBITS(258, 6); + ais->type5.to_starboard = UBITS(264, 6); + ais->type5.epfd = UBITS(270, 4); + ais->type5.month = UBITS(274, 4); + ais->type5.day = UBITS(278, 5); + ais->type5.hour = UBITS(283, 5); + ais->type5.minute = UBITS(288, 6); + ais->type5.draught = UBITS(294, 8); + UCHARS(302, ais->type5.destination); + ais->type5.dte = UBITS(422, 1); + //ais->type5.spare = UBITS(423, 1); + gpsd_report(LOG_INF, + "AIS=%d callsign=%s, name=%s destination=%s\n", + ais->type5.ais_version, + ais->type5.callsign, + ais->type5.shipname, + ais->type5.destination); + break; + case 6: /* Addressed Binary Message */ + if (ais_context->bitlen < 88 || ais_context->bitlen > 1008) { + gpsd_report(LOG_WARN, "AIVDM message type 6 size is out of range (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type6.seqno = UBITS(38, 2); + ais->type6.dest_mmsi = UBITS(40, 30); + ais->type6.retransmit = (bool)UBITS(70, 1); + //ais->type6.spare = UBITS(71, 1); + ais->type6.dac = UBITS(72, 10); + ais->type6.fid = UBITS(82, 6); + ais->type6.bitcount = ais_context->bitlen - 88; + (void)memcpy(ais->type6.bitdata, + (char *)ais_context->bits + (88 / BITS_PER_BYTE), + (ais->type6.bitcount + 7) / 8); + gpsd_report(LOG_INF, "seqno=%d, dest=%u, dac=%u, fid=%u, cnt=%zd\n", + ais->type6.seqno, + ais->type6.dest_mmsi, + ais->type6.dac, + ais->type6.fid, + ais->type6.bitcount); + break; + case 7: /* Binary acknowledge */ + case 13: /* Safety Related Acknowledge */ + { + unsigned int mmsi[4]; + if (ais_context->bitlen < 72 || ais_context->bitlen > 168) { + gpsd_report(LOG_WARN, "AIVDM message type %d size is out of range (%zd).\n", + ais->type, + ais_context->bitlen); + return false; + } + for (i = 0; i < sizeof(mmsi)/sizeof(mmsi[0]); i++) + if (ais_context->bitlen > 40 + 32*i) + mmsi[i] = UBITS(40 + 32*i, 30); + else + mmsi[i] = 0; + /*@ -usedef @*/ + ais->type7.mmsi1 = mmsi[0]; + ais->type7.mmsi2 = mmsi[1]; + ais->type7.mmsi3 = mmsi[2]; + ais->type7.mmsi4 = mmsi[3]; + /*@ +usedef @*/ + gpsd_report(LOG_INF, "\n"); + break; + } + case 8: /* Binary Broadcast Message */ + if (ais_context->bitlen < 56 || ais_context->bitlen > 1008) { + gpsd_report(LOG_WARN, "AIVDM message type 8 size is out of range (%zd).\n", + ais_context->bitlen); + return false; + } + //ais->type8.spare = UBITS(38, 2); + ais->type8.dac = UBITS(40, 10); + ais->type8.fid = UBITS(40, 6); + ais->type8.bitcount = ais_context->bitlen - 56; + (void)memcpy(ais->type8.bitdata, + (char *)ais_context->bits + (56 / BITS_PER_BYTE), + (ais->type8.bitcount + 7) / 8); + gpsd_report(LOG_INF, "dac=%u, fid=%u, cnt=%zd\n", + ais->type8.dac, + ais->type8.fid, + ais->type8.bitcount); + break; + case 9: /* Standard SAR Aircraft Position Report */ + if (ais_context->bitlen != 168) { + gpsd_report(LOG_WARN, "AIVDM message type 9 size not 168 bits (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type9.alt = UBITS(38, 12); + ais->type9.speed = UBITS(50, 10); + ais->type9.accuracy = (bool)UBITS(60, 1); + ais->type9.lon = SBITS(61, 28); + ais->type9.lat = SBITS(89, 27); + ais->type9.course = UBITS(116, 12); + ais->type9.second = UBITS(128, 6); + ais->type9.regional = UBITS(134, 8); + ais->type9.dte = UBITS(142, 1); + //ais->type9.spare = UBITS(143, 3); + ais->type9.assigned = UBITS(146, 1)!=0; + ais->type9.raim = UBITS(147, 1)!=0; + ais->type9.radio = UBITS(148, 19); + gpsd_report(LOG_INF, + "Alt=%d SPEED=%d Q=%d Lon=%d Lat=%d COURSE=%d Sec=%d\n", + ais->type9.alt, + ais->type9.speed, + (uint)ais->type9.accuracy, + ais->type9.lon, + ais->type9.lat, + ais->type9.course, + ais->type9.second); + break; + case 10: /* UTC/Date inquiry */ + if (ais_context->bitlen != 72) { + gpsd_report(LOG_WARN, "AIVDM message type 10 size not 72 bits (%zd).\n", + ais_context->bitlen); + return false; + } + //ais->type10.spare = UBITS(38, 2); + ais->type10.dest_mmsi = UBITS(40, 30); + //ais->type10.spare2 = UBITS(70, 2); + gpsd_report(LOG_INF, "dest=%u\n", ais->type10.dest_mmsi); + break; + case 12: /* Safety Related Message */ + if (ais_context->bitlen < 72 || ais_context->bitlen > 1008) { + gpsd_report(LOG_WARN, "AIVDM message type 12 size is out of range (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type12.seqno = UBITS(38, 2); + ais->type12.dest_mmsi = UBITS(40, 30); + ais->type12.retransmit = (bool)UBITS(70, 1); + //ais->type12.spare = UBITS(71, 1); + from_sixbit((char *)ais_context->bits, + 72, ais_context->bitlen-72, + ais->type12.text); + gpsd_report(LOG_INF, "seqno=%d, dest=%u\n", + ais->type12.seqno, + ais->type12.dest_mmsi); + break; + case 14: /* Safety Related Broadcast Message */ + if (ais_context->bitlen < 40 || ais_context->bitlen > 1008) { + gpsd_report(LOG_WARN, "AIVDM message type 14 size is out of range (%zd).\n", + ais_context->bitlen); + return false; + } + //ais->type14.spare = UBITS(38, 2); + from_sixbit((char *)ais_context->bits, + 40, ais_context->bitlen-40, + ais->type14.text); + gpsd_report(LOG_INF, "\n"); + break; + case 15: /* Interrogation */ + if (ais_context->bitlen < 88 || ais_context->bitlen > 168) { + gpsd_report(LOG_WARN, "AIVDM message type 15 size is out of range (%zd).\n", + ais_context->bitlen); + return false; + } + (void)memset(&ais->type15, '\0', sizeof(ais->type15)); + //ais->type14.spare = UBITS(38, 2); + ais->type15.mmsi1 = UBITS(40, 30); + ais->type15.type1_1 = UBITS(70, 6); + ais->type15.type1_1 = UBITS(70, 6); + ais->type15.offset1_1 = UBITS(76, 12); + //ais->type14.spare2 = UBITS(88, 2); + if (ais_context->bitlen > 90) { + ais->type15.type1_2 = UBITS(90, 6); + ais->type15.offset1_2 = UBITS(96, 12); + //ais->type14.spare3 = UBITS(108, 2); + if (ais_context->bitlen > 110) { + ais->type15.mmsi2 = UBITS(110, 30); + ais->type15.type2_1 = UBITS(140, 6); + ais->type15.offset2_1 = UBITS(146, 12); + //ais->type14.spare4 = UBITS(158, 2); + } + } + gpsd_report(LOG_INF, "\n"); + break; + case 16: /* Assigned Mode Command */ + if (ais_context->bitlen != 96 && ais_context->bitlen != 144) { + gpsd_report(LOG_WARN, "AIVDM message type 16 size is out of range (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type16.mmsi1 = UBITS(40, 30); + ais->type16.offset1 = UBITS(70, 12); + ais->type16.increment1 = UBITS(82, 10); + if (ais_context->bitlen < 144) + ais->type16.mmsi2=ais->type16.offset2=ais->type16.increment2 = 0; + else { + ais->type16.mmsi2 = UBITS(92, 30); + ais->type16.offset2 = UBITS(122, 12); + ais->type16.increment2 = UBITS(134, 10); + } + gpsd_report(LOG_INF, "\n"); + break; + case 17: /* GNSS Broadcast Binary Message */ + if (ais_context->bitlen < 80 || ais_context->bitlen > 816) { + gpsd_report(LOG_WARN, "AIVDM message type 17 size is out of range (%zd).\n", + ais_context->bitlen); + return false; + } + //ais->type17.spare = UBITS(38, 2); + ais->type17.lon = UBITS(40, 18); + ais->type17.lat = UBITS(58, 17); + //ais->type17.spare = UBITS(75, 4); + ais->type17.bitcount = ais_context->bitlen - 80; + (void)memcpy(ais->type17.bitdata, + (char *)ais_context->bits + (80 / BITS_PER_BYTE), + (ais->type17.bitcount + 7) / 8); + gpsd_report(LOG_INF, "\n"); + break; + case 18: /* Standard Class B CS Position Report */ + if (ais_context->bitlen != 168) { + gpsd_report(LOG_WARN, "AIVDM message type 18 size not 168 bits (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type18.reserved = UBITS(38, 8); + ais->type18.speed = UBITS(46, 10); + ais->type18.accuracy = UBITS(56, 1)!=0; + ais->type18.lon = SBITS(57, 28); + ais->type18.lat = SBITS(85, 27); + ais->type18.course = UBITS(112, 12); + ais->type18.heading = UBITS(124, 9); + ais->type18.second = UBITS(133, 6); + ais->type18.regional = UBITS(139, 2); + ais->type18.cs = UBITS(141, 1)!=0; + ais->type18.display = UBITS(142, 1)!=0; + ais->type18.dsc = UBITS(143, 1)!=0; + ais->type18.band = UBITS(144, 1)!=0; + ais->type18.msg22 = UBITS(145, 1)!=0; + ais->type18.assigned = UBITS(146, 1)!=0; + ais->type18.raim = UBITS(147, 1)!=0; + ais->type18.radio = UBITS(148, 20); + gpsd_report(LOG_INF, + "reserved=%d speed=%d accuracy=%d lon=%d lat=%d course=%d heading=%d sec=%d\n", + ais->type18.reserved, + ais->type18.speed, + (uint)ais->type18.accuracy, + ais->type18.lon, + ais->type18.lat, + ais->type18.course, + ais->type18.heading, + ais->type18.second); + break; + case 19: /* Extended Class B CS Position Report */ + if (ais_context->bitlen != 312) { + gpsd_report(LOG_WARN, "AIVDM message type 19 size not 312 bits (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type19.reserved = UBITS(38, 8); + ais->type19.speed = UBITS(46, 10); + ais->type19.accuracy = UBITS(56, 1)!=0; + ais->type19.lon = SBITS(57, 28); + ais->type19.lat = SBITS(85, 27); + ais->type19.course = UBITS(112, 12); + ais->type19.heading = UBITS(124, 9); + ais->type19.second = UBITS(133, 6); + ais->type19.regional = UBITS(139, 4); + UCHARS(143, ais->type19.shipname); + ais->type19.shiptype = UBITS(263, 8); + ais->type19.to_bow = UBITS(271, 9); + ais->type19.to_stern = UBITS(280, 9); + ais->type19.to_port = UBITS(289, 6); + ais->type19.to_starboard = UBITS(295, 6); + ais->type19.epfd = UBITS(299, 4); + ais->type19.raim = UBITS(302, 1)!=0; + ais->type19.dte = UBITS(305, 1)!=0; + ais->type19.assigned = UBITS(306, 1)!=0; + //ais->type19.spare = UBITS(307, 5); + gpsd_report(LOG_INF, + "reserved=%d speed=%d accuracy=%d lon=%d lat=%d course=%d heading=%d sec=%d name=%s\n", + ais->type19.reserved, + ais->type19.speed, + (uint)ais->type19.accuracy, + ais->type19.lon, + ais->type19.lat, + ais->type19.course, + ais->type19.heading, + ais->type19.second, + ais->type19.shipname); + break; + case 20: /* Data Link Management Message */ + if (ais_context->bitlen < 72 || ais_context->bitlen > 160) { + gpsd_report(LOG_WARN, "AIVDM message type 20 size is out of range (%zd).\n", + ais_context->bitlen); + return false; + } + //ais->type20.spare = UBITS(38, 2); + ais->type20.offset1 = UBITS(40, 12); + ais->type20.number1 = UBITS(52, 4); + ais->type20.timeout1 = UBITS(56, 3); + ais->type20.increment1 = UBITS(59, 11); + ais->type20.offset2 = UBITS(70, 12); + ais->type20.number2 = UBITS(82, 4); + ais->type20.timeout2 = UBITS(86, 3); + ais->type20.increment2 = UBITS(89, 11); + ais->type20.offset3 = UBITS(100, 12); + ais->type20.number3 = UBITS(112, 4); + ais->type20.timeout3 = UBITS(116, 3); + ais->type20.increment3 = UBITS(119, 11); + ais->type20.offset4 = UBITS(130, 12); + ais->type20.number4 = UBITS(142, 4); + ais->type20.timeout4 = UBITS(146, 3); + ais->type20.increment4 = UBITS(149, 11); + break; + case 21: /* Aid-to-Navigation Report */ + if (ais_context->bitlen < 272 || ais_context->bitlen > 360) { + gpsd_report(LOG_WARN, "AIVDM message type 21 size is out of range (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type21.aid_type = UBITS(38, 5); + from_sixbit((char *)ais_context->bits, + 43, 21, ais->type21.name); + if (strlen(ais->type21.name) == 20 && ais_context->bitlen > 272) + from_sixbit((char *)ais_context->bits, + 272, (ais_context->bitlen - 272)/6, + ais->type21.name+20); + ais->type21.accuracy = UBITS(163, 1); + ais->type21.lon = SBITS(164, 28); + ais->type21.lat = SBITS(192, 27); + ais->type21.to_bow = UBITS(219, 9); + ais->type21.to_stern = UBITS(228, 9); + ais->type21.to_port = UBITS(237, 6); + ais->type21.to_starboard = UBITS(243, 6); + ais->type21.epfd = UBITS(249, 4); + ais->type21.second = UBITS(253, 6); + ais->type21.off_position = UBITS(259, 1)!=0; + ais->type21.regional = UBITS(260, 8); + ais->type21.raim = UBITS(268, 1)!=0; + ais->type21.virtual_aid = UBITS(269, 1)!=0; + ais->type21.assigned = UBITS(270, 1)!=0; + //ais->type21.spare = UBITS(271, 1); + gpsd_report(LOG_INF, + "name=%s accuracy=%d lon=%d lat=%d sec=%d\n", + ais->type21.name, + (uint)ais->type19.accuracy, + ais->type19.lon, + ais->type19.lat, + ais->type19.second); + break; + case 22: /* Channel Management */ + if (ais_context->bitlen != 168) { + gpsd_report(LOG_WARN, "AIVDM message type 22 size not 168 bits (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type22.channel_a = UBITS(40, 12); + ais->type22.channel_b = UBITS(52, 12); + ais->type22.txrx = UBITS(64, 4); + ais->type22.power = UBITS(68, 1); + ais->type22.addressed = UBITS(139, 1); + if (!ais->type22.addressed) { + ais->type22.area.ne_lon = SBITS(69, 18); + ais->type22.area.ne_lat = SBITS(87, 17); + ais->type22.area.sw_lon = SBITS(104, 18); + ais->type22.area.sw_lat = SBITS(122, 17); + } else { + ais->type22.mmsi.dest1 = SBITS(69, 30); + ais->type22.mmsi.dest2 = SBITS(104, 30); + } + ais->type22.band_a = UBITS(140, 1); + ais->type22.band_b = UBITS(141, 1); + ais->type22.zonesize = UBITS(142, 3); + break; + case 23: /* Group Assignment Command */ + if (ais_context->bitlen != 160) { + gpsd_report(LOG_WARN, "AIVDM message type 23 size not 160 bits (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type23.ne_lon = SBITS(40, 18); + ais->type23.ne_lat = SBITS(58, 17); + ais->type23.sw_lon = SBITS(75, 18); + ais->type23.sw_lat = SBITS(93, 17); + ais->type23.stationtype = UBITS(110, 4); + ais->type23.shiptype = UBITS(114, 8); + ais->type23.txrx = UBITS(144, 4); + ais->type23.interval = UBITS(146, 4); + ais->type23.quiet = UBITS(150, 4); + break; + case 24: /* Class B CS Static Data Report */ + switch (UBITS(38, 2)) { + case 0: + if (ais_context->bitlen != 160) { + gpsd_report(LOG_WARN, "AIVDM message type 24A size not 160 bits (%zd).\n", + ais_context->bitlen); + return false; + } + if (ais_context->mmsi24) { + gpsd_report(LOG_WARN, + "AIVDM message type 24 collision on channel %c : Discarding previous sentence 24A from %09u.\n", + field[4][0], + ais_context->mmsi24); + /* no return false */ + } + ais_context->mmsi24 = ais->mmsi; + UCHARS(40, ais_context->shipname24); + //ais->type24.a.spare = UBITS(160, 8); + gpsd_report(LOG_INF, "subtype=A name=%s\n", + ais_context->shipname24); + return false; /* data only partially decoded */ + case 1: + if (ais_context->bitlen != 168) { + gpsd_report(LOG_WARN, "AIVDM message type 24B size not 168 bits (%zd).\n", + ais_context->bitlen); + return false; + } + if (ais_context->mmsi24 != ais->mmsi) { + if (ais_context->mmsi24) + gpsd_report(LOG_WARN, + "AIVDM message type 24 collision on channel %c: MMSI mismatch: %09u vs %09u.\n", + field[4][0], + ais_context->mmsi24, ais->mmsi); + else + gpsd_report(LOG_WARN, + "AIVDM message type 24 collision on channel %c: 24B sentence from %09u without 24A.\n", + field[4][0], + ais->mmsi); + return false; + } + (void)strlcpy(ais->type24.shipname, + ais_context->shipname24, + sizeof(ais_context->shipname24)); + ais->type24.shiptype = UBITS(40, 8); + UCHARS(48, ais->type24.vendorid); + UCHARS(90, ais->type24.callsign); + if (AIS_AUXILIARY_MMSI(ais->mmsi)) { + ais->type24.mothership_mmsi = UBITS(132, 30); + gpsd_report(LOG_INF, + "subtype=B subsubtype=aux " + "shiptype=%u vendor=%s callsign=%s " + "mothership=%09u\n", + ais->type24.shiptype, ais->type24.vendorid, ais->type24.callsign, + ais->type24.mothership_mmsi); + } else { + ais->type24.dim.to_bow = UBITS(132, 9); + ais->type24.dim.to_stern = UBITS(141, 9); + ais->type24.dim.to_port = UBITS(150, 6); + ais->type24.dim.to_starboard = UBITS(156, 6); + gpsd_report(LOG_INF, + "subtype=B subsubtype=dim " + "shiptype=%u vendor=%s callsign=%s " + "bow=%u stern=%u port=%u starboard=%u\n", + ais->type24.shiptype, ais->type24.vendorid, ais->type24.callsign, + ais->type24.dim.to_bow, ais->type24.dim.to_stern, + ais->type24.dim.to_port, ais->type24.dim.to_starboard); + } + //ais->type24.b.spare = UBITS(162, 8); + ais_context->mmsi24 = 0; /* reset last know 24A for collision detection */ + break; + default: + gpsd_report(LOG_WARN, "AIVDM message type 24 of subtype unknown.\n"); + gpsd_report(LOG_INF, "\n"); + return false; + } + break; + case 25: /* Binary Message, Single Slot */ + /* this check and the following one reject line noise */ + if (ais_context->bitlen < 40 || ais_context->bitlen > 168) { + gpsd_report(LOG_WARN, "AIVDM message type 25 size not between 40 to 168 bits (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type25.addressed = (bool)UBITS(38, 1); + ais->type25.structured = (bool)UBITS(39, 1); + if (ais_context->bitlen < (40 + (16*ais->type25.structured) + (30*ais->type25.addressed))) { + gpsd_report(LOG_WARN, "AIVDM message type 25 too short for mode.\n"); + return false; + } + if (ais->type25.addressed) + ais->type25.dest_mmsi = UBITS(40, 30); + if (ais->type25.structured) + ais->type25.app_id = UBITS(40+ais->type25.addressed*30,16); + /* + * Not possible to do this right without machinery we + * don't yet have. The problem is that if the addressed + * bit is on the bitfield start won't be on a byte + * boundary. Thus the formulas below (and in message type 26) + * will work perfectly for brodacst messages, but for addressed + * messages the retrieved data will be led by thr 30 bits of + * the destination MMSI + */ + ais->type25.bitcount = ais_context->bitlen - 40 - 16*ais->type25.structured; + (void)memcpy(ais->type25.bitdata, + (char *)ais_context->bits+5 + 2 * ais->type25.structured, + (ais->type25.bitcount + 7) / 8); + gpsd_report(LOG_INF, "addressed=%d, structured=%d, dest=%u, id=%u, cnt=%zd\n", + ais->type25.addressed, + ais->type25.structured, + ais->type25.dest_mmsi, + ais->type25.app_id, + ais->type25.bitcount); + break; + case 26: /* Binary Message, Multiple Slot */ + if (ais_context->bitlen < 60 || ais_context->bitlen > 1004) { + gpsd_report(LOG_WARN, "AIVDM message type 26 size is out of range (%zd).\n", + ais_context->bitlen); + return false; + } + ais->type26.addressed = (bool)UBITS(38, 1); + ais->type26.structured = (bool)UBITS(39, 1); + if (ais->type26.addressed) + ais->type26.dest_mmsi = UBITS(40, 30); + if (ais->type26.structured) + ais->type26.app_id = UBITS(40+ais->type26.addressed*30,16); + ais->type26.bitcount = ais_context->bitlen - 60 - 16*ais->type26.structured; + (void)memcpy(ais->type26.bitdata, + (char *)ais_context->bits+5 + 2 * ais->type26.structured, + (ais->type26.bitcount + 7) / 8); + gpsd_report(LOG_INF, "addressed=%d, structured=%d, dest=%u, id=%u, cnt=%zd\n", + ais->type26.addressed, + ais->type26.structured, + ais->type26.dest_mmsi, + ais->type26.app_id, + ais->type26.bitcount); + break; + default: + gpsd_report(LOG_INF, "\n"); + gpsd_report(LOG_ERROR, "Unparsed AIVDM message type %d.\n",ais->type); + return false; + } + /* *INDENT-ON* */ +#undef UCHARS +#undef SBITS +#undef UBITS +#undef BITS_PER_BYTE + + /* data is fully decoded */ + return true; + } + + /* we're still waiting on another sentence */ + ais_context->decoded_frags++; + return false; +} + +/*@ -charint +fixedformalarray +usedef +branchstate @*/ + +/* driver_aivdm.c ends here */ diff --git a/driver_evermore.c b/driver_evermore.c new file mode 100644 index 0000000..39706fa --- /dev/null +++ b/driver_evermore.c @@ -0,0 +1,645 @@ +/* + * + * This is the gpsd driver for EverMore GPSes operating in binary mode. + * About the only thing this gives us that NMEA won't is TDOP. + * But we'll get atomic position reports from it, which is good. + * + * The vendor site is . + * + * This driver was written by Petr Slansky based on a framework by Eric S. + * Raymond. The following remarks are by Petr Slansky. + * + * Snooping on the serial the communication between a Windows program and + * an Evermore chipset reveals some messages not described in the vendor + * documentation (Issue C of Aug 2002): + * + * 10 02 06 84 00 00 00 84 10 03 switch to binary mode (84 00 00 00) + * 10 02 06 84 01 00 00 85 10 03 switch to NMEA mode (84 01 00 00) + * + * 10 02 06 89 01 00 00 8a 10 03 set baud rate 4800 + * 10 02 06 89 01 01 00 8b 10 03 set baud rate 9600 + * 10 02 06 89 01 02 00 8c 10 03 set baud rate 19200 + * 10 02 06 89 01 03 00 8d 10 03 set baud rate 38400 + * + * 10 02 06 8D 00 01 00 8E 10 03 switch to datum ID 001 (WGS-84) + * 10 02 06 8D 00 D8 00 65 10 03 switch to datum ID 217 (WGS-72) + * + * These don't entail a reset of GPS as the 0x80 message does. + * + * 10 02 04 38 85 bd 10 03 answer from GPS to 0x85 message; ACK message + * 10 02 04 38 8d c5 10 03 answer from GPS to 0x8d message; ACK message + * 10 02 04 38 8e c6 10 03 answer from GPS to 0x8e message; ACK message + * 10 02 04 38 8f c7 10 03 answer from GPS to 0x8f message; ACK message + * + * The chip sometimes sends vendor extension messages with the prefix + * $PEMT,100. After restart, it sends a $PEMT,100 message describing the + * chip's configuration. Here is a sample: + * + * $PEMT,100,05.42g,100303,180,05,1,20,15,08,0,0,2,1*5A + * 100 - message type + * 05.42g - firmware version + * 100303 - date of firmware release DDMMYY + * 180 - datum ID; 001 is WGS-84 + * 05 - default elevation mask; see message 0x86 + * 1 - default DOP select (1 is auto DOP mask); see message 0x87 + * 20 - default GDOP; see message 0x87 + * 15 - default PDOP + * 08 - default HDOP + * 0 - Normal mode, without 1PPS + * 0 - default position pinning control (0 disable, 1 enable) + * 2 - altitude hold mode (0 disable, 1 always, 2 auto) + * 1 - 2/1 satellite nav mode (0,1,2,3,4) + * 0 disable 2/1 sat nav mode + * 1 hold direction (2 sat) + * 2 clock hold only (2 sat) + * 3 direction hold then clock hold (1 sat) + * 4 clock hold then direction hold (1 sat) + * + * Message $PEMT,100 could be forced with message 0x85 (restart): + * 10 02 12 85 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 87 10 03 + * 0x85 ID, Restart + * 0x00 restart mode (0 default, 1 hot, 2 warm, 3 cold, 4 test) + * 0x00 test start search PRN (1-32) + * 0x00 UTC second (0-59) + * 0x00 UTC Minute (0-59) + * 0x00 UTC Hour (0-23) + * 0x01 UTC Day (1-31) + * 0x01 UTC Month (1-12) + * 0x0000 UTC year (1980+x, uint16) + * 0x0000 Latitude WGS-84 (+/-900, 1/10 degree, + for N, int16) + * 0x0000 Longtitude WGS-84 (+/-1800, 1/10 degree, + for E, int16) + * 0x0000 Altitude WGS-84 (-1000..+18000, meters, int16) + * 0x87 CRC + * + * With message 0x8e it is possible to define how often each NMEA + * message is sent (0-255 seconds). It is possible with message 0x8e + * to activate PEMT,101 messages that have information about time, + * position, velocity and HDOP. + * + * $PEMT,101,1,02,00.0,300906190446,5002.5062,N,01427.6166,E,00259,000,0000*27 + * $PEMT,101,2,06,02.1,300906185730,5002.7546,N,01426.9524,E,00323,020,0011*26 + * 101 - message type, Compact Navigation Solution + * 2 - position status (1,2,3,4,5,6) + * (1 invalid, 2 2D fix, 3 3D fix, 4 2D with DIFF, 5 3D with DIFF, + * 6 2/1 sat degrade mode) + * 06 - number of used satelites + * 02.1 - DOP (00.0 no fix, HDOP 2D fix, PDOP 3D fix) + * 300906185730 - date and time, UTC ddmmyyHHMMSS (30/09/2006 18:57:30) + * 5002.7546,N - Latitude (degree) + * 01426.9524,E - Longitude (degree) + * 00323 - Altitude (323 metres) + * 020 - heading (20 degrees from true north) + * 0011 - speed over ground (11 metres per second); documentation says km per h + * + * This is an exampe of an 0x8e message that activates all NMEA sentences + * with 1s period: + * 10 02 12 8E 7F 01 01 01 01 01 01 01 01 00 00 00 00 00 00 15 10 03 + * + * There is a way to probe for this chipset. When binary message 0x81 is sent: + * 10 02 04 81 13 94 10 03 + * + * EverMore will reply with message like this: + * *10 *02 *0D *20 E1 00 00 *00 0A 00 1E 00 32 00 5B *10 *03 + * bytes marked with * are fixed + * Message in reply is information about logging configuration of GPS + * + * Another way to detect the EverMore chipset is to send one of the messages + * 0x85, 0x8d, 0x8e or 0x8f and check for a reply. + * The reply message from an EverMore GPS will look like this: + * *10 *02 *04 *38 8d c5 *10 *03 + * 8d indicates that message 0x8d was sent; + * c5 is EverMore checksum, other bytes are fixed + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#include +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include + +#include "gpsd.h" +#if defined(EVERMORE_ENABLE) && defined(BINARY_ENABLE) + +#define GET_ORIGIN 1 +#define PUT_ORIGIN 0 +#include "bits.h" + +#define EVERMORE_CHANNELS 12 + +/*@ +charint @*/ +gps_mask_t evermore_parse(struct gps_device_t * session, unsigned char *buf, + size_t len) +{ + unsigned char buf2[MAX_PACKET_LENGTH], *cp, *tp; + size_t i, datalen; + unsigned int type, used, visible, satcnt, j, k; + double version; + gps_mask_t mask = 0; + + if (len == 0) + return 0; + + /* time to unstuff it and discard the header and footer */ + cp = buf + 2; + tp = buf2; + if (*cp == 0x10) + cp++; + datalen = (size_t) * cp++; + + gpsd_report(LOG_RAW, "raw EverMore packet type 0x%02x, length %zd: %s\n", + *cp, len, gpsd_hexdump_wrapper(buf, len, LOG_RAW)); + + datalen -= 2; + + /*@ -usedef @*/ + for (i = 0; i < (size_t) datalen; i++) { + *tp = *cp++; + if (*tp == 0x10) + cp++; + tp++; + } + + type = (unsigned char)getub(buf2, 1); + /*@ +usedef @*/ + + /*@ -usedef -compdef @*/ + gpsd_report(LOG_RAW, "EverMore packet type 0x%02x, length %zd: %s\n", + type, datalen, gpsd_hexdump_wrapper(buf2, datalen, LOG_RAW)); + /*@ +usedef +compdef @*/ + + (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), + "EID%u", type); + + session->cycle_end_reliable = true; + + switch (type) { + case 0x02: /* Navigation Data Output */ + session->context->gps_week = (unsigned short)getleuw(buf2, 2); + session->context->gps_tow = (double)getleul(buf2, 4) * 0.01; + /*@ ignore @*//*@ splint is confused @ */ + session->newdata.time = + gpstime_to_unix(session->context->gps_week, + session->context->gps_tow) - + session->context->leap_seconds; + /*@ end @*/ + ecef_to_wgs84fix(&session->newdata, &session->gpsdata.separation, + getlesl(buf2, 8) * 1.0, getlesl(buf2, 12) * 1.0, + getlesl(buf2, 16) * 1.0, getlesw(buf2, 20) / 10.0, + getlesw(buf2, 22) / 10.0, getlesw(buf2, 24) / 10.0); + used = (unsigned char)getub(buf2, 26) & 0x0f; + //visible = (getub(buf2, 26) & 0xf0) >> 4; + version = (uint) getleuw(buf2, 27) / 100.0; + /* that's all the information in this packet */ + if (used < 3) + session->newdata.mode = MODE_NO_FIX; + else if (used == 3) + session->newdata.mode = MODE_2D; + else { + session->newdata.mode = MODE_3D; + mask |= ALTITUDE_IS | CLIMB_IS; + } + mask |= TIME_IS | LATLON_IS | TRACK_IS | SPEED_IS | MODE_IS; + if (session->subtype[0] == '\0') { + (void)snprintf(session->subtype, sizeof(session->subtype), + "%3.2f", version); + mask |= DEVICEID_IS; + } + gpsd_report(LOG_DATA, + "NDO 0x02: time=%.2f, lat=%.2f lon=%.2f alt=%.2f speed=%.2f track=%.2f climb=%.2f mode=%d subtype='%s' mask=%s\n", + session->newdata.time, session->newdata.latitude, + session->newdata.longitude, session->newdata.altitude, + session->newdata.speed, session->newdata.track, + session->newdata.climb, session->newdata.mode, + session->gpsdata.dev.subtype, gpsd_maskdump(mask)); + return mask | CLEAR_IS | REPORT_IS; + + case 0x04: /* DOP Data Output */ + session->context->gps_week = (unsigned short)getleuw(buf2, 2); + session->context->gps_tow = (double)getleul(buf2, 4) * 0.01; + /*@ ignore @*//*@ splint is confused @ */ + session->newdata.time = + gpstime_to_unix(session->context->gps_week, + session->context->gps_tow) - + session->context->leap_seconds; + /*@ end @*/ + /* + * We make a deliberate choice not to clear DOPs from the + * last skyview here, but rather to treat this as a supplement + * to our calculations from the visiniolity matrix, trusting + * the firmware algorithms over ours. + */ + session->gpsdata.dop.gdop = (double)getub(buf2, 8) * 0.1; + session->gpsdata.dop.pdop = (double)getub(buf2, 9) * 0.1; + session->gpsdata.dop.hdop = (double)getub(buf2, 10) * 0.1; + session->gpsdata.dop.vdop = (double)getub(buf2, 11) * 0.1; + session->gpsdata.dop.tdop = (double)getub(buf2, 12) * 0.1; + switch (getub(buf2, 13)) { + case 0: /* no position fix */ + case 1: /* manual calls this "1D navigation" */ + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + break; + case 2: /* 2D navigation */ + session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_2D; + break; + case 3: /* 3D navigation */ + session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_3D; + break; + case 4: /* 3D navigation with DGPS */ + session->gpsdata.status = STATUS_DGPS_FIX; + session->newdata.mode = MODE_3D; + break; + } + /* that's all the information in this packet */ + mask = TIME_IS | DOP_IS | MODE_IS | STATUS_IS; + gpsd_report(LOG_DATA, + "DDO 0x04: gdop=%.2f pdop=%.2f hdop=%.2f vdop=%.2f tdop=%.2f mode=%d, status=%d mask={TIME| DOP|MODE|STATUS}\n", + session->gpsdata.dop.gdop, session->gpsdata.dop.pdop, + session->gpsdata.dop.hdop, session->gpsdata.dop.vdop, + session->gpsdata.dop.tdop, session->newdata.mode, + session->gpsdata.status); + return mask; + + case 0x06: /* Channel Status Output */ + session->context->gps_week = (unsigned short)getleuw(buf2, 2); + session->context->gps_tow = (double)getleul(buf2, 4) * 0.01; + /*@ ignore @*//*@ splint is confused @ */ + session->gpsdata.skyview_time = + gpstime_to_unix(session->context->gps_week, + session->context->gps_tow) - + session->context->leap_seconds; + /*@ end @*/ + session->gpsdata.satellites_visible = (int)getub(buf2, 8); + gpsd_zero_satellites(&session->gpsdata); + memset(session->gpsdata.used, 0, sizeof(session->gpsdata.used)); + if (session->gpsdata.satellites_visible > 12) { + gpsd_report(LOG_WARN, + "Warning: EverMore packet has information about %d satellites!\n", + session->gpsdata.satellites_visible); + } + if (session->gpsdata.satellites_visible > EVERMORE_CHANNELS) + session->gpsdata.satellites_visible = EVERMORE_CHANNELS; + satcnt = 0; + for (i = 0; i < (size_t) session->gpsdata.satellites_visible; i++) { + int prn; + // channel = getub(buf2, 7*i+7+2) + prn = (int)getub(buf2, 7 * i + 7 + 3); + if (prn == 0) + continue; /* satellite record is not valid */ + session->gpsdata.PRN[satcnt] = prn; + session->gpsdata.azimuth[satcnt] = + (int)getleuw(buf2, 7 * i + 7 + 4); + session->gpsdata.elevation[satcnt] = + (int)getub(buf2, 7 * i + 7 + 6); + session->gpsdata.ss[satcnt] = (float)getub(buf2, 7 * i + 7 + 7); + /* + * Status bits at offset 8: + * bit0 = 1 satellite acquired + * bit1 = 1 code-tracking loop locked + * bit2 = 1 carrier-tracking loop locked + * bit3 = 1 data-bit synchronization done + * bit4 = 1 frame synchronization done + * bit5 = 1 ephemeris data collected + * bit6 = 1 used for position fix + */ + if (getub(buf2, 7 * i + 7 + 8) & 0x40) { + session->gpsdata.used[session->gpsdata.satellites_used++] = + prn; + } + + satcnt++; + } + session->gpsdata.satellites_visible = (int)satcnt; + /* that's all the information in this packet */ + mask = SATELLITE_IS | USED_IS; + gpsd_report(LOG_DATA, + "CSO 0x06: time=%.2f used=%d visible=%d mask={TIME|SATELLITE|USED}\n", + session->newdata.time, session->gpsdata.satellites_used, + session->gpsdata.satellites_visible); + return mask; + + case 0x08: /* Measurement Data Output */ + /* clock offset is a manufacturer diagnostic */ + /* (int)getleuw(buf2, 8); clock offset, 29000..29850 ?? */ + session->context->gps_week = (unsigned short)getleuw(buf2, 2); + session->context->gps_tow = (double)getleul(buf2, 4) * 0.01; + /*@ ignore @*//*@ splint is confused @ */ + session->newdata.time = + gpstime_to_unix(session->context->gps_week, + session->context->gps_tow) - + session->context->leap_seconds; + /*@ end @*/ + visible = (unsigned char)getub(buf2, 10); + /* + * Note: This code is untested. It was written from the manual. + * The results need to be sanity-checked against a GPS with + * known-good raw decoding and the same skyview. + * + * We can get pseudo range (m), delta-range (m/s), doppler (Hz) + * and status for each channel from the chip. We cannot get + * codephase or carrierphase. + */ +#define SBITS(sat, s, l) sbits((char *)buf, 10 + (sat*14) + s, l) +#define UBITS(sat, s, l) ubits((char *)buf, 10 + (sat*14) + s, l) + for (k = 0; k < visible; k++) { + int prn = (int)UBITS(k, 4, 5); + /* this is so we can tell which never got set */ + for (j = 0; j < MAXCHANNELS; j++) + session->gpsdata.raw.mtime[j] = 0; + for (j = 0; j < MAXCHANNELS; j++) { + if (session->gpsdata.PRN[j] == prn) { + session->gpsdata.raw.codephase[j] = NAN; + session->gpsdata.raw.carrierphase[j] = NAN; + session->gpsdata.raw.mtime[j] = session->newdata.time; + session->gpsdata.raw.satstat[j] = (unsigned)UBITS(k, 24, 8); + session->gpsdata.raw.pseudorange[j] = (double)SBITS(k,40,32); + session->gpsdata.raw.deltarange[j] = (double)SBITS(k,72,32); + session->gpsdata.raw.doppler[j] = (double)SBITS(k, 104, 16); + } + } + } +#undef SBITS +#undef UBITS + gpsd_report(LOG_DATA, "MDO 0x04: time=%.2f mask={TIME|RAW}\n", + session->newdata.time); + return TIME_IS | RAW_IS; + + case 0x20: /* LogConfig Info, could be used as a probe for EverMore GPS */ + gpsd_report(LOG_IO, "LogConfig EverMore packet, length %zd: %s\n", + datalen, gpsd_hexdump_wrapper(buf2, datalen, LOG_IO)); + return ONLINE_IS; + + case 0x22: /* LogData */ + gpsd_report(LOG_IO, "LogData EverMore packet, length %zd: %s\n", + datalen, gpsd_hexdump_wrapper(buf2, datalen, LOG_IO)); + return ONLINE_IS; + + case 0x38: /* ACK */ + gpsd_report(LOG_PROG, "EverMore command %02X ACK\n", getub(buf2, 2)); + return ONLINE_IS; + + default: + gpsd_report(LOG_WARN, + "unknown EverMore packet EID 0x%02x, length %zd: %s\n", + buf2[0], datalen, gpsd_hexdump_wrapper(buf2, datalen, + LOG_IO)); + return 0; + } +} + +/*@ -charint @*/ + +static gps_mask_t evermore_parse_input(struct gps_device_t *session) +{ + gps_mask_t st; + + if (session->packet.type == EVERMORE_PACKET) { + st = evermore_parse(session, session->packet.outbuffer, + session->packet.outbuflen); + return st; +#ifdef NMEA_ENABLE + } else if (session->packet.type == NMEA_PACKET) { + st = nmea_parse((char *)session->packet.outbuffer, session); + return st; +#endif /* NMEA_ENABLE */ + } else + return 0; +} + +/*@ +charint -usedef -compdef @*/ +static ssize_t evermore_control_send(struct gps_device_t *session, char *buf, + size_t len) +{ + unsigned int crc; + size_t i; + char *cp; + + /*@ +charint +ignoresigns @*/ + /* prepare a DLE-stuffed copy of the message */ + cp = session->msgbuf; + *cp++ = 0x10; /* message starts with DLE STX */ + *cp++ = 0x02; + + session->msgbuflen = (size_t) (len + 2); /* len < 254 !! */ + *cp++ = (char)session->msgbuflen; /* message length */ + if (session->msgbuflen == 0x10) + *cp++ = 0x10; + + /* payload */ + crc = 0; + for (i = 0; i < len; i++) { + *cp++ = buf[i]; + if (buf[i] == 0x10) + *cp++ = 0x10; + crc += buf[i]; + } + + crc &= 0xff; + + /* enter CRC after payload */ + *cp++ = crc; + if (crc == 0x10) + *cp++ = 0x10; + + *cp++ = 0x10; /* message ends with DLE ETX */ + *cp++ = 0x03; + + session->msgbuflen = (size_t) (cp - session->msgbuf); + /*@ -charint -ignoresigns @*/ + + return gpsd_write(session, session->msgbuf, session->msgbuflen); +} + +/*@ -charint +usedef +compdef @*/ + +static bool evermore_protocol(struct gps_device_t *session, int protocol) +{ + /*@ +charint */ + char tmp8; + char evrm_protocol_config[] = { + (char)0x84, /* 0: msg ID, Protocol Configuration */ + (char)0x00, /* 1: mode; EverMore binary(0), NMEA(1) */ + (char)0x00, /* 2: reserved */ + (char)0x00, /* 3: reserved */ + }; + /*@ -charint */ + gpsd_report(LOG_PROG, "evermore_protocol(%d)\n", protocol); + /*@i1@*/ tmp8 = (protocol != 0) ? 1 : 0; + /* NMEA : binary */ + evrm_protocol_config[1] = tmp8; + return (evermore_control_send + (session, evrm_protocol_config, + sizeof(evrm_protocol_config)) != -1); +} + +static bool evermore_nmea_config(struct gps_device_t *session, int mode) +/* mode = 0 : EverMore default */ +/* mode = 1 : gpsd best */ +/* mode = 2 : EverMore search, activate PEMT101 message */ +{ + unsigned char tmp8; + /*@ +charint */ + unsigned char evrm_nmeaout_config[] = { + 0x8e, /* 0: msg ID, NMEA Message Control */ + 0xff, /* 1: NMEA sentence bitmask, GGA(0), GLL(1), GSA(2), GSV(3), ... */ + 0x01, /* 2: nmea checksum no(0), yes(1) */ + 1, /* 3: GPGGA, interval 0-255s */ + 0, /* 4: GPGLL, interval 0-255s */ + 1, /* 5: GPGSA, interval 0-255s */ + 1, /* 6: GPGSV, interval 0-255s */ + 1, /* 7: GPRMC, interval 0-255s */ + 0, /* 8: GPVTG, interval 0-255s */ + 0, /* 9: PEMT,101, interval 0-255s */ + 0, 0, 0, 0, 0, 0, /* 10-15: reserved */ + }; + /*@ -charint */ + gpsd_report(LOG_PROG, "evermore_nmea_config(%d)\n", mode); + /*@i1@*/ tmp8 = (mode == 1) ? 5 : 1; + /* NMEA GPGSV, gpsd */ + evrm_nmeaout_config[6] = tmp8; /* GPGSV, 1s or 5s */ + /*@i1@*/ tmp8 = (mode == 2) ? 1 : 0; + /* NMEA PEMT101 */ + evrm_nmeaout_config[9] = tmp8; /* PEMT101, 1s or 0s */ + return (evermore_control_send(session, (char *)evrm_nmeaout_config, + sizeof(evrm_nmeaout_config)) != -1); +} + +static void evermore_mode(struct gps_device_t *session, int mode) +{ + gpsd_report(LOG_PROG, "evermore_mode(%d), %d\n", mode, + session->back_to_nmea ? 1 : 0); + if (mode == MODE_NMEA) { + /* NMEA */ + (void)evermore_protocol(session, 1); + session->gpsdata.dev.driver_mode = MODE_NMEA; + (void)evermore_nmea_config(session, 1); /* configure NMEA messages for gpsd */ + } else { + /* binary */ + (void)evermore_protocol(session, 0); + session->back_to_nmea = false; + session->gpsdata.dev.driver_mode = MODE_BINARY; + } +} + +static void evermore_event_hook(struct gps_device_t *session, event_t event) +{ + /* + * FIX-ME: It might not be necessary to call this on reactivate. + * Experiment to see if the holds its settings through a close. + */ + if (event == event_identified || event == event_reactivate) { + if (session->packet.type == NMEA_PACKET) { + (void)evermore_nmea_config(session, 1); /* configure NMEA messages for gpsd (GPGSV every 5s) */ + } + (void)evermore_mode(session, 1); /* switch GPS to binary mode */ + session->back_to_nmea = true; + } else if (event == event_deactivate) { + (void)evermore_nmea_config(session, 0); /* configure NMEA messages to default */ + } +} + +#ifdef ALLOW_RECONFIGURE +static bool evermore_speed(struct gps_device_t *session, + speed_t speed, char parity, int stopbits) +{ + /*@ -type @*/ + gpsd_report(LOG_PROG, "evermore_speed(%u%c%d)\n", speed, parity, + stopbits); + /* parity and stopbit switching aren't available on this chip */ + if (parity != session->gpsdata.dev.parity + || stopbits != (int)session->gpsdata.dev.parity) { + return false; + } else { + unsigned char tmp8; + unsigned char msg[] = { + 0x89, /* 0: msg ID, Serial Port Configuration */ + 0x01, /* 1: bit 0 cfg for main serial, bit 1 cfg for DGPS port */ + 0x00, /* 2: baud rate for main serial; 4800(0), 9600(1), 19200(2), 38400(3) */ + 0x00, /* 3: baud rate for DGPS serial port; 4800(0), 9600(1), etc */ + }; + switch (speed) { + case 4800: + tmp8 = 0; + break; + case 9600: + tmp8 = 1; + break; + case 19200: + tmp8 = 2; + break; + case 38400: + tmp8 = 3; + break; + default: + return false; + } + msg[2] = tmp8; + return (evermore_control_send(session, (char *)msg, sizeof(msg)) != + -1); + } + /*@ +type @*/ +} + +static bool evermore_rate_switcher(struct gps_device_t *session, double rate) +/* change the sample rate of the GPS */ +{ + /*@ +charint @*/ + unsigned char evrm_rate_config[] = { + 0x84, /* 1: msg ID, Operating Mode Configuration */ + 0x02, /* 2: normal mode with 1PPS */ + 0x00, /* 3: navigation update rate */ + 0x00, /* 4: RF/GPSBBP On Time */ + }; + + if (rate < 1 || rate > 10) { + gpsd_report(LOG_ERROR, "valid rate range is 1-10.\n"); + return false; + } else { + evrm_rate_config[2] = (unsigned char)trunc(rate); + return (evermore_control_send(session, (char *)evrm_rate_config, + sizeof(evrm_rate_config)) != -1); + } + /*@ -charint @*/ +} +#endif /* ALLOW_RECONFIGURE */ + + +/* this is everything we export */ +/* *INDENT-OFF* */ +const struct gps_type_t evermore_binary = +{ + .type_name = "EverMore binary", /* full name of type */ + .packet_type = EVERMORE_PACKET, /* lexer packet type */ + .trigger = "$PEMT,", /* recognize the type */ + .channels = EVERMORE_CHANNELS, /* consumer-grade GPS */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* use generic one */ + .parse_packet = evermore_parse_input, /* parse message packets */ + .rtcm_writer = pass_rtcm, /* send RTCM data straight */ + .event_hook = evermore_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = evermore_speed, /* we can change baud rates */ + .mode_switcher = evermore_mode, /* there is a mode switcher */ + .rate_switcher = evermore_rate_switcher, /* change sample rate */ + .min_cycle = 1, /* ignore, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = evermore_control_send, /* how to send a control string */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* defined(EVERMORE_ENABLE) && defined(BINARY_ENABLE) */ diff --git a/driver_garmin.c b/driver_garmin.c new file mode 100644 index 0000000..6071b50 --- /dev/null +++ b/driver_garmin.c @@ -0,0 +1,1469 @@ +/* + * This file contains two drivers for Garmin receivers and some code + * shared by both drivers. + * + * One driver "garmin_usb_binary" handles the Garmin binary packet + * format supported by the USB Garmins tested with the Garmin 18 and + * other models. (There is also "garmin_usb_binary_old".) These are ONLY + * for USB devices reporting as: 091e:0003. + * + * The other driver "garmin_ser_binary" is for Garmin receivers via a + * serial port, whether or not one uses a USB/serial adaptor or a real + * serial port. These receivers provide adequate NMEA support, so it + * often makes sense to just put them into NMEA mode. + * + * On Linux, USB Garmins (091e:0003) need the Linux garmin_gps driver and + * will not function without it. On other operating systems, it is clear + * garmin_usb_binary_old does not work since it requires the Linux + * garmin_gps module. + * + * This code has been tested and at least at one time is known to work on + * big- and little-endian CPUs and 32 and 64 bit cpu modes. + * + * + * Documentation for the Garmin protocols can be found via + * http://www.garmin.com/support/commProtocol.html + * The file IOSDK.zip contains IntfSpec.pdf, which describes the + * protocol in terms of Application, Link, and Physical. This + * identical file is also available at: + * http://www.garmin.com/support/pdf/iop_spec.pdf + * An older version of iop_spec.pdf that describes only Serial Binary + * is available at: + * http://vancouver-webpages.com/pub/peter/iop_spec.pdf + * Information about the GPS 18 + * http://www.garmin.com/manuals/425_TechnicalSpecification.pdf + * + * There is one physical link protocol for serial which uses DLE/ETX + * framing. There is another physical protocol for USB which relies + * on the packetization intrinstic to USB bulk pipes. + * + * There are several link protocols; all devices implement L000. + * There are then product-specific protocols; most devices implement + * L001. Link protocols are the same and carried over either Physical + * protocol. + * + * Application protocols are named A000 and then with different + * 3-digit numbres. They are carried over Link protocols. + * + * Thus, much of the higher-level code dealing the data formats is + * shared between USB Binary and Serial Binary. + * + * This code is partly from the Garmin IOSDK and partly from the + * sample code in the Linux garmin_gps driver. + * + * bad code by: Gary E. Miller + * + * -D 3 = packet trace + * -D 4 = packet details + * -D 5 = more packet details + * -D 6 = very excessive details + * + * limitations: + * + * do not have from garmin: + * pdop + * hdop + * vdop + * magnetic variation + * + * known bugs: + * hangs in the fread loop instead of keeping state and returning. + * + * TODO: + * + * ?? Add probe function for Serial Binary to start PVT output. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#define __USE_POSIX199309 1 +#include +#include // for nanosleep() + +#include +#include +#include + +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include + +#include "gpsd_config.h" +#if defined (HAVE_SYS_SELECT_H) +#include +#endif + +#if defined(HAVE_STRINGS_H) +#include +#endif + +#if defined(HAVE_LIBUSB) +#include +#endif + +#include "gpsd.h" +#include "gps.h" + +#ifdef GARMIN_ENABLE + +#define USE_RMD 0 + +/* Used in Serial Physical Layer */ +#define ETX 0x03 +#define ACK 0x06 +#define DLE 0x10 +#define NAK 0x15 + +#define GARMIN_LAYERID_TRANSPORT (uint8_t) 0 +#define GARMIN_LAYERID_APPL (uint32_t) 20 +// Linux Garmin USB driver layer-id to use for some control mechanisms +#define GARMIN_LAYERID_PRIVATE 0x01106E4B + +// packet ids used in private layer +#define PRIV_PKTID_SET_DEBUG 1 +#define PRIV_PKTID_SET_MODE 2 +#define PRIV_PKTID_INFO_REQ 3 +#define PRIV_PKTID_INFO_RESP 4 +#define PRIV_PKTID_RESET_REQ 5 +#define PRIV_PKTID_SET_DEF_MODE 6 + +#define MODE_NATIVE 0 +#define MODE_GARMIN_SERIAL 1 + +#define GARMIN_PKTID_TRANSPORT_START_SESSION_REQ 5 +#define GARMIN_PKTID_TRANSPORT_START_SESSION_RESP 6 + +#define GARMIN_PKTID_PROTOCOL_ARRAY 253 +#define GARMIN_PKTID_PRODUCT_RQST 254 +#define GARMIN_PKTID_PRODUCT_DATA 255 +/* 0x29 ')' */ +#define GARMIN_PKTID_RMD41_DATA 41 +/* 0x33 '3' */ +#define GARMIN_PKTID_PVT_DATA 51 +/* 0x33 '4' */ +#define GARMIN_PKTID_RMD_DATA 52 +/* 0x72 'r' */ +#define GARMIN_PKTID_SAT_DATA 114 + +#define GARMIN_PKTID_L001_XFER_CMPLT 12 +#define GARMIN_PKTID_L001_COMMAND_DATA 10 +#define GARMIN_PKTID_L001_DATE_TIME_DATA 14 +#define GARMIN_PKTID_L001_RECORDS 27 +#define GARMIN_PKTID_L001_WPT_DATA 35 + +#define CMND_ABORT 0 +#define CMND_START_PVT_DATA 49 +#define CMND_STOP_PVT_DATA 50 +#define CMND_START_RM_DATA 110 + +#define MAX_BUFFER_SIZE 4096 + +#define GARMIN_CHANNELS 12 + +// something magic about 64, garmin driver will not return more than +// 64 at a time. If you read less than 64 bytes the next read will +// just get the last of the 64 byte buffer. +#define ASYNC_DATA_SIZE 64 + + +#pragma pack(1) +// This is the data format of the satellite data from the garmin USB +typedef struct +{ + uint8_t svid; + int16_t snr; // 0 - 0xffff + uint8_t elev; + uint16_t azmth; + uint8_t status; // bit 0, has ephemeris, 1, has diff correction + // bit 2 used in solution + // bit 3?? +} cpo_sat_data; + +/* Garmin D800_Pvt_Datetype_Type */ +/* packet type: GARMIN_PKTID_PVT_DATA 52 */ +/* This is the data format of the position data from the garmin USB */ +typedef struct +{ + float alt; /* altitude above WGS 84 (meters) */ + float epe; /* estimated position error, 2 sigma (meters) */ + float eph; /* epe, but horizontal only (meters) */ + float epv; /* epe but vertical only (meters ) */ + int16_t fix; /* 0 - failed integrity check + * 1 - invalid or unavailable fix + * 2 - 2D + * 3 - 3D + * 4 - 2D Diff + * 5 - 3D Diff + */ + double gps_tow; /* gps time of week (seconds) */ + double lat; /* ->latitude (radians) */ + double lon; /* ->longitude (radians) */ + float lon_vel; /* velocity east (meters/second) */ + float lat_vel; /* velocity north (meters/second) */ + float alt_vel; /* velocity up (meters/sec) */ + // Garmin GPS25 uses pkt_id 0x28 and does not output the + // next 3 items + float msl_hght; /* height of WGS 84 above MSL (meters) */ + int16_t leap_sec; /* diff between GPS and UTC (seconds) */ + int32_t grmn_days; /* days from UTC December 31st, 1989 to the + * beginning of the current week */ +} cpo_pvt_data; + +typedef struct +{ + uint32_t cycles; + double pr; + uint16_t phase; + int8_t slp_dtct; + uint8_t snr_dbhz; + uint8_t svid; + int8_t valid; +} cpo_rcv_sv_data; + +/* packet type: GARMIN_PKTID_RMD_DATA 53 */ +/* seems identical to the packet id 0x29 from the Garmin GPS 25 */ +typedef struct +{ + double rcvr_tow; + int16_t rcvr_wn; + cpo_rcv_sv_data sv[GARMIN_CHANNELS]; +} cpo_rcv_data; + +// This is the packet format to/from the Garmin USB +typedef struct +{ + uint8_t mPacketType; + uint8_t mReserved1; + uint16_t mReserved2; + uint16_t mPacketId; + uint16_t mReserved3; + uint32_t mDataSize; + union + { + int8_t chars[MAX_BUFFER_SIZE]; + uint8_t uchars[MAX_BUFFER_SIZE]; + cpo_pvt_data pvt; + cpo_sat_data sats; + } mData; +} Packet_t; + +// useful funcs to read/write ints +// floats and doubles are Intel order only... +static inline void set_int16(uint8_t * buf, uint32_t value) +{ + buf[0] = (uint8_t) (0x0FF & value); + buf[1] = (uint8_t) (0x0FF & (value >> 8)); +} + +static inline void set_int32(uint8_t * buf, uint32_t value) +{ + buf[0] = (uint8_t) (0x0FF & value); + buf[1] = (uint8_t) (0x0FF & (value >> 8)); + buf[2] = (uint8_t) (0x0FF & (value >> 16)); + buf[3] = (uint8_t) (0x0FF & (value >> 24)); +} + +static inline uint16_t get_uint16(const uint8_t * buf) +{ + return (uint16_t) (0xFF & buf[0]) + | ((uint16_t) (0xFF & buf[1]) << 8); +} + +static inline uint32_t get_int32(const uint8_t * buf) +{ + return (uint32_t) (0xFF & buf[0]) + | ((uint32_t) (0xFF & buf[1]) << 8) + | ((uint32_t) (0xFF & buf[2]) << 16) + | ((uint32_t) (0xFF & buf[3]) << 24); +} + +// convert radians to degrees +static inline double radtodeg(double rad) +{ + return (double)(rad * RAD_2_DEG); +} + +static gps_mask_t PrintSERPacket(struct gps_device_t *session, + unsigned char pkt_id, int pkt_len, + unsigned char *buf); +static gps_mask_t PrintUSBPacket(struct gps_device_t *session, + Packet_t * pkt); + +gps_mask_t PrintSERPacket(struct gps_device_t *session, unsigned char pkt_id, + int pkt_len, unsigned char *buf) +{ + + gps_mask_t mask = 0; + int i = 0, j = 0; + uint16_t prod_id = 0; + uint16_t ver = 0; + int maj_ver; + int min_ver; + time_t time_l = 0; + double track; + char msg_buf[512] = ""; + char *msg = NULL; + cpo_sat_data *sats = NULL; + cpo_pvt_data *pvt = NULL; + cpo_rcv_data *rmd = NULL; + + gpsd_report(LOG_IO, "Garmin: PrintSERPacket(, %#02x, %#02x, )\n", pkt_id, + pkt_len); + + session->cycle_end_reliable = true; + + switch (pkt_id) { + case ACK: + gpsd_report(LOG_PROG, "Garmin: ACK\n"); + break; + case NAK: + gpsd_report(LOG_PROG, "Garmin: NAK\n"); + break; + case GARMIN_PKTID_L001_COMMAND_DATA: + prod_id = get_uint16((uint8_t *) buf); + /*@ -branchstate @*/ + switch (prod_id) { + case CMND_ABORT: + msg = "Abort current xfer"; + break; + case CMND_START_PVT_DATA: + msg = "Start Xmit PVT data"; + break; + case CMND_STOP_PVT_DATA: + msg = "Stop Xmit PVT data"; + break; + case CMND_START_RM_DATA: + msg = "Start RMD data"; + break; + default: + (void)snprintf(msg_buf, sizeof(msg_buf), "Unknown: %u", + (unsigned int)prod_id); + msg = msg_buf; + break; + } + /*@ +branchstate @*/ + gpsd_report(LOG_PROG, "Garmin: Appl, Command Data: %s\n", msg); + break; + case GARMIN_PKTID_PRODUCT_RQST: + gpsd_report(LOG_PROG, "Garmin: Appl, Product Data req\n"); + break; + case GARMIN_PKTID_PRODUCT_DATA: + prod_id = get_uint16((uint8_t *) buf); + ver = get_uint16((uint8_t *) & buf[2]); + maj_ver = (int)(ver / 100); + min_ver = (int)(ver - (maj_ver * 100)); + gpsd_report(LOG_PROG, "Garmin: Appl, Product Data, sz: %d\n", + pkt_len); + (void)snprintf(session->subtype, sizeof(session->subtype), + "%d: %d.%02d", (int)prod_id, maj_ver, min_ver); + gpsd_report(LOG_INF, "Garmin: Product ID: %d, SoftVer: %d.%02d\n", + prod_id, maj_ver, min_ver); + gpsd_report(LOG_INF, "Garmin: Product Desc: %s\n", &buf[4]); + mask |= DEVICEID_IS; + gpsd_report(LOG_DATA, "Garmin: PRODUCT_DATA: subtype=%s mask=%s\n", + session->subtype, gpsd_maskdump(mask)); + break; + case GARMIN_PKTID_PVT_DATA: + gpsd_report(LOG_PROG, "Garmin: Appl, PVT Data Sz: %d\n", pkt_len); + + pvt = (cpo_pvt_data *) buf; + + // 631065600, unix seconds for 31 Dec 1989 Zulu + time_l = (time_t) (631065600 + (pvt->grmn_days * 86400)); + // TODO, convert grmn_days to context->gps_week + time_l -= pvt->leap_sec; + session->context->leap_seconds = pvt->leap_sec; + session->context->valid = LEAP_SECOND_VALID; + // gps_tow is always like x.999 or x.998 so just round it + time_l += (time_t) round(pvt->gps_tow); + session->context->gps_tow = pvt->gps_tow; + session->newdata.time = (double)time_l; + gpsd_report(LOG_PROG, "Garmin: time_l: %ld\n", (long int)time_l); + + session->newdata.latitude = radtodeg(pvt->lat); + /* sanity check the lat */ + if (90.0 < session->newdata.latitude) { + session->newdata.latitude = 90.0; + gpsd_report(LOG_INF, "Garmin: ERROR: Latitude overrange\n"); + } else if (-90.0 > session->newdata.latitude) { + session->newdata.latitude = -90.0; + gpsd_report(LOG_INF, + "Garmin: ERROR: Latitude negative overrange\n"); + } + session->newdata.longitude = radtodeg(pvt->lon); + /* sanity check the lon */ + if (180.0 < session->newdata.longitude) { + session->newdata.longitude = 180.0; + gpsd_report(LOG_INF, "Garmin: ERROR: Longitude overrange\n"); + } else if (-180.0 > session->newdata.longitude) { + session->newdata.longitude = -180.0; + gpsd_report(LOG_INF, + "Garmin: ERROR: Longitude negative overrange\n"); + } + // altitude over WGS84 converted to MSL + session->newdata.altitude = pvt->alt + pvt->msl_hght; + + // geoid separation from WGS 84 + // gpsd sign is opposite of garmin sign + session->gpsdata.separation = -pvt->msl_hght; + + // Estimated position error in meters. + // We follow the advice at . + // If this assumption changes here, it should also change in + // nmea_parse.c where we analyze PGRME. + session->gpsdata.epe = pvt->epe * (GPSD_CONFIDENCE / CEP50_SIGMA); + /* eph is a circular error, sqrt(epx**2 + epy**2) */ + session->newdata.epx = session->newdata.epy = + pvt->eph * (1 / sqrt(2)) * (GPSD_CONFIDENCE / CEP50_SIGMA); + session->newdata.epv = pvt->epv * (GPSD_CONFIDENCE / CEP50_SIGMA); + + // convert lat/lon to directionless speed + session->newdata.speed = hypot(pvt->lon_vel, pvt->lat_vel); + + // keep climb in meters/sec + session->newdata.climb = pvt->alt_vel; + + track = atan2(pvt->lon_vel, pvt->lat_vel); + if (track < 0) { + track += 2 * GPS_PI; + } + session->newdata.track = radtodeg(track); + + switch (pvt->fix) { + case 0: + case 1: + default: + // no fix + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + break; + case 2: + // 2D fix + session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_2D; + break; + case 3: + // 3D fix + session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_3D; + break; + case 4: + // 2D Differential fix + session->gpsdata.status = STATUS_DGPS_FIX; + session->newdata.mode = MODE_2D; + break; + case 5: + // 3D differential fix + session->gpsdata.status = STATUS_DGPS_FIX; + session->newdata.mode = MODE_3D; + break; + } + + gpsd_report(LOG_PROG, "Garmin: Appl, mode %d, status %d\n", + session->newdata.mode, session->gpsdata.status); + + gpsd_report(LOG_INF, "Garmin: UTC Time: %lf\n", + session->newdata.time); + gpsd_report(LOG_INF, + "Garmin: Geoid Separation (MSL-WGS84): from garmin %lf, calculated %lf\n", + -pvt->msl_hght, + wgs84_separation(session->newdata.latitude, + session->newdata.longitude)); + + gpsd_report(LOG_INF, + "Garmin: Alt: %.3f, Epe: %.3f, Eph: %.3f, Epv: %.3f, Fix: %d, Gps_tow: %f, Lat: %.3f, Lon: %.3f, LonVel: %.3f, LatVel: %.3f, AltVel: %.3f, MslHgt: %.3f, Leap: %d, GarminDays: %d\n", + pvt->alt, pvt->epe, pvt->eph, pvt->epv, pvt->fix, + pvt->gps_tow, session->newdata.latitude, + session->newdata.longitude, pvt->lon_vel, pvt->lat_vel, + pvt->alt_vel, pvt->msl_hght, pvt->leap_sec, + pvt->grmn_days); + + if (session->newdata.mode > MODE_NO_FIX) { + /* data only valid with a fix */ + mask |= + TIME_IS | LATLON_IS | ALTITUDE_IS | STATUS_IS | MODE_IS | + SPEED_IS | TRACK_IS | CLIMB_IS | HERR_IS | VERR_IS | PERR_IS | + CLEAR_IS | REPORT_IS; + } + gpsd_report(LOG_DATA, + "Garmin: PVT_DATA: time=%.2f, lat=%.2f lon=%.2f " + "speed=%.2f track=%.2f climb=%.2f " + "epx=%.2f epy=%.2f epv=%.2f " + "mode=%d status=%d mask=%s\n", + session->newdata.time, + session->newdata.latitude, + session->newdata.longitude, + session->newdata.speed, + session->newdata.track, + session->newdata.climb, + session->newdata.epx, + session->newdata.epy, + session->newdata.epv, + session->newdata.mode, + session->gpsdata.status, gpsd_maskdump(mask)); + break; + case GARMIN_PKTID_RMD_DATA: + case GARMIN_PKTID_RMD41_DATA: + rmd = (cpo_rcv_data *) buf; + gpsd_report(LOG_IO, "Garmin: PVT RMD Data Sz: %d\n", pkt_len); + gpsd_report(LOG_PROG, "Garmin: PVT RMD rcvr_tow: %f, rcvr_wn: %d\n", + rmd->rcvr_tow, rmd->rcvr_wn); + for (i = 0; i < GARMIN_CHANNELS; i++) { + gpsd_report(LOG_INF, + "Garmin: PVT RMD Sat: %3u, cycles: %9u, pr: %16.6f, " + "phase: %7.3f, slp_dtct: %3s, snr: %3u, Valid: %3s\n", + rmd->sv[i].svid + 1, rmd->sv[i].cycles, rmd->sv[i].pr, + (rmd->sv[i].phase * 360.0) / 2048.0, + rmd->sv[i].slp_dtct != '\0' ? "Yes" : "No", + rmd->sv[i].snr_dbhz, + rmd->sv[i].valid != '\0' ? "Yes" : "No"); + } + break; + + case GARMIN_PKTID_SAT_DATA: + gpsd_report(LOG_PROG, "Garmin: SAT Data Sz: %d\n", pkt_len); + sats = (cpo_sat_data *) buf; + + session->gpsdata.satellites_used = 0; + memset(session->gpsdata.used, 0, sizeof(session->gpsdata.used)); + gpsd_zero_satellites(&session->gpsdata); + for (i = 0, j = 0; i < GARMIN_CHANNELS; i++, sats++) { + gpsd_report(LOG_INF, + "Garmin: Sat %3d, snr: %5d, elev: %2d, Azmth: %3d, Stat: %x\n", + sats->svid, sats->snr, sats->elev, sats->azmth, + sats->status); + + if (255 == (int)sats->svid) { + // Garmin uses 255 for empty + // gpsd uses 0 for empty + continue; + } + + session->gpsdata.PRN[j] = (int)sats->svid; + session->gpsdata.azimuth[j] = (int)sats->azmth; + session->gpsdata.elevation[j] = (int)sats->elev; + // Garmin does not document this. snr is in dB*100 + // Known, but not seen satellites have a dB value of -1*100 + session->gpsdata.ss[j] = (float)(sats->snr / 100.0); + if (session->gpsdata.ss[j] < 0.0) { + session->gpsdata.ss[j] = 0.0; + } + // FIX-ME: Garmin documents this, but Daniel Dorau + // says the behavior on his GPSMap60CSX + // doesn't match it. + if ((uint8_t) 0 != (sats->status & 4)) { + // used in solution? + session->gpsdata.used[session->gpsdata.satellites_used++] + = (int)sats->svid; + } + session->gpsdata.satellites_visible++; + j++; + + } + session->gpsdata.skyview_time = NAN; + mask |= SATELLITE_IS | USED_IS; + gpsd_report(LOG_DATA, + "Garmin: SAT_DATA: visible=%d used=%d mask=%s\n", + session->gpsdata.satellites_visible, + session->gpsdata.satellites_used, gpsd_maskdump(mask)); + break; + case GARMIN_PKTID_PROTOCOL_ARRAY: + // this packet is never requested, it just comes, in some case + // after a GARMIN_PKTID_PRODUCT_RQST + gpsd_report(LOG_INF, "Garmin: Appl, Product Capability, sz: %d\n", + pkt_len); + for (i = 0; i < pkt_len; i += 3) { + gpsd_report(LOG_INF, "Garmin: %c%03d\n", buf[i], + get_uint16((uint8_t *) & buf[i + 1])); + } + break; + default: + gpsd_report(LOG_WARN, + "Garmin: Unknown packet id: %#02x, Sz: %#02x, pkt:%s\n", + pkt_id, pkt_len, gpsd_hexdump_wrapper(buf, + (size_t) pkt_len, + LOG_WARN)); + break; + } + gpsd_report(LOG_IO, "Garmin: PrintSERPacket(, %#02x, %#02x, ) = %s\n", + pkt_id, pkt_len, gpsd_maskdump(mask)); + return mask; +} + + +/*@ -branchstate @*/ +// For debugging, decodes and prints some known packets. +static gps_mask_t PrintUSBPacket(struct gps_device_t *session, Packet_t * pkt) +{ + gps_mask_t mask = 0; + int maj_ver; + int min_ver; + uint32_t mode = 0; + uint16_t prod_id = 0; + uint32_t veri = 0; + uint32_t serial; + uint32_t mDataSize = get_int32((uint8_t *) & pkt->mDataSize); + +// + uint8_t *buffer = (uint8_t *) pkt; + + gpsd_report(LOG_PROG, "Garmin: PrintUSBPacket()\n"); +// gem + if (DLE == pkt->mPacketType) { + gpsd_report(LOG_PROG, "Garmin: really a SER packet!\n"); + return PrintSERPacket(session, + (unsigned char)buffer[1], + (int)buffer[2], (unsigned char *)(buffer + 3)); + } +// gem + if (4096 < mDataSize) { + gpsd_report(LOG_WARN, "Garmin: bogus packet, size too large=%d\n", + mDataSize); + return 0; + } + + (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), "%u", + (unsigned int)pkt->mPacketType); + switch (pkt->mPacketType) { + case GARMIN_LAYERID_TRANSPORT: + /* Garmin USB layer specific */ + switch (pkt->mPacketId) { + case GARMIN_PKTID_TRANSPORT_START_SESSION_REQ: + gpsd_report(LOG_PROG, "Garmin: Transport, Start Session req\n"); + break; + case GARMIN_PKTID_TRANSPORT_START_SESSION_RESP: + mode = get_int32(&pkt->mData.uchars[0]); + gpsd_report(LOG_PROG, + "Garmin: Transport, Start Session resp, unit: 0x%x\n", + mode); + break; + default: + gpsd_report(LOG_PROG, + "Garmin: Transport, Packet: Type %d %d %d, ID: %d, Sz: %d\n", + pkt->mPacketType, pkt->mReserved1, pkt->mReserved2, + pkt->mPacketId, mDataSize); + break; + } + break; + case GARMIN_LAYERID_APPL: + /* raw data transport, shared with Garmin Serial Driver */ + + mask = PrintSERPacket(session, + (unsigned char)pkt->mPacketId, + (int)mDataSize, + (unsigned char *)pkt->mData.uchars); + break; + case 75: + // private, garmin USB kernel driver specific + switch (pkt->mPacketId) { + case PRIV_PKTID_SET_MODE: + prod_id = get_uint16(&pkt->mData.uchars[0]); + gpsd_report(LOG_PROG, "Garmin: Private, Set Mode: %d\n", prod_id); + break; + case PRIV_PKTID_INFO_REQ: + gpsd_report(LOG_PROG, "Garmin: Private, ID: Info Req\n"); + break; + case PRIV_PKTID_INFO_RESP: + veri = get_int32(pkt->mData.uchars); + maj_ver = (int)(veri >> 16); + min_ver = (int)(veri & 0xffff); + mode = get_int32(&pkt->mData.uchars[4]); + serial = get_int32(&pkt->mData.uchars[8]); + gpsd_report(LOG_PROG, "Garmin: Private, ID: Info Resp\n"); + gpsd_report(LOG_INF, + "Garmin: USB Driver found, Version %d.%d, Mode: %d, GPS Serial# %u\n", + maj_ver, min_ver, mode, serial); + break; + default: + gpsd_report(LOG_PROG, "Garmin: Private, Packet: ID: %d, Sz: %d\n", + pkt->mPacketId, mDataSize); + break; + } + break; + default: + gpsd_report(LOG_PROG, + "Garmin: Packet: Type %d %d %d, ID: %d, Sz: %d\n", + pkt->mPacketType, pkt->mReserved1, pkt->mReserved2, + pkt->mPacketId, mDataSize); + break; + } + + return mask; +} + +/*@ +branchstate @*/ + + +/* build and send a packet w/ USB protocol */ +static void Build_Send_USB_Packet(struct gps_device_t *session, + uint32_t layer_id, uint32_t pkt_id, + uint32_t length, uint32_t data) +{ + uint8_t *buffer = (uint8_t *) session->driver.garmin.Buffer; + Packet_t *thePacket = (Packet_t *) buffer; + ssize_t theBytesReturned = 0; + ssize_t theBytesToWrite = 12 + (ssize_t) length; + + set_int32(buffer, layer_id); + set_int32(buffer + 4, pkt_id); + set_int32(buffer + 8, length); + if (2 == length) { + set_int16(buffer + 12, data); + } else if (4 == length) { + set_int32(buffer + 12, data); + } +#if 0 + gpsd_report(LOG_IO, "Garmin: SendPacket(), writing %d bytes: %s\n", + theBytesToWrite, + gpsd_hexdump_wrapper(thePacket, theBytesToWrite, LOG_IO)); +#endif + (void)PrintUSBPacket(session, thePacket); + + theBytesReturned = gpsd_write(session, thePacket, + (size_t) theBytesToWrite); + gpsd_report(LOG_IO, "Garmin: SendPacket(), wrote %zd bytes\n", + theBytesReturned); + + // Garmin says: + // If the packet size was an exact multiple of the USB packet + // size, we must make a final write call with no data + + // as a practical matter no known packets are 64 bytes long so + // this is untested + + // So here goes just in case + if (0 == (theBytesToWrite % ASYNC_DATA_SIZE)) { + char *n = ""; + theBytesReturned = gpsd_write(session, &n, 0); + } +} + +/* build and send a packet in serial protocol */ +/* layer_id unused */ +// FIX-ME: This should go through the common message buffer someday +static void Build_Send_SER_Packet(struct gps_device_t *session, + uint32_t layer_id UNUSED, uint32_t pkt_id, + uint32_t length, uint32_t data) +{ + uint8_t *buffer = (uint8_t *) session->driver.garmin.Buffer; + uint8_t *buffer0 = buffer; + Packet_t *thePacket = (Packet_t *) buffer; + ssize_t theBytesReturned = 0; + ssize_t theBytesToWrite = 6 + (ssize_t) length; + uint8_t chksum = 0; + + *buffer++ = (uint8_t) DLE; + *buffer++ = (uint8_t) pkt_id; + chksum = pkt_id; + *buffer++ = (uint8_t) length; + chksum += length; + /* ??? What is this doing? */ + if (2 == length) { + /* carefull! no DLE stuffing here! */ + set_int16(buffer, data); + chksum += buffer[0]; + chksum += buffer[1]; + } else if (4 == length) { + /* carefull! no DLE stuffing here! */ + set_int32(buffer, data); + chksum += buffer[0]; + chksum += buffer[1]; + chksum += buffer[2]; + chksum += buffer[3]; + } + /* ??? How is data copied to the buffer? */ + buffer += length; + + // Add checksum + *buffer++ = -chksum; + if (DLE == -chksum) { + /* stuff another DLE */ + *buffer++ = (uint8_t) DLE; + theBytesToWrite++; + } + // Add DLE, ETX + *buffer++ = (uint8_t) DLE; + *buffer++ = (uint8_t) ETX; + +#if 1 + gpsd_report(LOG_IO, "Garmin: SendPacket(), writing %zd bytes: %s\n", + theBytesToWrite, + gpsd_hexdump_wrapper(thePacket, (size_t) theBytesToWrite, + LOG_IO)); +#endif + (void)PrintSERPacket(session, + (unsigned char)buffer0[1], + (int)buffer0[2], (unsigned char *)(buffer0 + 3)); + + theBytesReturned = gpsd_write(session, thePacket, + (size_t) theBytesToWrite); + gpsd_report(LOG_IO, "Garmin: SendPacket(), wrote %zd bytes\n", + theBytesReturned); + +} + +#if defined(HAVE_LIBUSB) || defined(S_SPLINT_S) +/* + * is_usb_device() - is a specified device USB matching given vendor/product? + * + * BUG: Doesn't actually match against path yet. Must finish this function + * by querying /sys/dev/char, either directly or using libudev. Greg KH + * assures this is possible, though he is vague about how. + * + * libudev: http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/ + */ +/*@-compdef -usedef@*/ +static bool is_usb_device(const char *path UNUSED, int vendor, int product) +{ + // discover devices + libusb_device **list; + ssize_t cnt; + ssize_t i = 0; + bool found = false; + + gpsd_report(LOG_SHOUT, "attempting USB device enumeration.\n"); + /*@i2@*/ libusb_init(NULL); + + /*@-nullpass@*/ + if ((cnt = libusb_get_device_list(NULL, &list)) < 0) { + gpsd_report(LOG_ERROR, "USB device list call failed.\n"); + /*@i1@*/ libusb_exit(NULL); + return false; + } + /*@+nullpass@*/ + + for (i = 0; i < cnt; i++) { + struct libusb_device_descriptor desc; + libusb_device *dev = list[i]; + + int r = libusb_get_device_descriptor(dev, &desc); + if (r < 0) { + gpsd_report(LOG_ERROR, + "USB descriptor fetch failed on device %zd.\n", i); + continue; + } + + /* we can extract device descriptor data */ + gpsd_report(LOG_SHOUT, "%04x:%04x (bus %d, device %d)\n", + desc.idVendor, desc.idProduct, + libusb_get_bus_number(dev), + libusb_get_device_address(dev)); + + /* we match if vendor and product ID are right */ + if (desc.idVendor == 0x91e && desc.idProduct == 3) { + found = true; + break; + } + } + + gpsd_report(LOG_SHOUT, "vendor/product match with %04x:%04x %sfound\n", + vendor, product, found ? "" : "not "); + libusb_free_device_list(list, 1); + /*@i1@*/ libusb_exit(NULL); + return found; +} + +/*@-compdef -usedef@*/ +#endif /* HAVE_LIBUSB || S_SPLINT_S */ + +/* + * garmin_usb_detect() - detect a Garmin USB device connected to ession fd. + * + * This is ONLY for USB devices reporting as: 091e:0003. + * + * This driver ONLY works in Linux and ONLY when the the garmin_gps kernel + * module is installed. + * + * This is only necessary because under Linux Garmin USB devices need a + * kernel module rather than being normal USB-serial devices. + * + * The actual wire protocol from the Garmin device is very strange. There + * are no delimiters. End of packet is signaled by a zero-length read + * on the USB device, and start of packet is the next read. You can't just + * ignore the zero reads and pass the data through - you'd never be able + * to tell where the packet boundaries are. + * + * The garmin_usb module's job is to grab the packet and frame it in + * DLEs (with DLE stuffing). This makes the USB packets look as + * though they came from a regular Garmin *serial* device, which is how + * most of the processing for both types can be unified here. + * + * return 1 is device found + * return 0 if not + */ +static bool garmin_usb_detect(struct gps_device_t *session) +{ +#if defined(__linux__) || defined(S_SPLINT_S) + /* + * Only perform this check if we're looking at a USB-serial + * device. This prevents drivers for attached serial GPSes + * fronm being rudely elbowed aside by this one if they happen + * to be trying to coexist with the Garmin. + */ + if (session->sourcetype != source_usb) + return false; + else { +#ifdef HAVE_LIBUSB + if (!is_usb_device(session->gpsdata.dev.path, 0x091e, 0x0003)) + return false; +#else + /* + * This is ONLY for USB devices reporting as: 091e:0003. + * + * Check that the garmin_gps driver is installed in the kernel + * and that an active USB device is using it. + * + * BUG: It does not yet check that the currect device is the one + * attached to the Garmin. So if you have a Garmin and another + * USB gps this could be a problem. + * + * Return true if garmin_gps device found, false otherwise. + */ + FILE *fp = NULL; + char buf[256]; + bool ok = false; + + /* check for garmin USB serial driver -- very Linux-specific */ + if (access("/sys/module/garmin_gps", R_OK) != 0) { + gpsd_report(LOG_WARN, + "Garmin: garmin_gps Linux USB module not active.\n"); + return false; + } + /* check for a garmin_gps device in /proc + * if we can */ + if (NULL != (fp = fopen("/proc/bus/usb/devices", "r"))) { + + ok = false; + while (0 != fgets(buf, (int)sizeof(buf), fp)) { + if (strstr(buf, "garmin_gps")) { + ok = true; + break; + } + } + (void)fclose(fp); + if (!ok) { + // no device using garmin_gps now + gpsd_report(LOG_WARN, + "Garmin: garmin_gps not in /proc/bus/usb/devices.\n"); + gpsd_report(LOG_WARN, + "Garmin: garmin_gps driver present, but not in use\n"); + return false; + } + } else { + gpsd_report(LOG_WARN, + "Garmin: Can't open /proc/bus/usb/devices, will try anyway\n"); + } +#endif /* HAVE_LIBUSB */ + + if (!gpsd_set_raw(session)) { + gpsd_report(LOG_ERROR, + "Garmin: garmin_usb_detect: error changing port attributes: %s\n", + strerror(errno)); + return false; + } +#ifdef __UNUSED + Packet_t *thePacket = NULL; + uint8_t *buffer = NULL; + /* reset the buffer and buffer length */ + memset(session->driver.garmin.Buffer, 0, + sizeof(session->driver.garmin.Buffer)); + session->driver.garmin.BufferLen = 0; + + if (sizeof(session->driver.garmin.Buffer) < sizeof(Packet_t)) { + gpsd_report(LOG_ERROR, + "Garmin: garmin_usb_detect: Compile error, garmin.Buffer too small.\n", + strerror(errno)); + return false; + } + + buffer = (uint8_t *) session->driver.garmin.Buffer; + thePacket = (Packet_t *) buffer; +#endif /* __UNUSED__ */ + + // set Mode 1, mode 0 is broken somewhere past 2.6.14 + // but how? + gpsd_report(LOG_PROG, "Garmin: Set garmin_gps driver mode = 0\n"); + Build_Send_USB_Packet(session, GARMIN_LAYERID_PRIVATE, + PRIV_PKTID_SET_MODE, 4, MODE_GARMIN_SERIAL); + // expect no return packet !? + + return true; + } +#else + return false; +#endif /* __linux__ || S_SPLINT_S */ +} + +static void garmin_event_hook(struct gps_device_t *session, event_t event) +{ + /* + * FIX-ME: It might not be necessary to call this on reactivate. + * Experiment to see if the holds its settings through a close. + */ + if (event == event_identified || event == event_reactivate) { + // Tell the device to send product data + gpsd_report(LOG_PROG, "Garmin: Get Product Data\n"); + Build_Send_SER_Packet(session, GARMIN_LAYERID_APPL, + GARMIN_PKTID_PRODUCT_RQST, 0, 0); + + // turn on PVT data 49 + gpsd_report(LOG_PROG, "Garmin: Set to send reports every 1 second\n"); + + Build_Send_SER_Packet(session, GARMIN_LAYERID_APPL, + GARMIN_PKTID_L001_COMMAND_DATA, 2, + CMND_START_PVT_DATA); + +#if USE_RMD + // turn on RMD data 110 + gpsd_report(LOG_PROG, "Garmin: Set to send Raw sat data\n"); + Build_Send_SER_Packet(session, GARMIN_LAYERID_APPL, + GARMIN_PKTID_L001_COMMAND_DATA, 2, + CMND_START_RM_DATA); +#endif + } + if (event == event_deactivate) + /* FIX-ME: is any action needed, or is closing the port sufficient? */ + gpsd_report(LOG_PROG, "Garmin: garmin_close()\n"); +} + +#define Send_ACK() Build_Send_SER_Packet(session, 0, ACK, 0, 0) +#define Send_NAK() Build_Send_SER_Packet(session, 0, NAK, 0, 0) + +/*@ +charint @*/ +gps_mask_t garmin_ser_parse(struct gps_device_t *session) +{ + unsigned char *buf = session->packet.outbuffer; + size_t len = session->packet.outbuflen; + unsigned char data_buf[MAX_BUFFER_SIZE]; + unsigned char c; + int i = 0; + size_t n = 0; + int data_index = 0; + int got_dle = 0; + unsigned char pkt_id = 0; + unsigned char pkt_len = 0; + unsigned char chksum = 0; + gps_mask_t mask = 0; + + gpsd_report(LOG_RAW, "Garmin: garmin_ser_parse()\n"); + if (6 > len) { + /* WTF? */ + /* minimum packet; [pkt id] [length=0] [chksum] */ + Send_NAK(); + gpsd_report(LOG_RAW + 1, "Garmin: serial too short: %zd\n", len); + return 0; + } + /* debug */ + for (i = 0; i < (int)len; i++) { + gpsd_report(LOG_RAW + 1, "Garmin: Char: %#02x\n", buf[i]); + } + + if ('\x10' != buf[0]) { + Send_NAK(); + gpsd_report(LOG_RAW + 1, "Garmin: buf[0] not DLE\n"); + return 0; + } + n = 1; + pkt_id = buf[n++]; + chksum = pkt_id; + if ('\x10' == pkt_id) { + if ('\x10' != buf[n++]) { + Send_NAK(); + gpsd_report(LOG_RAW + 1, "Garmin: Bad pkt_id %#02x\n", pkt_id); + return 0; + } + } + + pkt_len = buf[n++]; + chksum += pkt_len; + if ('\x10' == pkt_len) { + if ('\x10' != buf[n++]) { + gpsd_report(LOG_RAW + 1, "Garmin: Bad pkt_len %#02x\n", pkt_len); + Send_NAK(); + return 0; + } + } + data_index = 0; + for (i = 0; i < 256; i++) { + + if ((int)pkt_len == data_index) { + // got it all + break; + } + if (len < n + i) { + gpsd_report(LOG_RAW + 1, "Garmin: Packet too short %zd < %zd\n", + len, n + i); + Send_NAK(); + return 0; + } + c = buf[n + i]; + if (got_dle) { + got_dle = 0; + if ('\x10' != c) { + Send_NAK(); + gpsd_report(LOG_RAW + 1, "Garmin: Bad DLE %#02x\n", c); + return 0; + } + } else { + chksum += c; + data_buf[data_index++] = c; + if ('\x10' == c) { + got_dle = 1; + } + } + } + /* get checksum */ + if (len < n + i) { + Send_NAK(); + gpsd_report(LOG_RAW + 1, + "Garmin: No checksum, Packet too short %zd < %zd\n", len, + n + i); + return 0; + } + c = buf[n + i++]; + chksum += c; + /* get final DLE */ + if (len < n + i) { + Send_NAK(); + gpsd_report(LOG_RAW + 1, + "Garmin: No final DLE, Packet too short %zd < %zd\n", len, + n + i); + return 0; + } + c = buf[n + i++]; + if ('\x10' != c) { + Send_NAK(); + gpsd_report(LOG_RAW + 1, "Garmin: Final DLE not DLE\n"); + return 0; + } + /* get final ETX */ + if (len < n + i) { + Send_NAK(); + gpsd_report(LOG_RAW + 1, + "Garmin: No final ETX, Packet too short %zd < %zd\n", len, + n + i); + return 0; + } + c = buf[n + i++]; + if ('\x03' != c) { + Send_NAK(); + gpsd_report(LOG_RAW + 1, "Garmin: Final ETX not ETX\n"); + return 0; + } + + /* debug */ + /*@ -usedef -compdef @*/ + for (i = 0; i < data_index; i++) { + gpsd_report(LOG_RAW + 1, "Garmin: Char: %#02x\n", data_buf[i]); + } + + + gpsd_report(LOG_IO, + "Garmin: garmin_ser_parse() Type: %#02x, Len: %#02x, chksum: %#02x\n", + pkt_id, pkt_len, chksum); + mask = PrintSERPacket(session, pkt_id, pkt_len, data_buf); + + // sending ACK too soon might hang the session + // so send ACK last, after a pause + (void)usleep(300); + Send_ACK(); + /*@ +usedef +compdef @*/ + gpsd_report(LOG_IO, "Garmin: garmin_ser_parse( ) = %s\n", + gpsd_maskdump(mask)); + return mask; +} + +/*@ -charint @*/ + +#ifdef ALLOW_RECONFIGURE +static void settle(void) +{ + struct timespec delay, rem; + /*@ -type -unrecog @*/ + memset(&delay, 0, sizeof(delay)); + delay.tv_sec = 0; + delay.tv_nsec = 333000000L; + nanosleep(&delay, &rem); + /*@ +type +unrecog @*/ +} + +static void garmin_switcher(struct gps_device_t *session, int mode) +{ + if (mode == MODE_NMEA) { + /*@ +charint @*/ + const char switcher[] = + { 0x10, 0x0A, 0x02, 0x26, 0x00, 0xCE, 0x10, 0x03 }; + // Note hard-coded string length in the next line... + int status = (int)gpsd_write(session, switcher, sizeof(switcher)); + /*@ -charint @*/ + if (status == (int)sizeof(switcher)) { + gpsd_report(LOG_IO, + "Garmin: => GPS: turn off binary %02x %02x %02x... \n", + switcher[0], switcher[1], switcher[2]); + } else { + gpsd_report(LOG_ERROR, "Garmin: => GPS: FAILED\n"); + } + settle(); // wait 333mS, essential! + + /* once a sec, no binary, no averaging, NMEA 2.3, WAAS */ + (void)nmea_send(session, "$PGRMC1,1,1"); + //(void)nmea_send(fd, "$PGRMC1,1,1,1,,,,2,W,N"); + (void)nmea_send(session, "$PGRMI,,,,,,,R"); + settle(); // wait 333mS, essential! + } else { + (void)nmea_send(session, "$PGRMC1,1,2,1,,,,2,W,N"); + (void)nmea_send(session, "$PGRMI,,,,,,,R"); + settle(); // wait 333mS, essential! + } +} +#endif /* ALLOW_RECONFIGURE */ + +#ifdef ALLOW_CONTROLSEND +static ssize_t garmin_control_send(struct gps_device_t *session, + char *buf, size_t buflen) +/* not used by the daemon, it's for gpsctl and friends */ +{ + /*@ -mayaliasunique @*/ + session->msgbuflen = buflen; + (void)memcpy(session->msgbuf, buf, buflen); + return gpsd_write(session, session->msgbuf, session->msgbuflen); + /*@ +mayaliasunique @*/ +} +#endif /* ALLOW_CONTROLSEND */ + +#ifdef NTPSHM_ENABLE +static double garmin_ntp_offset(struct gps_device_t *session) +{ + if (session->sourcetype == source_usb) { + return 0.035; /* Garmin USB, expect +/- 40mS jitter */ + } + /* only two sentences ships time */ + /* but the PVT data is always first */ + switch (session->gpsdata.dev.baudrate) { + case 4800: + return 0.430; /* TBD */ + case 9600: + return 0.430; /* tested 12Arp10 */ + case 19200: + return 0.430; /* TBD */ + case 38400: + return 0.430; /* TBD */ + } + return 0.430; /* WTF? WAG */ +} +#endif /* NTPSHM_ENABLE */ + +/* this is everything we export */ +#ifdef __UNUSED__ +static int GetPacket(struct gps_device_t *session); +//----------------------------------------------------------------------------- +// Gets a single packet. +// this is odd, the garmin usb driver will only return 64 bytes, or less +// at a time, no matter what you ask for. +// +// is you ask for less than 64 bytes then the next packet will include +// just the remaining bytes of the last 64 byte packet. +// +// Reading a packet of length Zero, or less than 64, signals the end of +// the entire packet. +// +// The Garmin sample WinXX code also assumes the same behavior, so +// maybe it is something in the USB protocol. +// +// Return: 0 = got a good packet +// -1 = error +// 1 = got partial packet +static int GetPacket(struct gps_device_t *session) +{ + struct timespec delay, rem; + int cnt = 0; + // int x = 0; // for debug dump + + memset(session->driver.garmin.Buffer, 0, sizeof(Packet_t)); + memset(&delay, 0, sizeof(delay)); + session->driver.garmin.BufferLen = 0; + session->packet.outbuflen = 0; + + gpsd_report(LOG_IO, "Garmin: GetPacket()\n"); + + for (cnt = 0; cnt < 10; cnt++) { + size_t pkt_size; + // Read async data until the driver returns less than the + // max async data size, which signifies the end of a packet + + // not optimal, but given the speed and packet nature of + // the USB not too bad for a start + ssize_t theBytesReturned = 0; + uint8_t *buf = (uint8_t *) session->driver.garmin.Buffer; + Packet_t *thePacket = (Packet_t *) buf; + + theBytesReturned = + read(session->gpsdata.gps_fd, + buf + session->driver.garmin.BufferLen, ASYNC_DATA_SIZE); + // zero byte returned is a legal value and denotes the end of a + // binary packet. + if (0 > theBytesReturned) { + // read error... + // or EAGAIN, but O_NONBLOCK is never set + gpsd_report(LOG_ERROR, + "Garmin: GetPacket() read error=%d, errno=%d\n", + theBytesReturned, errno); + continue; + } + gpsd_report(LOG_RAW, "Garmin: got %d bytes\n", theBytesReturned); +#if 1 + gpsd_report(LOG_IO, "Garmin: getPacket(), got %d bytes: %s\n", + theBytesReturned, + gpsd_hexdump_wrapper(thePacket, theBytesReturned, + LOG_IO)); +#endif + + session->driver.garmin.BufferLen += theBytesReturned; + if (256 <= session->driver.garmin.BufferLen) { + // really bad read error... + gpsd_report(LOG_ERROR, + "Garmin: GetPacket() packet too long, %ld > 255 !\n", + session->driver.garmin.BufferLen); + session->driver.garmin.BufferLen = 0; + break; + } + pkt_size = 12 + get_int32((uint8_t *) & thePacket->mDataSize); + if (12 <= session->driver.garmin.BufferLen) { + // have enough data to check packet size + if (session->driver.garmin.BufferLen > pkt_size) { + // wrong amount of data in buffer + gpsd_report(LOG_ERROR, + "Garmin: GetPacket() packet size wrong! Packet: %ld, s/b %ld\n", + session->driver.garmin.BufferLen, pkt_size); + session->driver.garmin.BufferLen = 0; + break; + } + } + if (64 > theBytesReturned) { + // zero length, or short, read is a flag for got the whole packet + break; + } + + + /*@ ignore @*/ + delay.tv_sec = 0; + delay.tv_nsec = 3330000L; + while (nanosleep(&delay, &rem) == -1) + continue; + /*@ end @*/ + } + // dump the individual bytes, debug only + // for ( x = 0; x < session->driver.garmin.BufferLen; x++ ) { + // gpsd_report(LOG_RAW+1, "Garmin: p[%d] = %x\n", x, session->driver.garmin.Buffer[x]); + // } + if (10 <= cnt) { + gpsd_report(LOG_ERROR, + "Garmin: GetPacket() packet too long or too slow!\n"); + return -1; + } + + gpsd_report(LOG_RAW, "Garmin: GotPacket() sz=%d \n", + session->driver.garmin.BufferLen); + session->packet.outbuflen = session->driver.garmin.BufferLen; + return 0; +} + +static gps_mask_t garmin_usb_parse(struct gps_device_t *session) +{ + gpsd_report(LOG_PROG, "Garmin: garmin_usb_parse()\n"); + return PrintUSBPacket(session, + (Packet_t *) session->driver.garmin.Buffer); +} + +static ssize_t garmin_get_packet(struct gps_device_t *session) +{ + return (ssize_t) (0 == GetPacket(session) ? 1 : 0); +} + +/* *INDENT-OFF* */ +const struct gps_type_t garmin_usb_binary_old = +{ + .type_name = "Garmin USB binary", /* full name of type */ + .packet_type = GARMIN_PACKET; /* associated lexer packet type */ + .trigger = NULL, /* no trigger, it has a probe */ + .channels = GARMIN_CHANNELS, /* consumer-grade GPS */ + .probe_detect = garmin_usb_detect,/* how to detect at startup time */ + .get_packet = garmin_get_packet,/* how to grab a packet */ + .parse_packet = garmin_usb_parse, /* parse message packets */ + .rtcm_writer = NULL, /* don't send DGPS corrections */ + .event_hook = garmin_event_hook,/* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = garmin_control_send, /* send raw bytes */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = garmin_ntp_offset, +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* __UNUSED__ */ + +/* *INDENT-OFF* */ +const struct gps_type_t garmin_usb_binary = +{ + .type_name = "Garmin USB binary", /* full name of type */ + .packet_type = GARMIN_PACKET, /* associated lexer packet type */ + .trigger = NULL, /* no trigger, it has a probe */ + .channels = GARMIN_CHANNELS, /* consumer-grade GPS */ + .probe_detect = garmin_usb_detect,/* how to detect at startup time */ + .get_packet = generic_get, /* how to grab a packet */ + .parse_packet = garmin_ser_parse, /* parse message packets */ + .rtcm_writer = NULL, /* don't send DGPS corrections */ + .event_hook = garmin_event_hook,/* lifetime ebent handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = NULL, /* Garmin USB Binary has no NMEA */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = garmin_control_send, /* send raw bytes */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = garmin_ntp_offset, +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +const struct gps_type_t garmin_ser_binary = +{ + .type_name = "Garmin Serial binary", /* full name of type */ + .packet_type = GARMIN_PACKET, /* associated lexer packet type */ + .trigger = NULL, /* no trigger, it has a probe */ + .channels = GARMIN_CHANNELS, /* consumer-grade GPS */ + .probe_detect = NULL, /* how to detect at startup time */ + .get_packet = generic_get, /* how to grab a packet */ + .parse_packet = garmin_ser_parse, /* parse message packets */ + .rtcm_writer = NULL, /* don't send DGPS corrections */ + .event_hook = NULL, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = garmin_switcher, /* how to change modes */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = garmin_control_send, /* send raw bytes */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = garmin_ntp_offset, +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ + +#endif /* GARMIN_ENABLE */ diff --git a/driver_garmin_txt.c b/driver_garmin_txt.c new file mode 100644 index 0000000..cec3314 --- /dev/null +++ b/driver_garmin_txt.c @@ -0,0 +1,474 @@ +/* + * Handle the Garmin simple text format supported by some Garmins. + * Tested with the 'Garmin eTrex Legend' device working in 'Text Out' mode. + * + * Protocol info from: + * http://gpsd.berlios.de/vendor-docs/garmin/garmin_simpletext.txt + * http://www.garmin.com/support/commProtocol.html + * + * Code by: Petr Slansky + * all rights abandoned, a thank would be nice if you use this code. + * + * -D 3 = packet trace + * -D 4 = packet details + * -D 5 = more packet details + * -D 6 = very excessive details + * + * limitations: + * very simple protocol, only very basic information + * TODO + * do not have from garmin: + * pdop + * vdop + * magnetic variation + * satellite information + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + */ + +/*************************************************** +Garmin Simple Text Output Format: + +The simple text (ASCII) output contains time, position, and velocity data in +the fixed width fields (not delimited) defined in the following table: + + FIELD DESCRIPTION: WIDTH: NOTES: + ----------------------- ------- ------------------------ + Sentence start 1 Always '@' + ----------------------- ------- ------------------------ + /Year 2 Last two digits of UTC year + | ----------------------- ------- ------------------------ + | Month 2 UTC month, "01".."12" +T | ----------------------- ------- ------------------------ +i | Day 2 UTC day of month, "01".."31" +m | ----------------------- ------- ------------------------ +e | Hour 2 UTC hour, "00".."23" + | ----------------------- ------- ------------------------ + | Minute 2 UTC minute, "00".."59" + | ----------------------- ------- ------------------------ + \Second 2 UTC second, "00".."59" + ----------------------- ------- ------------------------ + /Latitude hemisphere 1 'N' or 'S' + | ----------------------- ------- ------------------------ + | Latitude position 7 WGS84 ddmmmmm, with an implied + | decimal after the 4th digit + | ----------------------- ------- ------------------------ + | Longitude hemishpere 1 'E' or 'W' + | ----------------------- ------- ------------------------ + | Longitude position 8 WGS84 dddmmmmm with an implied +P | decimal after the 5th digit +o | ----------------------- ------- ------------------------ +s | Position status 1 'd' if current 2D differential GPS position +i | 'D' if current 3D differential GPS position +t | 'g' if current 2D GPS position +i | 'G' if current 3D GPS position +o | 'S' if simulated position +n | '_' if invalid position + | ----------------------- ------- ------------------------ + | Horizontal posn error 3 EPH in meters + | ----------------------- ------- ------------------------ + | Altitude sign 1 '+' or '-' + | ----------------------- ------- ------------------------ + | Altitude 5 Height above or below mean + \ sea level in meters + ----------------------- ------- ------------------------ + /East/West velocity 1 'E' or 'W' + | direction + | ----------------------- ------- ------------------------ + | East/West velocity 4 Meters per second in tenths, + | magnitude ("1234" = 123.4 m/s) +V | ----------------------- ------- ------------------------ +e | North/South velocity 1 'N' or 'S' +l | direction +o | ----------------------- ------- ------------------------ +c | North/South velocity 4 Meters per second in tenths, +i | magnitude ("1234" = 123.4 m/s) +t | ----------------------- ------- ------------------------ +y | Vertical velocity 1 'U' or 'D' (up/down) + | direction + | ----------------------- ------- ------------------------ + | Vertical velocity 4 Meters per second in hundredths, + \ magnitude ("1234" = 12.34 m/s) + ----------------------- ------- ------------------------ + Sentence end 2 Carriage return, '0x0D', and + line feed, '0x0A' + ----------------------- ------- ------------------------ + +If a numeric value does not fill its entire field width, the field is padded +with leading '0's (eg. an altitude of 50 meters above MSL will be output as +"+00050"). + +Any or all of the data in the text sentence (except for the sentence start +and sentence end fields) may be replaced with underscores to indicate +invalid data. + +***************************************************/ + +#include + +#include +#include +#include + +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include + +#include "gpsd_config.h" +#if defined (HAVE_SYS_SELECT_H) +#include +#endif + +#if defined(HAVE_STRINGS_H) +#include +#endif + +#include "gpsd.h" +#include "gps.h" +#include "timebase.h" + +#ifdef GARMINTXT_ENABLE + +/* Simple text message is fixed length, 55 chars text data + 2 characters EOL */ +/* buffer for text processing */ +#define TXT_BUFFER_SIZE 13 + +/************************************************************************** + * decode text string to double number, translate prefix to sign + * return 0: OK + * -1: data error + * -2: data not valid + * + * examples: + + * gar_decode(cbuf, 9, "EW", 100000.0, &result); + * E01412345 -> +14.12345 + + * gar_decode(cbuf, 9, "EW", 100000.0, &result); + * W01412345 -> -14.12345 + + * gar_decode(cbuf, 3, "", 10.0, &result); + * 123 -> +12.3 + +**************************************************************************/ +static int gar_decode(const char *data, const size_t length, const char *prefix, const double dividor, /*@out@*/ + double *result) +{ + char buf[10]; + float sign = 1.0; + int preflen = (int)strlen(prefix); + int offset = 1; /* assume one character prefix (E,W,S,N,U,D, etc) */ + long int intresult; + + /* splint is buggy here, thinks buf can be a null pointer */ + /*@ -mustdefine -nullderef -nullpass @*/ + if (length >= sizeof(buf)) { + gpsd_report(LOG_ERROR, "internal buffer too small\n"); + return -1; + } + + bzero(buf, (int)sizeof(buf)); + (void)strncpy(buf, data, length); + gpsd_report(LOG_RAW + 2, "Decoded string: %s\n", buf); + + if (strchr(buf, '_') != NULL) { + /* value is not valid, ignore it */ + return -2; + } + + /* parse prefix */ + do { + if (preflen == 0) { + offset = 0; /* only number, no prefix */ + break; + } + /* second character in prefix is flag for negative number */ + if (preflen >= 2) { + if (buf[0] == prefix[1]) { + sign = -1.0; + break; + } + } + /* first character in prefix is flag for positive number */ + if (preflen >= 1) { + if (buf[0] == prefix[0]) { + sign = 1.0; + break; + } + } + gpsd_report(LOG_WARN, "Unexpected char \"%c\" in data \"%s\"\n", + buf[0], buf); + return -1; + } while (0); + + if (strspn(buf + offset, "0123456789") != length - offset) { + gpsd_report(LOG_WARN, "Invalid value %s\n", buf); + return -1; + } + /*@ +mustdefine +nullderef +nullpass @*/ + + intresult = atol(buf + offset); + if (intresult == 0L) + sign = 0.0; /* don't create negative zero */ + + *result = (double)intresult / dividor * sign; + + return 0; /* SUCCESS */ +} + +/************************************************************************** + * decode integer from string, check if the result is in expected range + * return 0: OK + * -1: data error + * -2: data not valid +**************************************************************************/ +static int gar_int_decode(const char *data, const size_t length, + const unsigned int min, const unsigned int max, + /*@out@*/ unsigned int *result) +{ + char buf[6]; + unsigned int res; + + /*@ -mustdefine @*/ + if (length >= sizeof(buf)) { + gpsd_report(LOG_ERROR, "internal buffer too small\n"); + return -1; + } + + bzero(buf, (int)sizeof(buf)); + (void)strncpy(buf, data, length); + gpsd_report(LOG_RAW + 2, "Decoded string: %s\n", buf); + + if (strchr(buf, '_') != NULL) { + /* value is not valid, ignore it */ + return -2; + } + + /*@ -nullpass @*//* splint bug */ + if (strspn(buf, "0123456789") != length) { + gpsd_report(LOG_WARN, "Invalid value %s\n", buf); + return -1; + } + + res = (unsigned)atoi(buf); + if ((res >= min) && (res <= max)) { + *result = res; + return 0; /* SUCCESS */ + } else { + gpsd_report(LOG_WARN, "Value %u out of range <%u, %u>\n", res, min, + max); + return -1; + } + /*@ +mustdefine +nullpass @*/ +} + + +/************************************************************************** + * + * Entry points begin here + * + **************************************************************************/ + +gps_mask_t garmintxt_parse(struct gps_device_t * session) +{ +/* parse GARMIN Simple Text sentence, unpack it into a session structure */ + + gps_mask_t mask = 0; + + gpsd_report(LOG_PROG, "Garmin Simple Text packet, len %zd\n", + session->packet.outbuflen); + gpsd_report(LOG_RAW, "%s\n", + gpsd_hexdump_wrapper(session->packet.outbuffer, + session->packet.outbuflen, LOG_RAW)); + + if (session->packet.outbuflen < 54) { + /* trailing CR and LF can be ignored; ('@' + 54x 'DATA' + '\r\n') has length 57 */ + gpsd_report(LOG_WARN, "Message is too short, rejected.\n"); + return ONLINE_IS; + } + + session->packet.type = GARMINTXT_PACKET; + /* TAG message as GTXT, Garmin Simple Text Message */ + strncpy(session->gpsdata.tag, "GTXT", MAXTAGLEN); + + /* only one message, set cycle start */ + session->cycle_end_reliable = true; + do { + unsigned int result; + char *buf = (char *)session->packet.outbuffer + 1; + gpsd_report(LOG_PROG, "Timestamp: %.12s\n", buf); + + /* year */ + if (0 != gar_int_decode(buf + 0, 2, 0, 99, &result)) + break; + session->driver.garmintxt.date.tm_year = + (CENTURY_BASE + (int)result) - 1900; + /* month */ + if (0 != gar_int_decode(buf + 2, 2, 1, 12, &result)) + break; + session->driver.garmintxt.date.tm_mon = (int)result - 1; + /* day */ + if (0 != gar_int_decode(buf + 4, 2, 1, 31, &result)) + break; + session->driver.garmintxt.date.tm_mday = (int)result; + /* hour */ + if (0 != gar_int_decode(buf + 6, 2, 0, 23, &result)) + break; + session->driver.garmintxt.date.tm_hour = (int)result; /* mday update?? */ + /* minute */ + if (0 != gar_int_decode(buf + 8, 2, 0, 59, &result)) + break; + session->driver.garmintxt.date.tm_min = (int)result; + /* second */ + /* second value can be even 60, occasional leap second */ + if (0 != gar_int_decode(buf + 10, 2, 0, 60, &result)) + break; + session->driver.garmintxt.date.tm_sec = (int)result; + session->driver.garmintxt.subseconds = 0; + session->newdata.time = + (double)mkgmtime(&session->driver.garmintxt.date) + + session->driver.garmintxt.subseconds; + mask |= TIME_IS; + } while (0); + + /* assume that possition is unknown; if the position is known we will fix status information later */ + session->newdata.mode = MODE_NO_FIX; + session->gpsdata.status = STATUS_NO_FIX; + mask |= MODE_IS | STATUS_IS | CLEAR_IS | REPORT_IS; + + /* process position */ + + do { + double lat, lon; + unsigned int degfrag; + char status; + + /* Latitude, [NS]ddmmmmm */ + /* decode degrees of Latitude */ + if (0 != + gar_decode((char *)session->packet.outbuffer + 13, 3, "NS", 1.0, + &lat)) + break; + /* decode minutes of Latitude */ + if (0 != + gar_int_decode((char *)session->packet.outbuffer + 16, 5, 0, + 99999, °frag)) + break; + lat += degfrag * 100.0 / 60.0 / 100000.0; + session->newdata.latitude = lat; + + /* Longitude, [EW]dddmmmmm */ + /* decode degrees of Longitude */ + if (0 != + gar_decode((char *)session->packet.outbuffer + 21, 4, "EW", 1.0, + &lon)) + break; + /* decode minutes of Longitude */ + if (0 != + gar_int_decode((char *)session->packet.outbuffer + 25, 5, 0, + 99999, °frag)) + break; + lon += degfrag * 100.0 / 60.0 / 100000.0; + session->newdata.longitude = lon; + + /* fix mode, GPS status, [gGdDS_] */ + status = (char)session->packet.outbuffer[30]; + + switch (status) { + case 'G': + case 'S': /* 'S' is DEMO mode, assume 3D position */ + session->newdata.mode = MODE_3D; + session->gpsdata.status = STATUS_FIX; + break; + case 'D': + session->newdata.mode = MODE_3D; + session->gpsdata.status = STATUS_DGPS_FIX; + break; + case 'g': + session->newdata.mode = MODE_2D; + session->gpsdata.status = STATUS_FIX; + break; + case 'd': + session->newdata.mode = MODE_2D; + session->gpsdata.status = STATUS_DGPS_FIX; + break; + default: + session->newdata.mode = MODE_NO_FIX; + session->gpsdata.status = STATUS_NO_FIX; + } + mask |= MODE_IS | STATUS_IS | LATLON_IS; + } while (0); + + /* EPH */ + do { + double eph; + if (0 != + gar_decode((char *)session->packet.outbuffer + 31, 3, "", 1.0, + &eph)) + break; + /* eph is a circular error, sqrt(epx**2 + epy**2) */ + session->newdata.epx = session->newdata.epy = + eph * (1 / sqrt(2)) * (GPSD_CONFIDENCE / CEP50_SIGMA); + mask |= HERR_IS; + } while (0); + + /* Altitude */ + do { + double alt; + if (0 != + gar_decode((char *)session->packet.outbuffer + 34, 6, "+-", 1.0, + &alt)) + break; + session->newdata.altitude = alt; + mask |= ALTITUDE_IS; + } while (0); + + /* Velocity */ + do { + double ewvel, nsvel, speed, track; + if (0 != + gar_decode((char *)session->packet.outbuffer + 40, 5, "EW", 10.0, + &ewvel)) + break; + if (0 != + gar_decode((char *)session->packet.outbuffer + 45, 5, "NS", 10.0, + &nsvel)) + break; + speed = sqrt(ewvel * ewvel + nsvel * nsvel); /* is this correct formula? Result is in mps */ + session->newdata.speed = speed; + track = atan2(ewvel, nsvel) * RAD_2_DEG; /* is this correct formula? Result is in degrees */ + if (track < 0.0) + track += 360.0; + session->newdata.track = track; + mask |= SPEED_IS | TRACK_IS; + } while (0); + + + /* Climb (vertical velocity) */ + do { + double climb; + if (0 != + gar_decode((char *)session->packet.outbuffer + 50, 5, "UD", 100.0, + &climb)) + break; + session->newdata.climb = climb; /* climb in mps */ + mask |= CLIMB_IS; + } while (0); + + gpsd_report(LOG_DATA, + "GTXT: time=%.2f, lat=%.2f lon=%.2f alt=%.2f speed=%.2f track=%.2f climb=%.2f exp=%.2f epy=%.2f mode=%d status=%d mask=%s\n", + session->newdata.time, session->newdata.latitude, + session->newdata.longitude, session->newdata.altitude, + session->newdata.speed, session->newdata.track, + session->newdata.climb, session->newdata.epx, + session->newdata.epy, session->newdata.mode, + session->gpsdata.status, gpsd_maskdump(mask)); + return mask; +} + +#endif /* GARMINTXT_ENABLE */ diff --git a/driver_italk.c b/driver_italk.c new file mode 100644 index 0000000..847adb0 --- /dev/null +++ b/driver_italk.c @@ -0,0 +1,525 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + * Driver for the iTalk binary protocol used by FasTrax + */ +#include +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include + +#include "gpsd.h" +#if defined(ITRAX_ENABLE) && defined(BINARY_ENABLE) + +#include "bits.h" +#include "driver_italk.h" + +static gps_mask_t italk_parse(struct gps_device_t *, unsigned char *, size_t); +static gps_mask_t decode_itk_navfix(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t decode_itk_prnstatus(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t decode_itk_utcionomodel(struct gps_device_t *, + unsigned char *, size_t); +static gps_mask_t decode_itk_subframe(struct gps_device_t *, unsigned char *, + size_t); + +static gps_mask_t decode_itk_navfix(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + unsigned int tow; + unsigned short gps_week, flags, cflags, pflags; + gps_mask_t mask = 0; + double epx, epy, epz, evx, evy, evz, eph; + double t; + + if (len != 296) { + gpsd_report(LOG_PROG, "ITALK: bad NAV_FIX (len %zu, should be 296)\n", + len); + return -1; + } + + flags = (ushort) getleuw(buf, 7 + 4); + cflags = (ushort) getleuw(buf, 7 + 6); + pflags = (ushort) getleuw(buf, 7 + 8); + + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + mask = ONLINE_IS | MODE_IS | STATUS_IS | CLEAR_IS; + + /* just bail out if this fix is not marked valid */ + if (0 != (pflags & FIX_FLAG_MASK_INVALID) + || 0 == (flags & FIXINFO_FLAG_VALID)) + return mask; + + gps_week = (ushort) getlesw(buf, 7 + 82); + session->context->gps_week = gps_week; + tow = (uint) getleul(buf, 7 + 84); + session->context->gps_tow = tow / 1000.0; + t = gpstime_to_unix((int)gps_week, session->context->gps_tow) + - session->context->leap_seconds; + session->newdata.time = t; + mask |= TIME_IS; + + epx = (double)(getlesl(buf, 7 + 96) / 100.0); + epy = (double)(getlesl(buf, 7 + 100) / 100.0); + epz = (double)(getlesl(buf, 7 + 104) / 100.0); + evx = (double)(getlesl(buf, 7 + 186) / 1000.0); + evy = (double)(getlesl(buf, 7 + 190) / 1000.0); + evz = (double)(getlesl(buf, 7 + 194) / 1000.0); + ecef_to_wgs84fix(&session->newdata, &session->gpsdata.separation, + epx, epy, epz, evx, evy, evz); + mask |= LATLON_IS | ALTITUDE_IS | SPEED_IS | TRACK_IS | CLIMB_IS; + eph = (double)(getlesl(buf, 7 + 252) / 100.0); + /* eph is a circular error, sqrt(epx**2 + epy**2) */ + session->newdata.epx = session->newdata.epy = eph / sqrt(2); + session->newdata.eps = (double)(getlesl(buf, 7 + 254) / 100.0); + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) + session->gpsdata.satellites_used = + (int)MAX(getleuw(buf, 7 + 12), getleuw(buf, 7 + 14)); + mask |= USED_IS; + + if (flags & FIX_CONV_DOP_VALID) { + session->gpsdata.dop.hdop = (double)(getleuw(buf, 7 + 56) / 100.0); + session->gpsdata.dop.gdop = (double)(getleuw(buf, 7 + 58) / 100.0); + session->gpsdata.dop.pdop = (double)(getleuw(buf, 7 + 60) / 100.0); + session->gpsdata.dop.vdop = (double)(getleuw(buf, 7 + 62) / 100.0); + session->gpsdata.dop.tdop = (double)(getleuw(buf, 7 + 64) / 100.0); + mask |= DOP_IS; + } + + if ((pflags & FIX_FLAG_MASK_INVALID) == 0 + && (flags & FIXINFO_FLAG_VALID) != 0) { + if (pflags & FIX_FLAG_3DFIX) + session->newdata.mode = MODE_3D; + else + session->newdata.mode = MODE_2D; + + if (pflags & FIX_FLAG_DGPS_CORRECTION) + session->gpsdata.status = STATUS_DGPS_FIX; + else + session->gpsdata.status = STATUS_FIX; + } + + gpsd_report(LOG_DATA, + "NAV_FIX: time=%.2f, lat=%.2f lon=%.2f alt=%.f speed=%.2f track=%.2f climb=%.2f mode=%d status=%d gdop=%.2f pdop=%.2f hdop=%.2f vdop=%.2f tdop=%.2f mask=%s\n", + session->newdata.time, session->newdata.latitude, + session->newdata.longitude, session->newdata.altitude, + session->newdata.speed, session->newdata.track, + session->newdata.climb, session->newdata.mode, + session->gpsdata.status, session->gpsdata.dop.gdop, + session->gpsdata.dop.pdop, session->gpsdata.dop.hdop, + session->gpsdata.dop.vdop, session->gpsdata.dop.tdop, + gpsd_maskdump(mask)); + return mask; +} + +static gps_mask_t decode_itk_prnstatus(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + unsigned int i, tow, nsv, nchan, st; + unsigned short gps_week; + double t; + gps_mask_t mask; + + if (len < 62) { + gpsd_report(LOG_PROG, "ITALK: runt PRN_STATUS (len=%zu)\n", len); + mask = 0; + } else { + gps_week = (ushort) getleuw(buf, 7 + 4); + session->context->gps_week = gps_week; + tow = (uint) getleul(buf, 7 + 6); + session->context->gps_tow = tow / 1000.0; + t = gpstime_to_unix((int)gps_week, session->context->gps_tow) + - session->context->leap_seconds; + session->gpsdata.skyview_time = t; + + gpsd_zero_satellites(&session->gpsdata); + nsv = 0; + nchan = (unsigned int)getleuw(buf, 7 + 50); + if (nchan > MAX_NR_VISIBLE_PRNS) + nchan = MAX_NR_VISIBLE_PRNS; + for (i = st = 0; i < nchan; i++) { + unsigned int off = 7 + 52 + 10 * i; + unsigned short flags; + + flags = (ushort) getleuw(buf, off); + session->gpsdata.ss[i] = (float)(getleuw(buf, off + 2) & 0xff); + session->gpsdata.PRN[i] = (int)getleuw(buf, off + 4) & 0xff; + session->gpsdata.elevation[i] = (int)getlesw(buf, off + 6) & 0xff; + session->gpsdata.azimuth[i] = (int)getlesw(buf, off + 8) & 0xff; + if (session->gpsdata.PRN[i]) { + st++; + if (flags & PRN_FLAG_USE_IN_NAV) + session->gpsdata.used[nsv++] = session->gpsdata.PRN[i]; + } + } + session->gpsdata.satellites_visible = (int)st; + session->gpsdata.satellites_used = (int)nsv; + mask = USED_IS | SATELLITE_IS;; + + gpsd_report(LOG_DATA, + "PRN_STATUS: time=%.2f visible=%d used=%d mask={USED|SATELLITE}\n", + session->newdata.time, + session->gpsdata.satellites_visible, + session->gpsdata.satellites_used); + } + + return mask; +} + +static gps_mask_t decode_itk_utcionomodel(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + unsigned int tow; + int leap; + unsigned short gps_week, flags; + double t; + + if (len != 64) { + gpsd_report(LOG_PROG, + "ITALK: bad UTC_IONO_MODEL (len %zu, should be 64)\n", + len); + return 0; + } + + flags = (ushort) getleuw(buf, 7); + if (0 == (flags & UTC_IONO_MODEL_UTCVALID)) + return 0; + + leap = (int)getleuw(buf, 7 + 24); + if (session->context->leap_seconds < leap) + session->context->leap_seconds = leap; + + gps_week = (ushort) getleuw(buf, 7 + 36); + session->context->gps_week = gps_week; + tow = (uint) getleul(buf, 7 + 38); + session->context->gps_tow = tow / 1000.0; + t = gpstime_to_unix((int)gps_week, session->context->gps_tow) + - session->context->leap_seconds; + session->newdata.time = t; + + gpsd_report(LOG_DATA, + "UTC_IONO_MODEL: time=%.2f mask={TIME}\n", + session->newdata.time); + return TIME_IS; +} + +static gps_mask_t decode_itk_subframe(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + unsigned short flags, prn, sf; + unsigned int i, words[10]; + + if (len != 64) { + gpsd_report(LOG_PROG, + "ITALK: bad SUBFRAME (len %zu, should be 64)\n", len); + return 0; + } + + flags = (ushort) getleuw(buf, 7 + 4); + prn = (ushort) getleuw(buf, 7 + 6); + sf = (ushort) getleuw(buf, 7 + 8); + gpsd_report(LOG_PROG, "iTalk 50B SUBFRAME prn %u sf %u - decode %s %s\n", + prn, sf, + flags & SUBFRAME_WORD_FLAG_MASK ? "error" : "ok", + flags & SUBFRAME_GPS_PREAMBLE_INVERTED ? "(inverted)" : ""); + if (flags & SUBFRAME_WORD_FLAG_MASK) + return 0; // don't try decode an erroneous packet + + /* + * Timo says "SUBRAME message contains decoded navigation message subframe + * words with parity checking done but parity bits still present." + */ + for (i = 0; i < 10; i++) + words[i] = + (unsigned int)(getleul(buf, 7 + 14 + 4 * i) >> 6) & 0xffffff; + + gpsd_interpret_subframe(session, words); + return ONLINE_IS; +} + +static gps_mask_t decode_itk_pseudo(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + unsigned short gps_week, flags, n, i; + unsigned int tow; + union long_double l_d; + double t; + + n = (ushort) getleuw(buf, 7 + 4); + if ((n < 1) || (n > MAXCHANNELS)){ + gpsd_report(LOG_INF, "ITALK: bad PSEUDO channel count\n"); + return 0; + } + + if (len != (size_t)((n+1)*36)) { + gpsd_report(LOG_PROG, + "ITALK: bad PSEUDO len %zu\n", len); + } + + gpsd_report(LOG_PROG, "iTalk PSEUDO [%u]\n", n); + flags = (unsigned short)getleuw(buf, 7 + 6); + if ((flags & 0x3) != 0x3) + return 0; // bail if measurement time not valid. + + gps_week = (ushort) getleuw(buf, 7 + 8); + tow = (uint) getleul(buf, 7 + 38); + session->context->gps_week = gps_week; + session->context->gps_tow = tow / 1000.0; + t = gpstime_to_unix((int)gps_week, session->context->gps_tow) + - session->context->leap_seconds; + + /*@-type@*/ + for (i = 0; i < n; i++){ + session->gpsdata.PRN[i] = getleuw(buf, 7 + 26 + (i*36)) & 0xff; + session->gpsdata.ss[i] = getleuw(buf, 7 + 26 + (i*36 + 2)) & 0x3f; + session->gpsdata.raw.satstat[i] = getleul(buf, 7 + 26 + (i*36 + 4)); + session->gpsdata.raw.pseudorange[i] = getled(buf, 7 + 26 + (i*36 + 8)); + session->gpsdata.raw.doppler[i] = getled(buf, 7 + 26 + (i*36 + 16)); + session->gpsdata.raw.carrierphase[i] = getleuw(buf, 7 + 26 + (i*36 + 28)); + + session->gpsdata.raw.mtime[i] = t; + session->gpsdata.raw.codephase[i] = NAN; + session->gpsdata.raw.deltarange[i] = NAN; + } + /*@+type@*/ + return RAW_IS; +} + +/*@ +charint @*/ +static gps_mask_t italk_parse(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + unsigned int type; + gps_mask_t mask = 0; + + if (len == 0) + return 0; + + type = (uint) getub(buf, 4); + /* we may need to dump the raw packet */ + gpsd_report(LOG_RAW, "raw italk packet type 0x%02x length %zu: %s\n", + type, len, gpsd_hexdump_wrapper(buf, len, LOG_RAW)); + + session->cycle_end_reliable = true; + + switch (type) { + case ITALK_NAV_FIX: + gpsd_report(LOG_IO, "iTalk NAV_FIX len %zu\n", len); + mask = decode_itk_navfix(session, buf, len) | (CLEAR_IS | REPORT_IS); + break; + case ITALK_PRN_STATUS: + gpsd_report(LOG_IO, "iTalk PRN_STATUS len %zu\n", len); + mask = decode_itk_prnstatus(session, buf, len); + break; + case ITALK_UTC_IONO_MODEL: + gpsd_report(LOG_IO, "iTalk UTC_IONO_MODEL len %zu\n", len); + mask = decode_itk_utcionomodel(session, buf, len); + break; + + case ITALK_ACQ_DATA: + gpsd_report(LOG_IO, "iTalk ACQ_DATA len %zu\n", len); + break; + case ITALK_TRACK: + gpsd_report(LOG_IO, "iTalk TRACK len %zu\n", len); + break; + case ITALK_PSEUDO: + gpsd_report(LOG_IO, "iTalk PSEUDO len %zu\n", len); + mask = decode_itk_pseudo(session, buf, len); + break; + case ITALK_RAW_ALMANAC: + gpsd_report(LOG_IO, "iTalk RAW_ALMANAC len %zu\n", len); + break; + case ITALK_RAW_EPHEMERIS: + gpsd_report(LOG_IO, "iTalk RAW_EPHEMERIS len %zu\n", len); + break; + case ITALK_SUBFRAME: + mask = decode_itk_subframe(session, buf, len); + break; + case ITALK_BIT_STREAM: + gpsd_report(LOG_IO, "iTalk BIT_STREAM len %zu\n", len); + break; + + case ITALK_AGC: + case ITALK_SV_HEALTH: + case ITALK_PRN_PRED: + case ITALK_FREQ_PRED: + case ITALK_DBGTRACE: + case ITALK_START: + case ITALK_STOP: + case ITALK_SLEEP: + case ITALK_STATUS: + case ITALK_ITALK_CONF: + case ITALK_SYSINFO: + case ITALK_ITALK_TASK_ROUTE: + case ITALK_PARAM_CTRL: + case ITALK_PARAMS_CHANGED: + case ITALK_START_COMPLETED: + case ITALK_STOP_COMPLETED: + case ITALK_LOG_CMD: + case ITALK_SYSTEM_START: + case ITALK_STOP_SEARCH: + case ITALK_SEARCH: + case ITALK_PRED_SEARCH: + case ITALK_SEARCH_DONE: + case ITALK_TRACK_DROP: + case ITALK_TRACK_STATUS: + case ITALK_HANDOVER_DATA: + case ITALK_CORE_SYNC: + case ITALK_WAAS_RAWDATA: + case ITALK_ASSISTANCE: + case ITALK_PULL_FIX: + case ITALK_MEMCTRL: + case ITALK_STOP_TASK: + gpsd_report(LOG_IO, + "iTalk not processing packet: id 0x%02x length %zu\n", + type, len); + break; + default: + gpsd_report(LOG_IO, "iTalk unknown packet: id 0x%02x length %zu\n", + type, len); + } + (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), + "ITK-%02x", type); + + return mask | ONLINE_IS; +} + +/*@ -charint @*/ + +static gps_mask_t italk_parse_input(struct gps_device_t *session) +{ + gps_mask_t st; + + if (session->packet.type == ITALK_PACKET) { + st = italk_parse(session, session->packet.outbuffer, + session->packet.outbuflen); + session->gpsdata.dev.driver_mode = MODE_BINARY; /* binary */ + return st; +#ifdef NMEA_ENABLE + } else if (session->packet.type == NMEA_PACKET) { + st = nmea_parse((char *)session->packet.outbuffer, session); + session->gpsdata.dev.driver_mode = MODE_NMEA; /* NMEA */ + return st; +#endif /* NMEA_ENABLE */ + } else + return 0; +} + +#ifdef ALLOW_CONTROLSEND +/*@ +charint -usedef -compdef @*/ +static ssize_t italk_control_send(struct gps_device_t *session, + char *msg, size_t msglen) +{ + ssize_t status; + + /*@ -mayaliasunique @*/ + session->msgbuflen = msglen; + (void)memcpy(session->msgbuf, msg, msglen); + /*@ +mayaliasunique @*/ + /* we may need to dump the message */ + gpsd_report(LOG_IO, "writing italk control type %02x:%s\n", + msg[0], gpsd_hexdump_wrapper(msg, msglen, LOG_IO)); + status = write(session->gpsdata.gps_fd, msg, msglen); + (void)tcdrain(session->gpsdata.gps_fd); + return status; +} + +/*@ -charint +usedef +compdef @*/ +#endif /* ALLOW_CONTROLSEND */ + +static bool italk_set_mode(struct gps_device_t *session UNUSED, + speed_t speed UNUSED, + char parity UNUSED, int stopbits UNUSED, + bool mode UNUSED) +{ +#ifdef __NOT_YET__ + /*@ +charint @*/ + char msg[] = { 0, }; + + /* HACK THE MESSAGE */ + + return (italk_control_send(session, msg, sizeof(msg)) != -1); + /*@ +charint @*/ +#endif + + return false; /* until this actually works */ +} + +#ifdef ALLOW_RECONFIGURE +static bool italk_speed(struct gps_device_t *session, + speed_t speed, char parity, int stopbits) +{ + return italk_set_mode(session, speed, parity, stopbits, true); +} + +static void italk_mode(struct gps_device_t *session, int mode) +{ + if (mode == MODE_NMEA) { + (void)italk_set_mode(session, + session->gpsdata.dev.baudrate, + (char)session->gpsdata.dev.parity, + (int)session->gpsdata.dev.stopbits, false); + } +} +#endif /* ALLOW_RECONFIGURE */ + +static void italk_event_hook(struct gps_device_t *session, event_t event) +{ + /* + * FIX-ME: It might not be necessary to call this on reactivate. + * Experiment to see if the holds its settings through a close. + */ + if ((event == event_identified || event == event_reactivate) + && session->packet.type == NMEA_PACKET) + (void)italk_set_mode(session, session->gpsdata.dev.baudrate, + (char)session->gpsdata.dev.parity, + (int)session->gpsdata.dev.stopbits, true); +} + +#ifdef __not_yet__ +static void italk_ping(struct gps_device_t *session) +/* send a "ping". it may help us detect an itrax more quickly */ +{ + char *ping = ""; + (void)gpsd_write(session, ping, 3); +} +#endif /* __not_yet__ */ + +/* *INDENT-OFF* */ +const struct gps_type_t italk_binary = +{ + .type_name = "iTalk binary", /* full name of type */ + .packet_type = ITALK_PACKET, /* associated lexer packet type */ + .trigger = NULL, /* recognize the type */ + .channels = 12, /* consumer-grade GPS */ + .probe_detect = NULL, /* how to detect at startup time */ + .get_packet = generic_get, /* use generic packet grabber */ + .parse_packet = italk_parse_input,/* parse message packets */ + .rtcm_writer = pass_rtcm, /* send RTCM data straight */ + .event_hook = italk_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = italk_speed, /* we can change baud rates */ + .mode_switcher = italk_mode, /* there is a mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = italk_control_send, /* how to send a control string */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* defined(ITRAX_ENABLE) && defined(BINARY_ENABLE) */ diff --git a/driver_italk.h b/driver_italk.h new file mode 100644 index 0000000..b0ed9f5 --- /dev/null +++ b/driver_italk.h @@ -0,0 +1,544 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#ifndef _GPSD_ITALK_H_ +#define _GPSD_ITALK_H_ + +/* 0 and 1 are responses to the ping for iTalk and NMEA respectively */ +#define PROTO_ITALK 0 +#define PROTO_NMEA 1 + +/* + * Assistance from Timo Ylhainen of Fastrax is acknowledged and appreciated. + * + * iTalk is a messaging system which communicates between tasks, which may + * be running on different devices (nodes). For our purposes (receiver + * configuration), we will probably be sending to the SYSTEM task. + */ + +#define TASK_MASK 0x1f /* 5 low bits of src/dst fields */ +#define NODE_MASK 0xe0 /* 3 high bits of src/dst fields */ +#define NODE_UNDEF 0x00 /* Used in message routing */ +#define NODE_ITRAX 0x20 /* The receiver */ +#define NODE_HOST 0x40 /* Software on your computer */ +#define NODE_GPSWB 0x60 /* GPSWorkbench seems to be HOST|ITRAX */ + +/* FIX-ME: These defines will likely be replaced by an enum + * once I map every message to the task that sent it. + */ +/* System controller on the receiver */ +#define TASK_SYSTEM 0 +/* Acquisition & Tracking messages (PD) */ +#define TASK_TRACK1 2 +#define TASK_TRACK2 3 +/* Data decoding messages (PD) */ +#define TASK_DATA 4 +/* Navigation messages are sent by these tasks (PD) */ +#define TASK_NAV1 7 +#define TASK_NAV2 8 +#define TASK_NAV3 9 +/* Host controller software (PD) */ +#define TASK_HOST 31 + +#define MAX_NR_VISIBLE_PRNS 16 + +/* iTalk Message IDs - isuite.fastrax.fi/sdk/331/Protocols/PRO_MsgId.html */ +#define ITALK_ACQ_DATA 1 +#define ITALK_PRN_STATUS 2 +#define ITALK_TRACK 3 +#define ITALK_PSEUDO 4 +#define ITALK_AGC 6 +#define ITALK_NAV_FIX 7 +#define ITALK_RAW_ALMANAC 9 +#define ITALK_RAW_EPHEMERIS 10 +#define ITALK_SV_HEALTH 11 +#define ITALK_UTC_IONO_MODEL 12 +#define ITALK_PRN_PRED 13 +#define ITALK_FREQ_PRED 14 +#define ITALK_SUBFRAME 15 +#define ITALK_BIT_STREAM 18 +#define ITALK_DBGTRACE 19 +#define ITALK_START 64 +#define ITALK_STOP 65 +#define ITALK_SLEEP 66 +#define ITALK_STATUS 67 +#define ITALK_ITALK_CONF 68 +#define ITALK_SYSINFO 69 +#define ITALK_ITALK_TASK_ROUTE 70 +#define ITALK_PARAM_CTRL 71 +#define ITALK_PARAMS_CHANGED 72 +#define ITALK_START_COMPLETED 73 +#define ITALK_STOP_COMPLETED 74 +#define ITALK_LOG_CMD 75 +#define ITALK_SYSTEM_START 76 +#define ITALK_STOP_SEARCH 79 +#define ITALK_SEARCH 80 +#define ITALK_PRED_SEARCH 81 +#define ITALK_SEARCH_DONE 82 +#define ITALK_TRACK_DROP 88 +#define ITALK_TRACK_STATUS 90 +#define ITALK_HANDOVER_DATA 92 +#define ITALK_CORE_SYNC 93 +#define ITALK_WAAS_RAWDATA 96 +#define ITALK_ASSISTANCE 98 +#define ITALK_PULL_FIX 99 +#define ITALK_MEMCTRL 112 +#define ITALK_STOP_TASK 255 + +/* NAV_FIX */ +#define FIX_CONV_VEL_VALID 0x0002 +#define FIX_CONV_ACC_VALID 0x0004 +#define FIX_CONV_DOP_VALID 0x0010 +#define FIX_CONV_ERR_VALID 0x0020 +#define FIX_CONV_UTC_VALID 0x0040 +#define FIX_CONV_UND_VALID 0x0080 +#define FIX_CONV_MAG_VALID 0x0100 +#define FIX_CONV_GRID_VALID 0x0200 +#define FIX_CONV_VEL_ESTIMATED 0x0400 + +#define FIX_FLAG_POS_REJECT_FOM 0x0003 +#define FIX_FLAG_POS_REJECT_DOP 0x0004 +#define FIX_FLAG_POS_PINNING 0x0020 + +#define FIX_FLAG_VEL_REJECT_RES 0x0003 +#define FIX_FLAG_ACCELERATION 0x4000 +#define FIX_FLAG_VEL_RELIABLE 0x0020 +#define FIX_FLAG_VEL_RELIABLE_3D 0x0040 + +#define FIX_FLAG_MASK_INVALID 0x0007 +#define FIX_FLAG_REJECT_NUM_SV 0x0001 +#define FIX_FLAG_REJECT_POSTRAIM 0x0002 +#define FIX_FLAG_REJECT_OTHER 0x0007 +#define FIX_FLAG_RELIABLE 0x0008 +#define FIX_FLAG_PF_RAIM 0x0010 +#define FIX_FLAG_3DFIX 0x0100 +#define FIX_FLAG_DGPS_CORRECTION 0x0200 +#define FIX_FLAG_TROPO 0x0400 +#define FIX_FLAG_IONO 0x0800 +#define FIX_FLAG_INS 0x2000 + +#define FIXINFO_FLAG_VALID 0x0002 +#define FIXINFO_FLAG_NEW_FIX 0x0004 +#define FIXINFO_FLAG_SKY_FIX 0x0008 +#define FIXINFO_FLAG_AID_GPSTIME 0x0010 +#define FIXINFO_FLAG_AID_TIMESTAMP 0x0020 +#define FIXINFO_FLAG_AID_EPHEMERIS 0x0040 +#define FIXINFO_FLAG_AID_ALTITUDE 0x0080 +#define FIXINFO_FLAG_KALMAN 0x1000 +#define FIXINFO_FLAG_INTERNAL 0x2000 +#define FIXINFO_FLAG_FIRSTFIX 0x4000 + +/* PRN_STATUS */ +#define PRN_FLAG_FOUND 0x0001 +#define PRN_FLAG_TRACKING 0x0002 +#define PRN_FLAG_USE_IN_NAV 0x0004 + +/* UTC_IONO_MODEL */ +#define UTC_IONO_MODEL_UTCVALID 0x0001 +#define UTC_IONO_MODEL_IONOVALID 0x0002 + +/* SUBFRAME */ +#define SUBFRAME_WORD_FLAG_MASK 0x03ff +#define SUBFRAME_GPS_PREAMBLE_INVERTED 0x0400 + +/* PSEUDO */ +#define PSEUDO_OBS_DOPPLER_OK 0x0001 +#define PSEUDO_OBS_PSEUDORANGE_OK 0x0002 +#define PSEUDO_OBS_TOW_OK 0x0004 +#define PSEUDO_OBS_PRN_OK 0x0008 +#define PSEUDO_OBS_ELEV_OK 0x0010 +#define PSEUDO_OBS_SNR_OK 0x0020 +#define PSEUDO_OBS_SV_HEALTHY 0x0040 +#define PSEUDO_OBS_NO_CROSS_CORR 0x0080 +#define PSEUDO_OBS_DATA_EXISTS 0x0100 +#define PSEUDO_OBS_DATA_GOOD 0x0200 +#define PSEUDO_OBS_BIT_LOCK 0x0400 +#define PSEUDO_OBS_FIRST_MEAS 0x0800 +#define PSEUDO_OBS_RAIM_P_OK 0x1000 +#define PSEUDO_OBS_RAIM_V_OK 0x2000 +#define PSEUDO_OBS_RAIM_T_OK 0x4000 +#define PSEUDO_OBS_PLL 0x8000 +#define PSEUDO_OBS_MEAS_OK ( PSEUDO_OBS_ELEV_OK | PSEUDO_OBS_SNR_OK | PSEUDO_OBS_PRN_OK | PSEUDO_OBS_NO_CROSS_CORR | PSEUDO_OBS_SV_HEALTHY | PSEUDO_OBS_DATA_EXISTS | PSEUDO_OBS_DATA_GOOD | PSEUDO_OBS_PSEUDORANGE_OK ) +#define PSEUDO_OBS_DOPPLER_MEAS_OK ( PSEUDO_OBS_ELEV_OK | PSEUDO_OBS_SNR_OK | PSEUDO_OBS_PRN_OK | PSEUDO_OBS_NO_CROSS_CORR | PSEUDO_OBS_SV_HEALTHY | PSEUDO_OBS_DATA_EXISTS | PSEUDO_OBS_DATA_GOOD | PSEUDO_OBS_DOPPLER_OK ) + +#define PSEUDO_TOW_WEEK_OK 0x0001 +#define PSEUDO_TOW_OK 0x0002 +#define PSEUDO_RESYNCH 0x0004 +#define PSEUDO_FIRST_MEAS 0x0008 +#define PSEUDO_UNSCHEDULED 0x0010 + +#define PSEUDO_OBS_CORRECTED_AMBIGUOUS 0x0001 +#define PSEUDO_OBS_CORRECTED_BY_SMOOTHING 0x0002 +#define PSEUDO_OBS_CORRECTED_BY_IONO 0x0008 +#define PSEUDO_OBS_CORRECTED_BY_TROPO 0x0010 +#define PSEUDO_OBS_CORRECTED_BY_FAST_CORR 0x0020 +#define PSEUDO_OBS_CORRECTED_BY_DGPS 0x0040 +#define PSEUDO_OBS_CORRECTED_BY_SLOW_CORR 0x0080 +#define PSEUDO_OBS_CORRECTED_BY_WAAS_IONO 0x0100 +#define PSEUDO_OBS_CORR_POSSIBLE_XCORR 0x4000 +#define PSEUDO_OBS_CORR_FRAME_LOCK 0x8000 +#define PSEUDO_OBS_CORRECTED_BY_WAAS ( PSEUDO_OBS_CORRECTED_BY_WAAS_IONO | PSEUDO_OBS_CORRECTED_BY_FAST_CORR) + +/* MEMCTRL */ +#define MEM_WRITE 0x0002 +#define MEM_READD 0x0003 +#define MEM_BOOT 0x0004 +#define MEM_ERASE 0x0006 +#define MEM_XTAL_CALIBRATE 0x000a +/* BOOT flags based on isuite.fastrax.fi/sdk/331/Protocols/PRO_NMEA.html */ +#define MEM_BOOT_NORMAL 0x0000 +#define MEM_BOOT_INT_FWLOADER 0x0001 +#define MEM_BOOT_DL_FWLOADER 0x0002 +#define MEM_BOOT_RELOC_ALTFW 0x0003 + +/* Config Parameters - isuite.fastrax.fi/sdk/331/System/SYS_Parameters.html */ +/* System parameters */ +#define SYS_SET_ID 0x0001 +#define SYS_FACTORY_SET_ID 0x0002 +#define SYS_AUTOSTART 0x0380 +#define START_MODE_AUTO 0x0301 +#define SYS_LKG_SAVE_TIME_LIMIT 0x0008 +#define SYS_LKG_SAVE_DIST_LIMIT 0x0009 +#define SYS_LKG_SAVE_STOP_TIME_LIMIT 0x000a +#define SYS_WATCHDOG 0x0028 +#define SYS_WATCHDOG_TIMEOUT 0x0029 +#define SYS_BOOT_ERASE_PARAMS 0x0080 +#define SYS_ENABLE_UI_LEDS 0x0081 + +/* Protocols parameters */ +#define SYS_ITALK_PORT 0x0010 +#define SYS_ITALK_SPEED 0x0011 +#define SYS_ITALK_MASK 0x0012 +#define SYS_NMEA_PORT 0x0020 +#define SYS_NMEA_SPEED 0x0021 +#define SYS_NMEA_MASK 0x0022 +#define TRACK_ALT_MSG_ROUTING 0x047f +#define OBS_ALT_MSG_ROUTING 0x047e + +/* Fix Conversion parameters */ +#define NAV_DATUM_ID 0x0b08 +#define NAV_GRID_ID 0x0b09 +#define NAV_GRID_NUMBER 0x0b0a +#define NAV_HEAD_VEL_THR 0x0b0b +#define NAV_HEAD_VEL_FILTER 0x0b0c +#define NAV_HEAD_VEL_THRMAX 0x0b0d +#define NAV_HEAD_VEL_THR_PLL 0x0b0e +#define NAV_HEAD_VEL_THRMAX_PLL 0x0b0f +#define NAV_HOLD_HEADING_IF_NO_FIX 0x0bd0 + +/* General navigation parameters */ +#define NAV_MODE 0x0b01 +#define NAV_FIX_INTERVAL 0x0b02 +#define NAV_OUTPUT_INTERVAL 0x0b03 +#define NAV_FOM_LIMIT 0x0b10 +#define NAV_VEL_FOM_LIMIT 0x0b15 +#define NAV_HDOP_LIMIT 0x0b11 +#define NAV_VDOP_LIMIT 0x0b12 +#define NAV_ALT_LIMIT 0x0b13 +#define NAV_VEL_LIMIT 0x0b14 +#define NAV_EXT_AIDING_ALT 0x0b20 +#define NAV_CS_INIT_VAR 0x0b30 +#define NAV_CS_PROC_VAR 0x0b31 +#define NAV_CS_MEAS_VAR 0x0b32 +#define NAV_FILTER_VEL_LOW 0x0b33 +#define NAV_FILTER_VEL_HIGH 0x0b34 +#define NAV_MAX_LKGAGE 0x0b40 +#define NAV_MAX_2D_FIX_SEC 0x0b41 +#define NAV_CARRIERSMOOTHING_ENA 0x0b81 +#define NAV_OLD_DATA_ENA 0x0b82 +#define NAV_SNR_WEIGHTING_ENA 0x0b83 +#define NAV_NORMAL_ENV_ENA 0x0b84 +#define NAV_IONO_ENA 0x0b85 +#define NAV_TROPO_ENA 0x0b87 +#define NAV_DGPS_ENA 0x0b88 +#define NAV_VEL_FILTER_ENA 0x0b8b +#define NAV_ALT_LIMIT_ENA 0x0b8c +#define NAV_VEL_LIMIT_ENA 0x0b8d +#define NAV_EXT_AIDING_ALT_ENA 0x0b8e +#define NAV_FOM_ENA 0x0b8f +#define NAV_HDOP_ENA 0x0b90 +#define NAV_VDOP_ENA 0x0b91 +#define NAV_TENTATIVE_ENA 0x0b96 +#define NAV_PULLFIX_ENA 0x0b97 +#define NAV_2D_FIX_ENA 0x0ba0 +#define NAV_RESERVED_001 0x0ba1 +#define NAV_OUTPUT_LAST_POS_IF_NO_FIX 0x0bb0 +#define NAV_ESTIMATE_VEL_WITHOUT_PLL 0x0bb1 +#define NAV_OUTPUT_LAST_VEL_IF_NO_FIX 0x0bb2 + +/* Position pinning parameters */ +#define NAV_PIN_VEL 0x0b35 +#define NAV_PIN_DRIFT_ERR 0x0b36 +#define NAV_PIN_XYZ_ERR 0x0b37 +#define NAV_PIN_TIMEOUT 0x0b38 +#define NAV_PIN_START_DELAY 0x0b39 +#define NAV_PINNING_ENA 0x0b8a + +/* Interval mode parameters */ +#define NAV_INTMODE_NBR_FIXES 0x0b22 +#define NAV_INTMODE_FIX_INTERVAL 0x0b23 +#define NAV_INTMODE_TRY_FIND_SV 0x0b24 +#define NAV_INTMODE_TRY_GET_FIX 0x0b25 +#define NAV_INTMODE_MAX_STAY_UP 0x0b26 +#define NAV_INTMODE_NUM_IGNORED_FIXES 0x0b27 +#define NAV_INTERVAL_MODE_ENA 0x0ba2 + +/* Kalman navigation parameters */ +#define KLM_MODE 0x0801 +#define KLM_MAX_NUM_STATES 0x0802 +#define KLM_START_FLAGS 0x0803 +#define KLM_OUTPUT_FLAGS 0x0804 +#define KLM_NUM_OBS_LIMIT 0x0805 +#define KLM_MEAS_FLAGS 0x0806 +#define KLM_COV_LIMIT 0x0807 +#define KLM_DOPPLER_NOISE 0x0810 +#define KLM_RANGE_NOISE 0x0811 +#define KLM_DOPPLER_NOISE_LOW 0x0812 +#define KLM_RANGE_NOISE_LOW 0x0813 +#define KLM_NOISE_SNR_LOW 0x0814 +#define KLM_DOPPLER_NOISE_PLL 0x0815 +#define KLM_RANGE_NOISE_PLL 0x0816 +#define KLM_CLOCK_OFFSET_NOISE 0x0820 +#define KLM_CLOCK_DRIFT_NOISE 0x0821 +#define KLM_POS_NOISE 0x0822 +#define KLM_POS_NOISE_VERT 0x0823 +#define KLM_VEL_NOISE 0x0824 +#define KLM_VEL_NOISE_VERT 0x0825 +#define KLM_ACC_NOISE 0x0826 +#define KLM_ACC_NOISE_VERT 0x0827 +#define KLM_ACC_NOISE_PARAM 0x0828 +#define KLM_POS_INIT_UNC 0x0830 +#define KLM_VEL_INIT_UNC 0x0831 +#define KLM_CLOCK_OFFSET_INIT_UNC 0x0832 +#define KLM_CLOCK_DRIFT_INIT_UNC 0x0833 +#define KLM_RESERVED_001 0x0841 +#define KLM_RESERVED_002 0x0842 +#define KLM_RESERVED_003 0x0843 +#define KLM_RESERVED_004 0x0844 +#define KLM_RESERVED_005 0x0845 +#define KLM_RESERVED_006 0x0846 +#define KLM_RESERVED_007 0x0847 +#define KLM_RESERVED_008 0x0848 + +/* Observation parameters */ +#define TRACK_MEAS_INTERVAL 0x0420 +#define TRACK_CHANNELS 0x041d +#define OBS_ELEV_LIMIT 0x0101 +#define OBS_SNR_LIMIT 0x0102 +#define OBS_SNR_RAIM_LIMIT 0x0103 +#define OBS_CROSS_CORR_SNR_DIFF 0x0120 +#define OBS_MAX_SNR 0x0121 +#define OBS_PLL_CROSS_CORR_THR 0x0122 +#define OBS_FLL_CROSS_CORR_THR 0x0123 +#define OBS_FREQ_CROSS_CORR_THR 0x0124 +#define OBS_EPOCH_LIMIT 0x0130 +#define OBS_ELEV_LIMIT_ENA 0x0181 +#define OBS_SNR_LIMIT_ENA 0x0182 +#define OBS_SNR_RAIM_ENA 0x0183 +#define SAT_ORBIT_FIT_UPDATE 0x0203 +#define SAT_FIRST_WEEK 0x0204 +#define SAT_NUM_LEAP 0x0205 +#define SAT_PRED_MAX_LKGAGE 0x0220 +#define SAT_PRED_PHASE_TIMEOUT 0x0221 +#define SAT_PRED_LKG_TIMEOUT 0x0222 +#define SAT_ORBIT_CHECK 0x0281 + +/* Unav Tracking parameters */ +#define TRACK_DLL_ALPHA 0x0401 +#define TRACK_DLL_BETA 0x0402 +#define TRACK_DLL_THR_HIGH 0x0403 +#define TRACK_DLL_THR_LOW 0x0404 +#define TRACK_DLL_POW_NARROW 0x0405 +#define TRACK_DLL_POW_WIDE 0x0406 +#define TRACK_FLL_RESPONSE_TIME 0x0407 +#define TRACK_POW_CALIBRATION 0x0408 +#define TRACK_FLL_THR 0x0409 +#define TRACK_FLL_POW_NARROW 0x040b +#define TRACK_FLL_POW_WIDE 0x040c +#define TRACK_PLL_CTH 0x040d +#define TRACK_PLL_CDTH 0x040e +#define TRACK_PLL_CD2TH 0x040f +#define TRACK_RESERVED_000 0x0410 +#define TRACK_RESERVED_001 0x0411 +#define TRACK_RESERVED_002 0x0412 +#define TRACK_RESERVED_003 0x0413 +#define TRACK_RESERVED_004 0x0414 +#define TRACK_RESERVED_005 0x0415 +#define TRACK_RESERVED_006 0x0416 +#define TRACK_RESERVED_007 0x0417 +#define TRACK_RESERVED_008 0x0418 +#define TRACK_RESERVED_009 0x0419 +#define TRACK_RESERVED_010 0x0425 +#define TRACK_RESERVED_011 0x0426 +#define TRACK_RESERVED_012 0x0427 +#define TRACK_RESERVED_013 0x0428 +#define TRACK_RESERVED_014 0x0429 +#define TRACK_RESERVED_016 0x042a +#define TRACK_RESERVED_017 0x042b +#define TRACK_RESERVED_015 0x0483 +#define SUBF_CHECK_FLAGS 0x0432 + +/* Unav Track task parameters */ +#define TRACK_GROUP_1 0x041a +#define TRACK_GROUP_2 0x041b +#define TRACK_GROUP_2_DELAY 0x041c +#define TRACK_CC_DELAY 0x041e +#define TRACK_CC_THR 0x041f +#define TRACK_PLL_ENA 0x0480 +#define TRACK_NAVAID_ENA 0x0482 +#define TRACK_SHIFT_REG 0x0421 + +/* Agc config parameters */ +#define TRACK_AGC_LO 0x0422 +#define TRACK_AGC_HI 0x0423 +#define TRACK_AGC_MAX_HI 0x0424 +#define TRACK_AGC_ENA 0x0481 + +/* PPS parameters */ +#define PPS_DUTYCYCLE 0x0440 +#define PPS_FREQ 0x0441 +#define PPS_DELAY 0x0442 +#define PPS_SURVEYLEN 0x0443 +#define PPS_MEAS_MS 0x0444 +#define PPS_ENA 0x0490 +#define PPS_SYNC_TRACK 0x0491 +#define PPS_ENA_PRED 0x0492 +#define PPS_INVERT 0x0493 + +/* Frequency plan parameters */ +#define FREQ_XTAL 0x0501 +#define FREQ_MCLK_NOM 0x0502 +#define FREQ_MCLK_DENOM 0x0503 +#define FREQ_RF_NOM 0x0504 +#define FREQ_RF_DENOM 0x0505 +#define FREQ_MIXER_OFFSET 0x0506 +#define FREQ_TME2 0x0507 +#define FREQ_PARAM_ENA 0x0581 + +/* Search parameters */ +#define SEARCH_XTAL_UNC 0x0701 +#define SEARCH_DOPPLER_UNC 0x0702 +#define SEARCH_WIN_PRED_EVEN 0x0703 +#define SEARCH_WIN_PRED_ODD 0x0704 +#define SEARCH_SENS_FULL_R1 0x0705 +#define SEARCH_SENS_FULL_R2 0x0706 +#define SEARCH_SENS_FULL_R3 0x0707 +#define SEARCH_SENS_PRED_EVEN 0x0708 +#define SEARCH_SENS_PRED_ODD 0x0709 +#define SEARCH_PRED_ROUNDS 0x070a +#define SEARCH_BACK_PRNS 0x070b +#define SEARCH_GPS_MASK 0x070c +#define SEARCH_WAAS_MASK 0x070d +#define SEARCH_AUTO_PD_ROUNDS 0x070e +#define SEARCH_FLAGS 0x070f +#define SEARCH_PREC_PRED_TIMEOUT 0x0710 +#define SEARCH_PRED_TIMEOUT 0x0711 +#define SEARCH_FERRY_COND 0x0712 +#define SEARCH_IFFERRY_PRED_COND 0x0713 +#define SEARCH_TUNNEL_IN_SNR 0x0714 +#define SEARCH_TUNNEL_OUT_SNR 0x0715 +#define SEARCH_PRED_ENA 0x0781 +#define SEARCH_BITSYNC_ENA 0x0782 +#define SEARCH_AUTO_PRED_ENA 0x0783 +#define SEARCH_AUTO_PD_ENA 0x0784 +#define SEARCH_SE_PD 0x0785 + +/* Unav Acquisition parameters */ +#define ACQ_SENS_9_COH 0x0901 +#define ACQ_SENS_9_NONCOH 0x0902 +#define ACQ_SENS_9_THR 0x0903 +#define ACQ_SENS_9_BIN 0x0904 +#define ACQ_SENS_10_COH 0x0905 +#define ACQ_SENS_10_NONCOH 0x0906 +#define ACQ_SENS_10_THR 0x0907 +#define ACQ_SENS_10_BIN 0x0908 +#define ACQ_MSG_ENA 0x0981 +#define ACQ_QUICK_SEARCH_ENA 0x0982 +#define SE_NONCOH_SHIFT 0x0940 +#define SE_IR_SHIFT 0x0941 +#define SE_THR 0x0942 +#define SE_INT_ENA 0x09a0 + +/* Logging parameters */ +#define LOG_MODE 0x0d01 +#define LOG_INTERVAL_MIN 0x0d02 +#define LOG_INTERVAL_MAX 0x0d03 +#define LOG_MOVE_MIN 0x0d04 +#define LOG_MOVE_MAX 0x0d05 +#define LOG_VELOCITY_MIN 0x0d06 +#define LOG_VELOCITY_MAX 0x0d07 +#define LOG_MAXITEMS 0x0d08 +#define LOG_STORE_LAT_LONG 0x0d80 +#define LOG_STORE_ALT 0x0d81 +#define LOG_STORE_ALT_FULL 0x0d82 +#define LOG_STORE_GPSTIME 0x0d83 +#define LOG_STORE_GPSTIME_MS 0x0d84 +#define LOG_STORE_DIRECTION 0x0d85 +#define LOG_STORE_VEL 0x0d86 +#define LOG_STORE_VEL_VERT 0x0d87 +#define LOG_STORE_FIXINFO 0x0d88 + +/* SBAS parameters */ +#define WAAS_TIMEOUT_MODE 0x0b60 +#define WAAS_MAX_CHANNELS 0x0b61 +#define WAAS_ENA 0x0bc0 +#define WAAS_MSG_0_ENA 0x0bc1 +#define WAAS_STRICT_ENA 0x0bc2 + +/* Sony Track parameters */ +#define TRACK_DLL_COEFF_GPS 0x0f01 +#define TRACK_DLL_COEFF_DISCR 0x0f02 +#define TRACK_DLL_LIM_GPS 0x0f03 +#define TRACK_DLL4_COEFF_A 0x0f04 +#define TRACK_DLL4_COEFF_B 0x0f05 +#define TRACK_DLL4_COEFF_C 0x0f06 +#define TRACK_DLL4_COEFF_D 0x0f07 +#define TRACK_DLL4_FASTADJ_THRES 0x0f08 +#define TRACK_ELGATE_NARROW 0x0f09 +#define TRACK_COSTASLF_GPS 0x0f0a +#define TRACK_COSTASLF_WAAS 0x0f0b +#define TRACK_LPF_GPS_ACQ 0x0f0c +#define TRACK_LPF_GPS_LOCK 0x0f0d +#define TRACK_LPF_WAAS_LOCK 0x0f0e +#define TRACK_LPF_NOISE 0x0f0f +#define TRACK_SIGDETECT_TH 0x0f10 +#define TRACK_SIGDETECT_TH_HS 0x0f11 +#define TRACK_TIMEOUT_ACQ 0x0f12 +#define TRACK_TIMEOUT_ACQHS 0x0f13 +#define TRACK_TIMEOUT_REACQ 0x0f14 +#define TRACK_HANDOVER_OFFSET 0x0f15 +#define TRACK_CROSSCORR_THRES 0x0f16 +#define TRACK_DLLCTRL_INTERVAL 0x0f17 +#define TRACK_BITEXTRACT 0x0f18 +#define TRACK_RESERVED001 0x0f19 +#define TRACK_RESERVED002 0x0f1a +#define TRACK_WAAS_PRN_BITSTREAM 0x0f1b +#define TRACK_COSTAS_ERROR_TH 0x0f1d +#define TRACK_CARRFLT_OUT_TH 0x0f1e +#define TRACK_CARRFLT_MIDDLE_TH 0x0f1f +#define TRACK_CARRFLT_OUT_DIV 0x0f20 +#define TRACK_CARRFLT_MIDDLE_DIV 0x0f21 +#define TRACK_CARRFLT_INBAND_DIV 0x0f22 +#define TRACK_LATCHTIME_OFFSET 0x0f23 +#define TRACK_DIRECTHANDOVER_OFFSET 0x0f24 +#define TRACK_EN_HS 0x0f80 +#define TRACK_CARR_AID 0x0f81 +#define WAAS_EN_DECODE 0x0f82 +#define TRACK_CARRCHKATLOCK 0x0f83 +#define TRACK_BL_REACQ 0x0f84 + +/* Sony Test parameters */ +#define SONYTEST_DISABLE_PORTS 0x0f85 + +/* Sony Acq parameters */ +#define SACQ_SEARCH_CH_NUM 0x0f30 +#define SACQ_NOISE_COUNT_NUM 0x0f31 +#define SACQ_NOISE_VALID_TIME 0x0f32 +#define SACQ_NOISE_K 0x0f33 +#define SACQ_PEAK_FD 0x0f34 +#define SACQ_PEAK_NFD 0x0f35 +#define SACQ_RESERVE 0x0f36 +#define SACQ_SEARCH_CH_NUM_VALID 0x0f96 + +#endif /* _GPSD_ITALK_H_ */ diff --git a/driver_navcom.c b/driver_navcom.c new file mode 100644 index 0000000..60d65d8 --- /dev/null +++ b/driver_navcom.c @@ -0,0 +1,1342 @@ +/* + * Driver for Navcom receivers using propietary NCT messages, a binary protocol. + * + * Vendor website: http://www.navcomtech.com/ + * Technical references: http://www.navcomtech.com/support/docs.cfm + * + * Tested with two SF-2040G models + * + * At this stage, this driver implements the following commands: + * + * 0x20: Data Request (tell the unit which responses you want) + * 0x3f: LED Configuration (controls the front panel LEDs -- for testing) + * 0x1c: Test Support Block (again, blinks the front panel lights) + * + * and it understands the following responses: + * + * 0x06: Acknowledgement (without error) + * 0x15: Negative Acknowledge + * 0x86: Channel Status + * 0xae: Identification Block + * 0xb0: Raw Meas. Data Block + * 0xb1: PVT Block + * 0xb5: Pseudorange Noise Statistics + * 0xd3: LBM DSP Status Block + * 0xef: Clock Drift and Offset + * + * By Diego Berge. Contact via web form at http://www.navlost.eu/contact + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include "gpsd.h" + +#if defined(NAVCOM_ENABLE) && defined(BINARY_ENABLE) +#include "bits.h" + +/* Have data which is 24 bits long */ +#define getlesl24(buf,off) (int32_t)(((uint32_t)getub((buf), (off)+2)<<24 | (uint32_t)getub((buf), (off)+1)<<16 | (uint32_t)getub((buf), (off))<<8)>>8) +#define getleul24(buf,off) (uint32_t)(((uint32_t)getub((buf), (off)+2)<<24 | (uint32_t)getub((buf), (off)+1)<<16 | (uint32_t)getub((buf), (off))<<8)>>8) + +/* And just to be difficult, Navcom is little endian but the GPS data stream + is big endian. Some messages contain raw GPS data */ +#define getlesw_be(buf, off) (int16_t)((((uint16_t)getub(buf, (off)) << 8) \ + | (uint16_t)getub(buf, (off)+1))) +#define getleuw_be(buf, off) (uint16_t)((((uint16_t)getub(buf, (off)) << 8) \ + | (uint16_t)getub(buf, (off)+1))) +#define getlesl_be(buf, off) (int32_t)((((uint16_t)getleuw_be(buf, (off)) << 16) \ + | getleuw_be(buf, (off)+2))) +#define getleul_be(buf, off) (uint32_t)((((uint16_t)getleuw_be(buf, (off)) << 16) \ + | getleuw_be(buf, (off)+2))) +#define getlesL_be(buf, off) (int64_t)((((uint64_t)getleul_be(buf, (off)) << 32) \ + | getleul_be(buf, (off)+4))) +#define getleuL_be(buf, off) (uint64_t)((((uint64_t)getleul_be(buf, (off)) << 32) \ + | getleul_be(buf, (off)+4))) +#define getlesl24_be(buf,off) (int32_t)(((uint32_t)getub((buf), (off))<<24 \ + | (uint32_t)getub((buf), (off)+1)<<16 \ + | (uint32_t)getub((buf), (off)+2)<<8)>>8) + +#define NAVCOM_CHANNELS 12 + +static uint8_t checksum(unsigned char *buf, size_t len) +{ + size_t n; + uint8_t csum = (uint8_t) 0x00; + for (n = 0; n < len; n++) + csum ^= buf[n]; + return csum; +} + +static bool navcom_send_cmd(struct gps_device_t *session, unsigned char *cmd, + size_t len) +{ + gpsd_report(LOG_RAW, "Navcom: command dump: %s\n", + gpsd_hexdump_wrapper(cmd, len, LOG_RAW)); + return (gpsd_write(session, cmd, len) == (ssize_t) len); +} + +/* Data Request */ +static void navcom_cmd_0x20(struct gps_device_t *session, uint8_t block_id, + uint16_t rate) +{ + unsigned char msg[18]; + putbyte(msg, 0, 0x02); + putbyte(msg, 1, 0x99); + putbyte(msg, 2, 0x66); + putbyte(msg, 3, 0x20); /* Cmd ID */ + putleword(msg, 4, 0x000e); /* Length */ + putbyte(msg, 6, 0x00); /* Action */ + putbyte(msg, 7, 0x01); /* Count of blocks */ + putbyte(msg, 8, block_id); /* Data Block ID */ + putbyte(msg, 9, 0x02); /* Logical Ports */ + putleword(msg, 10, rate); /* Data rate */ + putbyte(msg, 12, 0x71); + putbyte(msg, 13, 0x00); + putleword(msg, 14, 0x0000); + putbyte(msg, 16, checksum(msg + 3, 13)); + putbyte(msg, 17, 0x03); + (void)navcom_send_cmd(session, msg, 18); + gpsd_report(LOG_PROG, + "Navcom: sent command 0x20 (Data Request) " + "- data block id = %02x at rate %02x\n", block_id, rate); +} + +/*@ unused @*/ +/* Changes the LED settings in the receiver */ +static void UNUSED navcom_cmd_0x3f(struct gps_device_t *session) +{ + unsigned char msg[12]; + putbyte(msg, 0, 0x02); + putbyte(msg, 1, 0x99); + putbyte(msg, 2, 0x66); + putbyte(msg, 3, 0x3f); /* Cmd ID */ + putleword(msg, 4, 0x0008); + putbyte(msg, 6, 0x01); /* Action */ + putbyte(msg, 7, 0x00); /* Reserved */ + putbyte(msg, 8, 0x02); /* Link LED setting */ + putbyte(msg, 9, 0x0a); /* Battery LED setting */ + putbyte(msg, 10, checksum(msg + 3, 7)); + putbyte(msg, 11, 0x03); + (void)navcom_send_cmd(session, msg, 12); + gpsd_report(LOG_PROG, + "Navcom: sent command 0x3f (LED Configuration Block)\n"); +} + +/* Test Support Block - Blinks the LEDs */ +static void navcom_cmd_0x1c(struct gps_device_t *session, uint8_t mode, + uint8_t length) +{ + unsigned char msg[12]; + putbyte(msg, 0, 0x02); + putbyte(msg, 1, 0x99); + putbyte(msg, 2, 0x66); + putbyte(msg, 3, 0x1c); /* Cmd ID */ + putleword(msg, 4, 0x0008); + putbyte(msg, 6, 0x04); /* Use ACK/NAK */ + putbyte(msg, 7, mode); /* 0x01 or 0x02 */ + putbyte(msg, 8, length); /* Only if mode == 0x01 */ + putbyte(msg, 9, 0x00); + putbyte(msg, 10, checksum(msg + 3, 7)); + putbyte(msg, 11, 0x03); + (void)navcom_send_cmd(session, msg, 12); + gpsd_report(LOG_PROG, "Navcom: sent command 0x1c (Test Support Block)\n"); + gpsd_report(LOG_IO, + "Navcom: command 0x1c mode = %02x, length = %u\n", + mode, length); +} + +#ifdef ALLOW_RECONFIGURE +/* Serial Port Configuration */ +static void navcom_cmd_0x11(struct gps_device_t *session, + uint8_t port_selection) +{ + /* NOTE - We only allow changing one port at a time, + * although the message supports doing both at once. */ + unsigned char msg[12]; + putbyte(msg, 0, 0x02); + putbyte(msg, 1, 0x99); + putbyte(msg, 2, 0x66); + putbyte(msg, 3, 0x11); /* Cmd ID */ + putleword(msg, 4, 0x0008); /* Length */ + putbyte(msg, 6, 0x04); /* Action - Use ACK/NAK) */ + putbyte(msg, 7, port_selection); + putbyte(msg, 8, 0x00); /* Reserved */ + putbyte(msg, 9, 0x00); /* Reserved */ + putbyte(msg, 10, checksum(msg + 3, 7)); + putbyte(msg, 11, 0x03); + (void)navcom_send_cmd(session, msg, 12); + gpsd_report(LOG_PROG, + "Navcom: sent command 0x11 (Serial Port Configuration)\n"); + gpsd_report(LOG_IO, + "Navcom: serial port selection: 0x%02x\n", port_selection); +} +#endif /* ALLOW_RECONFIGURE */ + +static void navcom_event_hook(struct gps_device_t *session, event_t event) +{ + if (event == event_wakeup) { + /* NOTE - This allows us to know into which of the unit's various + * serial ports we are connected. + * Its value gets updated every time we receive a 0x06 (Ack) + * message. Note that if commands are being fed into the + * unit from more than one port (which is entirely possible + * although not necessarily a bright idea), there is a good + * chance that we might misidentify our port */ + /*@ -type @*/ + navcom_cmd_0x1c(session, 0x02, 0); /* Test Support Block */ + navcom_cmd_0x20(session, 0xae, 0x0000); /* Identification Block */ + navcom_cmd_0x20(session, 0x86, 0x000a); /* Channel Status */ + /*@ +type @*/ + } + /* Request the following messages: */ + /* + * FIX-ME: It might not be necessary to call this on reactivate. + * Experiment to see if the holds its settings through a close. + */ + if (event == event_identified || event == event_reactivate) { + /*@ +charint @*/ + navcom_cmd_0x1c(session, 0x01, 5); /* Blink LEDs on receiver */ + navcom_cmd_0x20(session, 0xae, 0x1770); /* Identification Block - send every 10 min */ + navcom_cmd_0x20(session, 0xb1, 0x4000); /* PVT Block */ + navcom_cmd_0x20(session, 0xb5, 0x00c8); /* Pseudorange Noise Statistics - send every 20s */ + navcom_cmd_0x20(session, 0xb0, 0x4000); /* Raw Meas Data Block */ + navcom_cmd_0x20(session, 0x81, 0x0000); /* Packed Ephemeris Data - send once */ + navcom_cmd_0x20(session, 0x81, 0x4000); /* Packed Ephemeris Data */ + navcom_cmd_0x20(session, 0x86, 0x4000); /* Channel Status */ + navcom_cmd_0x20(session, 0x83, 0x4000); /* Ionosphere and UTC Data */ + navcom_cmd_0x20(session, 0xef, 0x0bb8); /* Clock Drift - send every 5 min */ + /*@ -charint @*/ + } +} + +/* Ionosphere and UTC Data */ +static gps_mask_t handle_0x83(struct gps_device_t *session) +{ + /* NOTE - At the present moment this is only being used + * for determining the GPS-UTC time difference, + * for which the iono data is not needed as far + * as we are concerned. However, I am still + * reporting it (if debuglevel >= LOG_IO) as a + * matter of interest */ +/* 2^-30 */ +#define SF_A0 (0.000000000931322574615478515625) +/* 2^-50 */ +#define SF_A1 (0.000000000000000888178419700125) +/* 2^12 */ +#define SF_TOT (4096) +/* 2^-30 */ +#define SF_ALPHA0 (0.000000000931322574615478515625) +/* 2^-27 */ +#define SF_ALPHA1 (0.000000007450580596923828125) +/* 2^-24 */ +#define SF_ALPHA2 (0.000000059604644775390625) +/* 2^-24 */ +#define SF_ALPHA3 (0.000000059604644775390625) +/* 2^11 */ +#define SF_BETA0 (2048) +/* 2^14 */ +#define SF_BETA1 (16384) +/* 2^16 */ +#define SF_BETA2 (65536) +/* 2^16 */ +#define SF_BETA3 (65536) + unsigned char *buf = session->packet.outbuffer + 3; + uint16_t week = getleuw(buf, 3); + uint32_t tow = getleul(buf, 5); + int8_t alpha0 = getsb(buf, 9); + int8_t alpha1 = getsb(buf, 10); + int8_t alpha2 = getsb(buf, 11); + int8_t alpha3 = getsb(buf, 12); + int8_t beta0 = getsb(buf, 13); + int8_t beta1 = getsb(buf, 14); + int8_t beta2 = getsb(buf, 15); + int8_t beta3 = getsb(buf, 16); + int32_t a1 = getlesl(buf, 17); + int32_t a0 = getlesl(buf, 21); + uint8_t tot = getub(buf, 25); + uint8_t wnt = getub(buf, 26); + int8_t dtls = getsb(buf, 27); + uint8_t wnlsf = getub(buf, 28); + uint8_t dn = getub(buf, 29); + int8_t dtlsf = getsb(buf, 30); + + /*@ +charint +relaxtypes @*/ + /* Ref.: ICD-GPS-200C 20.3.3.5.2.4 */ + if ((week % 256) * 604800 + tow / 1000.0 < wnlsf * 604800 + dn * 86400) { + /* Effectivity time is in the future, use dtls */ + session->context->leap_seconds = (int)dtls; + } else { + /* Effectivity time is not in the future, use dtlsf */ + session->context->leap_seconds = (int)dtlsf; + } + /*@ -relaxtypes -charint @*/ + + //gpstime_to_unix((int)week, tow/1000.0) - session->context->leap_seconds; + + gpsd_report(LOG_PROG, + "Navcom: received packet type 0x83 (Ionosphere and UTC Data)\n"); + gpsd_report(LOG_IO, "Navcom: Scaled parameters follow:\n"); + gpsd_report(LOG_IO, + "Navcom: GPS Week: %u, GPS Time of Week: %u (GPS Time: %f)\n", + week, tow, week * 604800 + tow / 1000.0); + gpsd_report(LOG_IO, + "Navcom: a0: %12.4E, a1: %12.4E, a2: %12.4E, a3: %12.4E, " + "b0: %12.4E, b1: %12.4E, b2: %12.4E, b3: %12.4E\n", + (double)alpha0 * SF_ALPHA0, (double)alpha1 * SF_ALPHA1, + (double)alpha2 * SF_ALPHA2, (double)alpha3 * SF_ALPHA3, + (double)beta0 * SF_BETA0, (double)beta1 * SF_BETA1, + (double)beta2 * SF_BETA2, (double)beta3 * SF_BETA3); + gpsd_report(LOG_IO, + "Navcom: A0: %19.12E, A1: %19.12E\n", (double)a0 * SF_A0, + (double)a1 * SF_A1); + gpsd_report(LOG_IO, + "Navcom: UTC Ref. Time: %lu, UTC Ref. Week: %u, dTls: %d\n", + (unsigned long)tot * SF_TOT, wnt, dtls); + gpsd_report(LOG_IO, + "Navcom: Week of leap seconds: %u, Day number of leap seconds: %u, dTlsf: %d\n", + wnlsf, dn, dtlsf); + + return 0; /* No flag for update of leap seconds (Not part of a fix) */ + +#undef SF_A0 +#undef SF_A1 +#undef SF_TOT +#undef SF_ALPHA0 +#undef SF_ALPHA1 +#undef SF_ALPHA2 +#undef SF_ALPHA3 +#undef SF_BETA0 +#undef SF_BETA1 +#undef SF_BETA2 +#undef SF_BETA3 +} + +/* Acknowledgement (without error) */ +static gps_mask_t handle_0x06(struct gps_device_t *session) +{ + unsigned char *buf = session->packet.outbuffer + 3; + uint8_t cmd_id = getub(buf, 3); + uint8_t port = getub(buf, 4); + session->driver.navcom.physical_port = port; /* This tells us which serial port was used last */ + gpsd_report(LOG_PROG, + "Navcom: received packet type 0x06 (Acknowledgement (without error))\n"); + /*@ -type @*/ + gpsd_report(LOG_IO, + "Navcom: acknowledged command id 0x%02x on port %c\n", + cmd_id, (port == 0 ? 'A' : (port == 1 ? 'B' : '?'))); + /*@ +type @*/ + return 0; /* Nothing updated */ +} + +/* Negative Acknowledge */ +static gps_mask_t handle_0x15(struct gps_device_t *session) +{ + size_t n; + unsigned char *buf = session->packet.outbuffer + 3; + size_t msg_len = (size_t) getleuw(buf, 1); + /*@ -type @*/ + uint8_t port, cmd_id = getub(buf, 3); + gpsd_report(LOG_PROG, + "Navcom: received packet type 0x15 (Negative Acknowledge)\n"); + for (n = 4; n < (msg_len - 2); n += 2) { + uint8_t err_id = getub(buf, n); + uint8_t err_desc = getub(buf, n + 1); + gpsd_report(LOG_IO, + "Navcom: error id = 0x%02x, error description = 0x%02x\n", + err_id, err_desc); + } + port = getub(buf, n); + gpsd_report(LOG_IO, + "Navcom: negative acknowledge was for command id 0x%02x on port %c\n", + cmd_id, (port == 0 ? 'A' : (port == 1 ? 'B' : '?'))); + /*@ -type @*/ + return 0; /* Nothing updated */ +} + +/* PVT Block */ +static gps_mask_t handle_0xb1(struct gps_device_t *session) +{ + gps_mask_t mask; + unsigned int n; + unsigned char *buf = session->packet.outbuffer + 3; + uint16_t week; + uint32_t tow; + uint32_t sats_used; + int32_t lat, lon; + /* Resolution of lat/lon values (2^-11) */ +#define LL_RES (0.00048828125) + uint8_t lat_fraction, lon_fraction; + /* Resolution of lat/lon fractions (2^-15) */ +#define LL_FRAC_RES (0.000030517578125) + uint8_t nav_mode; + int32_t ellips_height, altitude; + /* Resolution of height and altitude values (2.0^-10) */ +#define EL_RES (0.0009765625) + double vel_north, vel_east, vel_up; + /* Resolution of velocity values (2.0^-10) */ +#define VEL_RES (0.0009765625) + double track; + uint8_t fom, gdop, pdop, hdop, vdop, tdop, tfom; + double eph; + /* This value means "undefined" */ +#define DOP_UNDEFINED (255) + + int16_t ant_height_adj; + int32_t set_delta_up; + /* Resolution of delta north, east, and up, + * and ant. height adjustment values (1mm) */ +#define D_RES (0.001) + +#ifdef __UNUSED__ + /* Other values provided by the PVT block which we + * may want to provide in the future. At the present + * moment, the gpsd protocol does not have a mechanism + * to make this available to the user */ + uint8_t dgps_conf; + uint16_t max_dgps_age; + uint8_t ext_nav_mode; + int32_t set_delta_north, set_delta_east; + uint8_t nav_failure_code; +#endif /* __UNUSED__ */ + + /* Timestamp */ + week = (uint16_t) getleuw(buf, 3); + session->context->gps_week = week; + tow = (uint32_t) getleul(buf, 5); + session->context->gps_tow = tow / 1000.0; + session->newdata.time = + gpstime_to_unix((int)week, session->context->gps_tow) + - session->context->leap_seconds; + + /* Satellites used */ + sats_used = (uint32_t) getleul(buf, 9); + session->gpsdata.satellites_used = 0; + for (n = 0; n < 31; n++) { + if ((sats_used & (0x01 << n)) != 0) + session->gpsdata.used[session->gpsdata.satellites_used++] = + (int)(n + 1); + } + + /* Get latitude, longitude */ + lat = getlesl(buf, 13); + lon = getlesl(buf, 17); + lat_fraction = (uint8_t) (getub(buf, 21) >> 4); + lon_fraction = (uint8_t) (getub(buf, 21) & 0x0f); + + session->newdata.latitude = + (double)(lat * LL_RES + lat_fraction * LL_FRAC_RES) / 3600; + session->newdata.longitude = + (double)(lon * LL_RES + lon_fraction * LL_FRAC_RES) / 3600; + + /* Nav mode */ + nav_mode = (uint8_t) getub(buf, 22); + if (-nav_mode & 0x80) { + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + } else { + session->newdata.mode = (nav_mode & 0x40 ? MODE_3D : MODE_2D); + session->gpsdata.status = + (nav_mode & 0x03 ? STATUS_DGPS_FIX : STATUS_FIX); + } + + /* Height Data */ + ellips_height = getlesl(buf, 23); + altitude = getlesl(buf, 27); + + ant_height_adj = getlesw(buf, 51); + set_delta_up = getlesl(buf, 79); + + session->newdata.altitude = (double)(altitude * EL_RES) + + (ant_height_adj * D_RES) + (set_delta_up * D_RES); + session->gpsdata.separation = (double)(ellips_height - altitude) * EL_RES + + (ant_height_adj * D_RES) + (set_delta_up * D_RES); + + /* Speed Data */ + vel_north = (double)getlesl24(buf, 31); + vel_east = (double)getlesl24(buf, 34); + /* vel_up = getlesl24(buf, 37); */ + vel_up = (double)getlesl24(buf, 37); + + track = atan2(vel_east, vel_north); + if (track < 0) + track += 2 * GPS_PI; + session->newdata.track = track * RAD_2_DEG; + /*@ -evalorder @*/ + session->newdata.speed = + sqrt(pow(vel_east, 2) + pow(vel_north, 2)) * VEL_RES; + /*@ +evalorder @*/ + session->newdata.climb = vel_up * VEL_RES; + + /* Quality indicators */ + /*@ -type @*/ + fom = getub(buf, 40); + gdop = getub(buf, 41); + pdop = getub(buf, 42); + hdop = getub(buf, 43); + vdop = getub(buf, 44); + tdop = getub(buf, 45); + tfom = getub(buf, 46); + + /* Get two-sigma horizontal circular error estimate */ + eph = fom / 100.0 * 1.96; + /* approximate epx and epy errors from it */ + session->newdata.epx = session->newdata.epy = eph / sqrt(2); + session->newdata.ept = tfom * 1.96 /*Two sigma */ ; + + if (gdop != DOP_UNDEFINED) + session->gpsdata.dop.gdop = gdop / 10.0; + if (pdop != DOP_UNDEFINED) + session->gpsdata.dop.pdop = pdop / 10.0; + if (hdop != DOP_UNDEFINED) + session->gpsdata.dop.hdop = hdop / 10.0; + if (vdop != DOP_UNDEFINED) + session->gpsdata.dop.vdop = vdop / 10.0; + if (tdop != DOP_UNDEFINED) + session->gpsdata.dop.tdop = tdop / 10.0; + /*@ +type @*/ + + gpsd_report(LOG_PROG, "Navcom: received packet type 0xb1 (PVT Report)\n"); + gpsd_report(LOG_IO, "Navcom: navigation mode %s (0x%02x) - %s - %s\n", + (-nav_mode & 0x80 ? "invalid" : "valid"), nav_mode, + (nav_mode & 0x40 ? "3D" : "2D"), + (nav_mode & 0x03 ? "DGPS" : "GPS")); + gpsd_report(LOG_IO, + "Navcom: latitude = %f, longitude = %f, altitude = %f, geoid = %f\n", + session->newdata.latitude, session->newdata.longitude, + session->newdata.altitude, session->gpsdata.separation); + gpsd_report(LOG_IO, + "Navcom: velocities: north = %f, east = %f, up = %f (track = %f, speed = %f)\n", + vel_north * VEL_RES, vel_east * VEL_RES, vel_up * VEL_RES, + session->newdata.track, session->newdata.speed); +#undef D_RES +#undef LL_RES +#undef LL_FRAC_RES +#undef EL_RES +#undef VEL_RES +#undef DOP_UNDEFINED + + mask = LATLON_IS | ALTITUDE_IS | CLIMB_IS | SPEED_IS | TRACK_IS + | TIME_IS | STATUS_IS | MODE_IS | USED_IS | HERR_IS | VERR_IS + | TIMERR_IS | DOP_IS; + gpsd_report(LOG_DATA, "PVT 0xb1: time=%.2f, lat=%.2f lon=%.2f alt=%.f " + "speed=%.2f track=%.2f climb=%.2f mode=%d status=%d " + "epx=%.2f epy=%.2f epv=%.2f " + "gdop=%.2f pdop=%.2f hdop=%.2f vdop=%.2f tdop=%.2f " + "mask={LATLON|ALTITUDE|CLIMB|SPEED|TRACK|TIME|STATUS|MODE|" + "USED|HERR|VERR|TIMERR|DOP}\n", + session->newdata.time, + session->newdata.latitude, + session->newdata.longitude, + session->newdata.altitude, + session->newdata.speed, + session->newdata.track, + session->newdata.climb, + session->newdata.mode, + session->gpsdata.status, + session->newdata.epx, + session->newdata.epy, + session->newdata.epv, + session->gpsdata.dop.gdop, + session->gpsdata.dop.pdop, + session->gpsdata.dop.hdop, + session->gpsdata.dop.vdop, session->gpsdata.dop.tdop); + return mask; +} + +/* Packed Ephemeris Data */ +static gps_mask_t handle_0x81(struct gps_device_t *session) +{ + /* Scale factors for everything */ + /* 2^-31 */ +#define SF_TGD (.000000000465661287307739257812) + /* 2^4 */ +#define SF_TOC (16) + /* 2^-55 */ +#define SF_AF2 (.000000000000000027755575615628) + /* 2^-43 */ +#define SF_AF1 (.000000000000113686837721616029) + /* 2^-31 */ +#define SF_AF0 (.000000000465661287307739257812) + /* 2^-5 */ +#define SF_CRS (.031250000000000000000000000000) + /* 2^-43 */ +#define SF_DELTA_N (.000000000000113686837721616029) + /* 2^-31 */ +#define SF_M0 (.000000000465661287307739257812) + /* 2^-29 */ +#define SF_CUC (.000000001862645149230957031250) + /* 2^-33 */ +#define SF_E (.000000000116415321826934814453) + /* 2^-29 */ +#define SF_CUS (.000000001862645149230957031250) + /* 2^-19 */ +#define SF_SQRT_A (.000001907348632812500000000000) + /* 2^4 */ +#define SF_TOE (16) + /* 2^-29 */ +#define SF_CIC (.000000001862645149230957031250) + /* 2^-31 */ +#define SF_OMEGA0 (.000000000465661287307739257812) + /* 2^-29 */ +#define SF_CIS (.000000001862645149230957031250) + /* 2^-31 */ +#define SF_I0 (.000000000465661287307739257812) + /* 2^-5 */ +#define SF_CRC (.031250000000000000000000000000) + /* 2^-31 */ +#define SF_OMEGA (.000000000465661287307739257812) + /* 2^-43 */ +#define SF_OMEGADOT (.000000000000113686837721616029) + /* 2^-43 */ +#define SF_IDOT (.000000000000113686837721616029) + + unsigned char *buf = session->packet.outbuffer + 3; + uint8_t prn = getub(buf, 3); + uint16_t week = getleuw(buf, 4); + uint32_t tow = getleul(buf, 6); + uint16_t iodc = getleuw(buf, 10); + /* And now the fun starts... everything that follows is + * raw GPS data minus parity */ + /* Subframe 1, words 3 to 10 minus parity */ + uint16_t wn = (getleuw_be(buf, 12) & 0xffc0) >> 6; + uint8_t cl2 = (getub(buf, 13) & 0x30) >> 4; + uint8_t ura = getub(buf, 13) & 0x0f; + uint8_t svh = (getub(buf, 14) & 0xfc) >> 2; + /* We already have IODC from earlier in the message, so + * we do not decode again */ +/* uint16_t iodc = (getub(buf, 14)&0x03)<<8;*/ + uint8_t l2pd = (getub(buf, 15) & 0x80) >> 7; + int8_t tgd = getsb(buf, 26); +/* iodc |= getub(buf, 27);*/ + uint16_t toc = getleuw_be(buf, 28); + int8_t af2 = getsb(buf, 30); + int16_t af1 = getlesw_be(buf, 31); + /*@ -shiftimplementation @*/ + int32_t af0 = getlesl24_be(buf, 33) >> 2; + /*@ +shiftimplementation @*/ + /* Subframe 2, words 3 to 10 minus parity */ + uint8_t iode = getub(buf, 36); + int16_t crs = getlesw_be(buf, 37); + int16_t delta_n = getlesw_be(buf, 39); + int32_t m0 = getlesl_be(buf, 41); + int16_t cuc = getlesw_be(buf, 45); + uint32_t e = getleul_be(buf, 47); + int16_t cus = getlesw_be(buf, 51); + uint32_t sqrt_a = getleul_be(buf, 53); + uint16_t toe = getleuw_be(buf, 57); + /* NOTE - Fit interval & AODO not collected */ + /* Subframe 3, words 3 to 10 minus parity */ + int16_t cic = getlesw_be(buf, 60); + int32_t Omega0 = getlesl_be(buf, 62); + int16_t cis = getlesw_be(buf, 66); + int32_t i0 = getlesl_be(buf, 68); + int16_t crc = getlesw_be(buf, 72); + int32_t omega = getlesl_be(buf, 74); + int32_t Omegadot = getlesl24_be(buf, 78); + /*@ -predboolothers @*/ + /* Question: What is the proper way of shifting a signed int 2 bits to + * the right, preserving sign? Answer: integer division by 4. */ + int16_t idot = + (int16_t) (((getlesw_be(buf, 82) & 0xfffc) / + 4) | (getub(buf, 82) & 80 ? 0xc000 : 0x0000)); + /*@ +predboolothers @*/ + char time_str[24]; + session->context->gps_week = (unsigned short)wn; + session->context->gps_tow = (double)(toc * SF_TOC); + /* leap second? */ + (void)unix_to_iso8601(gpstime_to_unix((int)wn, session->context->gps_tow), + time_str, sizeof(time_str)); + + gpsd_report(LOG_PROG, + "Navcom: received packet type 0x81 (Packed Ephemeris Data)\n"); + gpsd_report(LOG_IO, + "Navcom: PRN: %u, Epoch: %u (%s), SV clock bias/drift/drift rate: %#19.12E/%#19.12E/%#19.12E\n", + prn, toc * SF_TOC, time_str, ((double)af0) * SF_AF0, + ((double)af1) * SF_AF1, ((double)af2) * SF_AF2); + gpsd_report(LOG_IO, + "Navcom: IODE (!AODE): %u Crs: %19.12e, Delta n: %19.12e, M0: %19.12e\n", + iode, (double)crs * SF_CRS, + (double)delta_n * SF_DELTA_N * GPS_PI, + (double)m0 * SF_M0 * GPS_PI); + gpsd_report(LOG_IO, + "Navcom: Cuc: %19.12e, Eccentricity: %19.12e, Cus: %19.12e, A^1/2: %19.12e\n", + (double)cuc * SF_CUC, (double)e * SF_E, (double)cus * SF_CUS, + (double)sqrt_a * SF_SQRT_A); + gpsd_report(LOG_IO, + "Navcom: TOE: %u, Cic: %19.12e, Omega %19.12e, Cis: %19.12e\n", + toe * SF_TOE, (double)cic * SF_CIC, + (double)Omega0 * SF_OMEGA0 * GPS_PI, (double)cis * SF_CIS); + gpsd_report(LOG_IO, + "Navcom: i0: %19.12e, Crc: %19.12e, omega: %19.12e, Omega dot: %19.12e\n", + (double)i0 * SF_I0 * GPS_PI, (double)crc * SF_CRC, + (double)omega * SF_OMEGA * GPS_PI, + (double)Omegadot * SF_OMEGADOT * GPS_PI); + gpsd_report(LOG_IO, + "Navcom: IDOT: %19.12e, Codes on L2: 0x%x, GPS Week: %u, L2 P data flag: %x\n", + (double)idot * SF_IDOT * GPS_PI, cl2, + week - (week % 1024) + wn, l2pd); + gpsd_report(LOG_IO, + "Navcom: SV accuracy: 0x%x, SV health: 0x%x, TGD: %f, IODC (!AODC): %u\n", + ura, svh, (double)tgd * SF_TGD, iodc); + gpsd_report(LOG_IO, "Navcom: Transmission time: %u\n", tow); + +#undef SF_TGD +#undef SF_TOC +#undef SF_AF2 +#undef SF_AF1 +#undef SF_AF0 +#undef SF_CRS +#undef SF_DELTA_N +#undef SF_M0 +#undef SF_CUC +#undef SF_E +#undef SF_CUS +#undef SF_SQRT_A +#undef SF_TOE +#undef SF_CIC +#undef SF_OMEGA0 +#undef SF_CIS +#undef SF_I0 +#undef SF_CRC +#undef SF_OMEGA +#undef SF_OMEGADOT +#undef SF_IDOT + + return 0; +} + +/* Channel Status */ +static gps_mask_t handle_0x86(struct gps_device_t *session) +{ + size_t n, i; + uint8_t prn, tracking_status, ele, ca_snr, p2_snr, log_channel, + hw_channel, s; + uint16_t azm, dgps_age; + unsigned char *buf = session->packet.outbuffer + 3; + size_t msg_len = (size_t) getleuw(buf, 1); + uint16_t week = getleuw(buf, 3); + uint32_t tow = getleul(buf, 5); + uint8_t eng_status = getub(buf, 9); + uint16_t sol_status = getleuw(buf, 10); + uint8_t sats_visible = getub(buf, 12); + //uint8_t sats_tracked = getub(buf, 13); + uint8_t sats_used = getub(buf, 14); + //uint8_t pdop = getub(buf, 15); + + /* Timestamp and PDOP */ + session->context->gps_week = (unsigned short)week; + session->context->gps_tow = (double)tow / 1000.0f; + /*@ ignore @*//*@ splint is confused @ */ + session->gpsdata.skyview_time = + gpstime_to_unix((int)week, session->context->gps_tow) + - session->context->leap_seconds; + /*@ end @*/ + /* Give this driver a single point of truth about DOPs */ + //session->gpsdata.dop.pdop = (int)pdop / 10.0; + + /* Satellite count */ + session->gpsdata.satellites_visible = (int)sats_visible; + session->gpsdata.satellites_used = (int)sats_used; + + /* Fix mode */ + switch (sol_status & 0x05) { + case 0x05: + session->gpsdata.status = STATUS_DGPS_FIX; + break; + case 0x01: + session->gpsdata.status = STATUS_FIX; + break; + default: + session->gpsdata.status = STATUS_NO_FIX; + } + + /*@ -predboolothers @*/ + gpsd_report(LOG_IO, + "Navcom: engine status = 0x%x, almanac = %s, time = 0x%x, pos = 0x%x\n", + eng_status & 0x07, (eng_status & 0x08 ? "valid" : "invalid"), + eng_status & 0x30 >> 4, eng_status & 0xc0 >> 6); + /*@ +predboolothers @*/ + + /* Satellite details */ + i = 0; + for (n = 17; n < msg_len; n += 14) { + if (i >= MAXCHANNELS) { + gpsd_report(LOG_ERROR, + "Navcom: packet type 0x86: too many satellites!\n"); + gpsd_zero_satellites(&session->gpsdata); + return 0; + } + prn = getub(buf, n); + tracking_status = getub(buf, n + 1); + log_channel = getub(buf, n + 2); + ele = getub(buf, n + 5); + azm = getleuw(buf, n + 6); + ca_snr = getub(buf, n + 8); + p2_snr = getub(buf, n + 10); + dgps_age = getleuw(buf, n + 11); + hw_channel = getub(buf, n + 13); + s = (unsigned char)0; + /*@ -predboolothers +charint @*/ + /* NOTE - In theory, I think one would check for hw channel number to + * see if one is dealing with a GPS or other satellite, but the + * channel numbers reported bear no resemblance to what the spec + * says should be. So I check for the fact that if all three + * values below are zero, one is not interested on this satellite */ + if (!(ele == 0 && azm == 0 && dgps_age == 0)) { + session->gpsdata.PRN[i] = (int)prn; + session->gpsdata.elevation[i] = (int)ele; + session->gpsdata.azimuth[i] = (int)azm; + /*@ ignore @*//* splint is confused */ + s = session->gpsdata.ss[i++] = (p2_snr ? p2_snr : ca_snr) / 4.0; + /*@ end @*/ + } + gpsd_report(LOG_IO, + "Navcom: prn = %3u, ele = %02u, azm = %03u, snr = %d (%s), " + "dgps age = %.1fs, log ch = %d, hw ch = 0x%02x\n", + prn, ele, azm, s, (p2_snr ? "P2" : "C/A"), + (double)dgps_age * 0.1, log_channel & 0x3f, hw_channel); + gpsd_report(LOG_IO, + "Navcom: sol. valid = %c, clock = %s, pos. = %s, " + "height = %s, err. code = 0x%x\n", + (sol_status & 0x01 ? 'Y' : 'N'), + (sol_status & 0x02 ? "stable" : "unstable"), + (sol_status & 0x04 ? "dgps" : "unaided"), + (sol_status & 0x08 ? "solved" : "constrained"), + (sol_status & 0x01 ? 0x00 : sol_status & 0x0f00 >> 8)); + /*@ +predboolothers -charint @*/ + } + + gpsd_report(LOG_DATA, + "CS 0x86: visible=%d, used=%d, mask={SATELLITE|STATUS}\n", + session->gpsdata.satellites_visible, + session->gpsdata.satellites_used); + return SATELLITE_IS | STATUS_IS; +} + +/* Raw Meas. Data Block */ +static gps_mask_t handle_0xb0(struct gps_device_t *session) +{ + /* L1 wavelength (299792458m/s / 1575420000Hz) */ +#define LAMBDA_L1 (.190293672798364880476317426464) + size_t n; + unsigned char *buf = session->packet.outbuffer + 3; + size_t msg_len = (size_t) getleuw(buf, 1); + uint16_t week = getleuw(buf, 3); + uint32_t tow = getleul(buf, 5); + uint8_t tm_slew_acc = getub(buf, 9); + uint8_t status = getub(buf, 10); + + char time_str[24]; + session->context->gps_week = (unsigned short)week; + session->context->gps_tow = (double)tow / 1000.0; + (void) + unix_to_iso8601(gpstime_to_unix((int)week, session->context->gps_tow), + time_str, sizeof(time_str)); + + gpsd_report(LOG_PROG, + "Navcom: received packet type 0xb0 (Raw Meas. Data Block)\n"); + /*@ -predboolothers @*/ + gpsd_report(LOG_IO, + "Navcom: Epoch = %s, time slew accumulator = %u (1/1023mS), status = 0x%02x " + "(%sclock %s - %u blocks follow)\n", + time_str, + tm_slew_acc, status, + (status & 0x80 ? "channel time set - " : ""), + (status & 0x40 ? "stable" : "not stable"), status & 0x0f); + /*@ +predboolothers @*/ + for (n = 11; n < msg_len - 1; n += 16) { + uint8_t sv_status = getub(buf, n); + uint8_t ch_status = getub(buf, n + 1); + uint32_t ca_pseudorange = getleul(buf, n + 2); + /* integer division by 16 is a sign-preserving right shift of 4 bits */ + int32_t l1_phase = getlesl24(buf, n + 6) / 16; + uint8_t l1_slips = (uint8_t) (getlesl24(buf, n + 6) & 0x0f); + int16_t p1_ca_pseudorange = getlesw(buf, n + 9); + int16_t p2_ca_pseudorange = getlesw(buf, n + 11); + int32_t l2_phase = getlesl24(buf, n + 13) / 16; + uint8_t l2_slips = (uint8_t) (getlesl24(buf, n + 13) & 0x0f); + /*@ -predboolothers +charint @*/ + double c1 = + (sv_status & 0x80 ? (double)ca_pseudorange / 16.0 * + LAMBDA_L1 : NAN); + double l1 = + (sv_status & 0x80 ? (double)ca_pseudorange / 16.0 + + (double)l1_phase / 256.0 : NAN); + double l2 = + (sv_status & 0x20 + ? ((double)ca_pseudorange / 16.0 + + (double)p2_ca_pseudorange / 16.0) * (120.0 / 154.0) + + (double)l2_phase / 256.0 : NAN); + double p1 = + (sv_status & 0x40 ? c1 + + (double)p1_ca_pseudorange / 16.0 * LAMBDA_L1 : NAN); + double p2 = + (sv_status & 0x20 ? c1 + + (double)p2_ca_pseudorange / 16.0 * LAMBDA_L1 : NAN); + gpsd_report(LOG_IO + 1, + "Navcom: >> sv status = 0x%02x (PRN %u - C/A & L1 %s - P1 %s - P2 & L2 %s)\n", + sv_status, (sv_status & 0x1f), + (sv_status & 0x80 ? "valid" : "invalid"), + (sv_status & 0x40 ? "valid" : "invalid"), + (sv_status & 0x20 ? "valid" : "invalid")); + gpsd_report(LOG_IO + 1, + "Navcom: >>> ch status = 0x%02x (Logical channel: %u - CA C/No: %u dBHz) " + "sL1: %u, sL2: %u\n", ch_status, ch_status & 0x0f, + ((ch_status & 0xf0) >> 4) + 35, l1_slips, l2_slips); + gpsd_report(LOG_IO + 1, + "Navcom: >>> C1: %14.3f, L1: %14.3f, L2: %14.3f, P1: %14.3f, P2: %14.3f\n", + c1, l1, l2, p1, p2); + /*@ +predboolothers -charint @*/ + } +#undef LAMBDA_L1 + return 0; /* Raw measurements not yet implemented in gpsd */ +} + +/* Pseudorange Noise Statistics */ +static gps_mask_t handle_0xb5(struct gps_device_t *session) +{ + if (sizeof(double) == 8) { + gps_mask_t mask = TIME_IS; + union long_double l_d; + unsigned char *buf = session->packet.outbuffer + 3; + uint16_t week = getleuw(buf, 3); + uint32_t tow = getleul(buf, 5); + double rms = getled(buf, 9); +#ifdef __UNUSED__ + /* Reason why it's unused is these figures do not agree + * with those obtained from the PVT report (handle_0xb1). + * The figures from 0xb1 do agree with the values reported + * by Navcom's PC utility */ + double ellips_maj = getled(buf, 17); + double ellips_min = getled(buf, 25); + double ellips_azm = getled(buf, 33); + double lat_sd = getled(buf, 41); + double lon_sd = getled(buf, 49); + double alt_sd = getled(buf, 57); + double hrms = sqrt(pow(lat_sd, 2) + pow(lon_sd, 2)); +#endif /* __UNUSED__ */ + session->gpsdata.epe = rms * 1.96; + mask |= PERR_IS; +#ifdef __UNUSED__ + session->newdata.eph = hrms * 1.96; + session->newdata.epv = alt_sd * 1.96; + mask |= (HERR_IS | VERR_IS); +#endif /* __UNUSED__ */ + session->context->gps_week = (unsigned short)week; + session->context->gps_tow = (double)tow / 1000.0f; + /*@ ignore @*//*@ splint is confused @ */ + session->newdata.time = + gpstime_to_unix((int)week, session->context->gps_tow) + - session->context->leap_seconds; + /*@ end @*/ + gpsd_report(LOG_PROG, + "Navcom: received packet type 0xb5 (Pseudorange Noise Statistics)\n"); + gpsd_report(LOG_IO, "Navcom: epe = %f\n", session->gpsdata.epe); + return mask; + } else { + /* Ignore this message block */ + if (!session->driver.navcom.warned) { + gpsd_report(LOG_WARN, + "Navcom: received packet type 0xb5 (Pseudorange Noise Statistics) ignored " + " - sizeof(double) == 64 bits required\n"); + session->driver.navcom.warned = true; + } + return 0; /* Block ignored - wrong sizeof(double) */ + } +} + +/* LBM DSP Status Block */ +static gps_mask_t handle_0xd3(struct gps_device_t *session UNUSED) +{ + /* This block contains status information about the + * unit's L-band (Inmarsat) module. There is nothing + * interesting in it for our purposes so we do not deal + * with it. This callback is purely to a) stop + * "unrecognised packet" messages appearing in the log + * and b) explain what it is for the curious */ + return 0; /* Nothing updated */ +} + +/* Identification Block */ +static gps_mask_t handle_0xae(struct gps_device_t *session) +{ + /*@-modobserver@*/ + char *engconfstr, *asicstr; + unsigned char *buf = session->packet.outbuffer + 3; + size_t msg_len = (size_t) getleuw(buf, 1); + uint8_t engconf = getub(buf, 3); + uint8_t asic = getub(buf, 4); + uint8_t swvermaj = getub(buf, 5); + uint8_t swvermin = getub(buf, 6); + uint16_t dcser = getleuw(buf, 7); + uint8_t dcclass = getub(buf, 9); + uint16_t rfcser = getleuw(buf, 10); + uint8_t rfcclass = getub(buf, 12); + /*@ -stringliteralnoroomfinalnull -type @*/ + uint8_t softtm[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + uint8_t bootstr[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + uint8_t ioptm[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + /*@ +stringliteralnoroomfinalnull +type @*/ + uint8_t iopvermaj = (uint8_t) 0x00; + uint8_t iopvermin = (uint8_t) 0x00; + uint8_t picver = (uint8_t) 0x00; + uint8_t slsbn = (uint8_t) 0x00; + uint8_t iopsbn = (uint8_t) 0x00; + memcpy(softtm, &buf[13], 16); + memcpy(bootstr, &buf[29], 16); + if (msg_len == 0x0037) { /* No IOP */ + slsbn = getub(buf, 53); + } else { /* IOP Present */ + iopvermaj = getub(buf, 53); + iopvermin = getub(buf, 54); + memcpy(ioptm, &buf[55], 16); + picver = getub(buf, 71); + slsbn = getub(buf, 72); + iopsbn = getub(buf, 73); + } + + switch (engconf) { + case 0x00: + engconfstr = "Unknown/Undefined"; + break; + case 0x01: + engconfstr = "NCT 2000 S"; + break; + case 0x02: + engconfstr = "NCT 2000 D"; + break; + case 0x03: + engconfstr = "Startfire Single"; + break; + case 0x04: + engconfstr = "Starfire Dual"; + break; + case 0x05: + engconfstr = "Pole Mount RTK (Internal Radio)"; + break; + case 0x06: + engconfstr = "Pole Mount GIS (LBM)"; + break; + case 0x07: + engconfstr = "Black Box RTK (Internal Radio)"; + break; + case 0x08: + engconfstr = "Black Box GIS (LBM)"; + break; + case 0x80: + engconfstr = "R100"; + break; + case 0x81: + engconfstr = "R200"; + break; + case 0x82: + engconfstr = "R210"; + break; + case 0x83: + engconfstr = "R300"; + break; + case 0x84: + engconfstr = "R310"; + break; + default: + engconfstr = "?"; + } + + switch (asic) { + case 0x01: + asicstr = "A-ASIC"; + break; + case 0x02: + asicstr = "B-ASIC"; + break; + case 0x03: + asicstr = "C-ASIC"; + break; + case 0x04: + asicstr = "M-ASIC"; + break; + default: + asicstr = "?"; + } + + gpsd_report(LOG_PROG, + "Navcom: received packet type 0xae (Identification Block)\n"); + if (msg_len == 0x0037) { + gpsd_report(LOG_INF, "Navcom: ID Data: " + "%s %s Ver. %u.%u.%u, DC S/N: %u.%u, RF S/N: %u.%u, " + "Build ID: %s, Boot software: %s\n", + engconfstr, asicstr, swvermaj, swvermin, slsbn, dcser, + dcclass, rfcser, rfcclass, softtm, bootstr); + } else { + gpsd_report(LOG_INF, "Navcom: ID Data: " + "%s %s Ver. %u.%u.%u, DC S/N: %u.%u, RF S/N: %u.%u, " + "Build ID: %s, Boot software: %s, " + "IOP Ver.: %u.%u.%u, PIC: %u, IOP Build ID: %s\n", + engconfstr, asicstr, swvermaj, swvermin, slsbn, dcser, + dcclass, rfcser, rfcclass, softtm, bootstr, iopvermaj, + iopvermin, iopsbn, picver, ioptm); + } + + /*@ -formattype @*/ + (void)snprintf(session->subtype, sizeof(session->subtype), + "%s %s Ver. %u.%u.%u S/N %u.%u %u.%u", + engconfstr, asicstr, swvermaj, swvermin, slsbn, dcser, + dcclass, rfcser, rfcclass); + /*@ +formattype @*/ + return DEVICEID_IS; + /*@+modobserver@*/ +} + +/* Clock Drift and Offset */ +static gps_mask_t handle_0xef(struct gps_device_t *session) +{ + unsigned char *buf = session->packet.outbuffer + 3; + //uint16_t week = getleuw(buf, 3); + //uint32_t tow = getleul(buf, 5); + int8_t osc_temp = getsb(buf, 9); + uint8_t nav_status = getub(buf, 10); + union long_double l_d; + double nav_clock_offset; + union int_float i_f; + float nav_clock_drift; + float osc_filter_drift_est; + int32_t time_slew = (int32_t) getlesl(buf, 27); + if (sizeof(double) == 8) { + nav_clock_offset = getled(buf, 11); + } else { + nav_clock_offset = NAN; + } + if (sizeof(float) == 4) { + nav_clock_drift = getlef(buf, 19); + osc_filter_drift_est = getlef(buf, 23); + } else { + nav_clock_drift = NAN; + osc_filter_drift_est = NAN; + } + + //gpstime_to_unix((int)week, tow/1000.0) - session->context->leap_seconds; + + gpsd_report(LOG_IO, + "Navcom: oscillator temp. = %d, nav. status = 0x%02x, " + "nav. clock offset = %f, nav. clock drift = %f, " + "osc. filter drift est. = %f, acc.time slew value = %d\n", + osc_temp, nav_status, nav_clock_offset, nav_clock_drift, + osc_filter_drift_est, time_slew); + gpsd_report(LOG_DATA, + "CDO 0xef: time=%.2f mask={TIME}\n", session->newdata.time); + return 0; +} + + +/*@ +charint @*/ +gps_mask_t navcom_parse(struct gps_device_t * session, unsigned char *buf, + size_t len) +{ + unsigned char cmd_id; + unsigned char *payload; + unsigned int msg_len; + + if (len == 0) + return 0; + + cmd_id = (unsigned char)getub(buf, 3); + payload = &buf[6]; + msg_len = (uint) getleuw(buf, 4); + + /*@ -usedef -compdef @*/ + gpsd_report(LOG_RAW, "Navcom: packet type 0x%02x, length %d: %s\n", + cmd_id, msg_len, gpsd_hexdump_wrapper(buf, len, LOG_RAW)); + /*@ +usedef +compdef @*/ + + (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), + "0x%02x", cmd_id); + + session->cycle_end_reliable = true; + + switch (cmd_id) { + case 0x06: + return handle_0x06(session); + case 0x15: + return handle_0x15(session); + case 0x81: + return handle_0x81(session); + case 0x83: + return handle_0x83(session); + case 0x86: + return handle_0x86(session); + case 0xae: + return handle_0xae(session); + case 0xb0: + return handle_0xb0(session); + case 0xb1: + return handle_0xb1(session) | (CLEAR_IS | REPORT_IS); + case 0xb5: + return handle_0xb5(session); + case 0xd3: + return handle_0xd3(session); + case 0xef: + return handle_0xef(session); + default: + gpsd_report(LOG_PROG, + "Navcom: received packet type 0x%02x, length %d - unknown or unimplemented\n", + cmd_id, msg_len); + return 0; + } +} + +/*@ -charint @*/ + +static gps_mask_t navcom_parse_input(struct gps_device_t *session) +{ + gps_mask_t st; + + if (session->packet.type == NAVCOM_PACKET) { + st = navcom_parse(session, session->packet.outbuffer, + session->packet.outbuflen); + session->gpsdata.dev.driver_mode = MODE_BINARY; /* binary */ + return st; +#ifdef NMEA_ENABLE + } else if (session->packet.type == NMEA_PACKET) { + st = nmea_parse((char *)session->packet.outbuffer, session); + session->gpsdata.dev.driver_mode = MODE_NMEA; /* NMEA */ + return st; +#endif /* NMEA_ENABLE */ + } else + return 0; +} + +#ifdef ALLOW_CONTROLSEND +static ssize_t navcom_control_send(struct gps_device_t *session, + char *buf, size_t len) +{ + /*@ +ignoresigns -mayaliasunique @*/ + putbyte(session->msgbuf, 0, 0x02); + putbyte(session->msgbuf, 1, 0x99); + putbyte(session->msgbuf, 2, 0x66); + putbyte(session->msgbuf, 3, buf[0]); /* Cmd ID */ + putleword(session->msgbuf, 4, len + 4); /* Length */ + memcpy(session->msgbuf, buf + 6, len - 1); + putbyte(session->msgbuf, 6 + len, + checksum((unsigned char *)session->msgbuf + 3, len + 5)); + putbyte(session->msgbuf, 7 + len, 0x03); + session->msgbuflen = len + 9; + /*@ -ignoresigns +mayaliasunique @*/ + gpsd_report(LOG_RAW, "Navcom: control dump: %s\n", + gpsd_hexdump_wrapper(session->msgbuf, session->msgbuflen, + LOG_RAW)); + return gpsd_write(session, session->msgbuf, session->msgbuflen); +} +#endif /* ALLOW_CONTROLSEND */ + +#ifdef ALLOW_RECONFIGURE +static bool navcom_speed(struct gps_device_t *session, + speed_t speed, char parity, int stopbits) +{ + /* parity and stopbit switching aren't implemented */ + if (parity != session->gpsdata.dev.parity + || stopbits != (int)session->gpsdata.dev.parity) { + return false; + } else { + uint8_t port, port_selection; + uint8_t baud; + if (session->driver.navcom.physical_port == (uint8_t) 0xFF) { + /* We still don't know which port we're connected to */ + return false; + } + /*@ +charint @*/ + switch (speed) { + /* NOTE - The spec says that certain baud combinations + * on ports A and B are not allowed, those are + * 1200/115200, 2400/57600, and 2400/115200. + * To try and minimise the possibility of those + * occurring, we do not allow baud rates below + * 4800. We could also disallow 57600 and 115200 + * to totally prevent this, but I do not consider + * that reasonable. Finding which baud speed the + * other port is set at would also be too much + * trouble, so we do not do it. */ + case 4800: + baud = 0x04; + break; + case 9600: + baud = 0x06; + break; + case 19200: + baud = 0x08; + break; + case 38400: + baud = 0x0a; + break; + case 57600: + baud = 0x0c; + break; + case 115200: + baud = 0x0e; + break; + default: + /* Unsupported speed */ + return false; + } + /*@ -charint @*/ + + /* Proceed to construct our message */ + port = session->driver.navcom.physical_port; + /*@i1@*/ port_selection = (port ? port : (uint8_t) 0xff) | baud; + + /* Send it off */ + navcom_cmd_0x11(session, port_selection); + + /* And cheekily return true, even though we have + * no way to know if the speed change succeeded + * until and if we receive an ACK (message 0x06), + * which will be at the new baud speed if the + * command was successful. Bottom line, the client + * should requery gpsd to see if the new speed is + * different than the old one */ + return true; + } +} +#endif /* ALLOW_RECONFIGURE */ + +/* this is everything we export */ +/* *INDENT-OFF* */ +const struct gps_type_t navcom_binary = +{ + .type_name = "Navcom binary", /* full name of type */ + .packet_type = NAVCOM_PACKET, /* lexer packet type */ + .trigger = "\x02\x99\x66", /* packet leader */ + .channels = NAVCOM_CHANNELS, /* 12 L1 + 12 L2 + 2 Inmarsat L-Band */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* use generic one */ + .parse_packet = navcom_parse_input, /* parse message packets */ + .rtcm_writer = pass_rtcm, /* send RTCM data straight */ + .event_hook = navcom_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = navcom_speed, /* we do change baud rates */ + .mode_switcher = NULL, /* there is not a mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* ignore, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = navcom_control_send, /* how to send a control string */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ + +#endif /* defined(NAVCOM_ENABLE) && defined(BINARY_ENABLE) */ diff --git a/driver_nmea.c b/driver_nmea.c new file mode 100644 index 0000000..fbefc66 --- /dev/null +++ b/driver_nmea.c @@ -0,0 +1,1158 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "timebase.h" + +#ifdef NMEA_ENABLE +/************************************************************************** + * + * Parser helpers begin here + * + **************************************************************************/ + +static void do_lat_lon(char *field[], struct gps_fix_t *out) +/* process a pair of latitude/longitude fields starting at field index BEGIN */ +{ + double lat, lon, d, m; + char str[20], *p; + + if (*(p = field[0]) != '\0') { + strncpy(str, p, 20); + (void)sscanf(p, "%lf", &lat); + m = 100.0 * modf(lat / 100.0, &d); + lat = d + m / 60.0; + p = field[1]; + if (*p == 'S') + lat = -lat; + out->latitude = lat; + } + if (*(p = field[2]) != '\0') { + strncpy(str, p, 20); + (void)sscanf(p, "%lf", &lon); + m = 100.0 * modf(lon / 100.0, &d); + lon = d + m / 60.0; + + p = field[3]; + if (*p == 'W') + lon = -lon; + out->longitude = lon; + } +} + +/************************************************************************** + * + * Scary timestamp fudging begins here + * + * Four sentences, GGA and GLL and RMC and ZDA, contain timestamps. + * GGA/GLL/RMC timestamps look like hhmmss.ss, with the trailing .ss part + * optional. RMC has a date field, in the format ddmmyy. ZDA has + * separate fields for day/month/year, with a 4-digit year. This + * means that for RMC we must supply a century and for GGA and GLL we + * must supply a century, year, and day. We get the missing data from + * a previous RMC or ZDA; century in RMC is supplied by a constant if + * there has been no previous ZDA. + * + **************************************************************************/ + +#define DD(s) ((int)((s)[0]-'0')*10+(int)((s)[1]-'0')) + +static void merge_ddmmyy(char *ddmmyy, struct gps_device_t *session) +/* sentence supplied ddmmyy, but no century part */ +{ + int yy = DD(ddmmyy + 4), year = session->driver.nmea.date.tm_year; + int mon = DD(ddmmyy + 2); + int mday = DD(ddmmyy); + + if (year <= 0) { + year = (CENTURY_BASE + yy) - 1900; + } else if (year % 100 != yy) { + /* update year */ + if (year % 100 == 99 && yy == 0) + yy += 100; /* century change */ + year = year / 100 * 100 + yy; + } + if ( (1 > year ) || (2200 < year ) ) { + gpsd_report(LOG_WARN, "merge_ddmmyy(), bad year: %d\n", year); + } else if ( (1 > mon ) || (12 < mon ) ) { + gpsd_report(LOG_WARN, "merge_ddmmyy(), malformed month: %2s\n", ddmmyy + 2); + } else if ( (1 > mday ) || (31 < mday ) ) { + gpsd_report(LOG_WARN, "merge_ddmmyy(), malformed day: %2s\n", ddmmyy); + } else { + gpsd_report(LOG_DATA, "merge_ddmmyy(ddmmyy) sets year %d from %s\n", + year, ddmmyy); + session->driver.nmea.date.tm_year = year; + session->driver.nmea.date.tm_mon = mon - 1; + session->driver.nmea.date.tm_mday = mday; + } +} + +static void merge_hhmmss(char *hhmmss, struct gps_device_t *session) +/* update from a UTC time */ +{ + int old_hour = session->driver.nmea.date.tm_hour; + + session->driver.nmea.date.tm_hour = DD(hhmmss); + if (session->driver.nmea.date.tm_hour < old_hour) /* midnight wrap */ + session->driver.nmea.date.tm_mday++; + session->driver.nmea.date.tm_min = DD(hhmmss + 2); + session->driver.nmea.date.tm_sec = DD(hhmmss + 4); + session->driver.nmea.subseconds = + atof(hhmmss + 4) - session->driver.nmea.date.tm_sec; +} + +static void register_fractional_time(const char *tag, const char *fld, + struct gps_device_t *session) +{ + if (fld[0] != '\0') { + session->driver.nmea.last_frac_time = + session->driver.nmea.this_frac_time; + session->driver.nmea.this_frac_time = atof(fld); + session->driver.nmea.latch_frac_time = true; + gpsd_report(LOG_DATA, "%s: registers fractional time %.2f\n", + tag, session->driver.nmea.this_frac_time); + } +} + +/************************************************************************** + * + * Compare GPS timestamps for equality. Depends on the fact that the + * timestamp granularity of GPS is 1/100th of a second. Use this to avoid + * naive float comparisons. + * + **************************************************************************/ + +#define GPS_TIME_EQUAL(a, b) (fabs((a) - (b)) < 0.01) + +/************************************************************************** + * + * NMEA sentence handling begins here + * + **************************************************************************/ + +static gps_mask_t processGPRMC(int count, char *field[], + struct gps_device_t *session) +/* Recommend Minimum Course Specific GPS/TRANSIT Data */ +{ + /* + * RMC,225446.33,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E,A*68 + * 1 225446.33 Time of fix 22:54:46 UTC + * 2 A Status of Fix: A = Autonomous, valid; + * D = Differential, valid; V = invalid + * 3,4 4916.45,N Latitude 49 deg. 16.45 min North + * 5,6 12311.12,W Longitude 123 deg. 11.12 min West + * 7 000.5 Speed over ground, Knots + * 8 054.7 Course Made Good, True north + * 9 181194 Date of fix 18 November 1994 + * 10,11 020.3,E Magnetic variation 20.3 deg East + * 12 A FAA mode indicator (NMEA 2.3 and later) + * A=autonomous, D=differential, E=Estimated, + * N=not valid, S=Simulator, M=Manual input mode + * *68 mandatory nmea_checksum + * + * * SiRF chipsets don't return either Mode Indicator or magnetic variation. + */ + gps_mask_t mask = 0; + + if (strcmp(field[2], "V") == 0) { + /* copes with Magellan EC-10X, see below */ + if (session->gpsdata.status != STATUS_NO_FIX) { + session->gpsdata.status = STATUS_NO_FIX; + mask |= STATUS_IS; + } + if (session->newdata.mode >= MODE_2D) { + session->newdata.mode = MODE_NO_FIX; + mask |= MODE_IS; + } + /* set something nz, so it won't look like an unknown sentence */ + mask |= ONLINE_IS; + } else if (strcmp(field[2], "A") == 0) { + /* + * The MKT3301, Royaltek RGM-3800, and possibly other + * devices deliver bogus time values when the navigation + * warning bit is set. + */ + if (count > 9 && field[1][0] != '\0' && field[9][0] != '\0') { + merge_hhmmss(field[1], session); + merge_ddmmyy(field[9], session); + mask |= TIME_IS; + register_fractional_time(field[0], field[1], session); + } + do_lat_lon(&field[3], &session->newdata); + mask |= LATLON_IS; + session->newdata.speed = atof(field[7]) * KNOTS_TO_MPS; + session->newdata.track = atof(field[8]); + mask |= (TRACK_IS | SPEED_IS); + /* + * This copes with GPSes like the Magellan EC-10X that *only* emit + * GPRMC. In this case we set mode and status here so the client + * code that relies on them won't mistakenly believe it has never + * received a fix. + */ + if (session->gpsdata.status == STATUS_NO_FIX) { + session->gpsdata.status = STATUS_FIX; /* could be DGPS_FIX, we can't tell */ + mask |= STATUS_IS; + } + if (session->newdata.mode < MODE_2D) { + session->newdata.mode = MODE_2D; + mask |= MODE_IS; + } + } + + gpsd_report(LOG_DATA, + "RMC: ddmmyy=%s hhmmss=%s lat=%.2f lon=%.2f " + "speed=%.2f track=%.2f mode=%d status=%d mask=%s\n", + field[9], field[1], + session->newdata.latitude, + session->newdata.longitude, + session->newdata.speed, + session->newdata.track, + session->newdata.mode, + session->gpsdata.status, gpsd_maskdump(mask)); + return mask; +} + +static gps_mask_t processGPGLL(int count, char *field[], + struct gps_device_t *session) +/* Geographic position - Latitude, Longitude */ +{ + /* Introduced in NMEA 3.0. + * + * $GPGLL,4916.45,N,12311.12,W,225444,A,A*5C + * + * 1,2: 4916.46,N Latitude 49 deg. 16.45 min. North + * 3,4: 12311.12,W Longitude 123 deg. 11.12 min. West + * 5: 225444 Fix taken at 22:54:44 UTC + * 6: A Data valid + * 7: A Autonomous mode + * 8: *5C Mandatory NMEA checksum + * + * 1,2 Latitude, N (North) or S (South) + * 3,4 Longitude, E (East) or W (West) + * 5 UTC of position + * 6 A=Active, V=Void + * 7 Mode Indicator + * A = Autonomous mode + * D = Differential Mode + * E = Estimated (dead-reckoning) mode + * M = Manual Input Mode + * S = Simulated Mode + * N = Data Not Valid + * + * I found a note at + * indicating that the Garmin 65 does not return time and status. + * SiRF chipsets don't return the Mode Indicator. + * This code copes gracefully with both quirks. + * + * Unless you care about the FAA indicator, this sentence supplies nothing + * that GPRMC doesn't already. But at least one Garmin GPS -- the 48 + * actually ships updates in GPLL that aren't redundant. + */ + char *status = field[7]; + gps_mask_t mask = 0; + + if (field[5][0] != '\0') { + merge_hhmmss(field[5], session); + register_fractional_time(field[0], field[5], session); + if (session->driver.nmea.date.tm_year == 0) + gpsd_report(LOG_WARN, + "can't use GLL time until after ZDA or RMC has supplied a year.\n"); + else { + mask = TIME_IS; + } + } + if (strcmp(field[6], "A") == 0 && (count < 8 || *status != 'N')) { + int newstatus = session->gpsdata.status; + + do_lat_lon(&field[1], &session->newdata); + mask |= LATLON_IS; + if (count >= 8 && *status == 'D') + newstatus = STATUS_DGPS_FIX; /* differential */ + else + newstatus = STATUS_FIX; + /* + * This is a bit dodgy. Technically we shouldn't set the mode + * bit until we see GSA. But it may be later in the cycle, + * some devices like the FV-18 don't send it by default, and + * elsewhere in the code we want to be able to test for the + * presence of a valid fix with mode > MODE_NO_FIX. + */ + if (session->newdata.mode < MODE_2D) { + session->newdata.mode = MODE_2D; + mask |= MODE_IS; + } + session->gpsdata.status = newstatus; + mask |= STATUS_IS; + } + + gpsd_report(LOG_DATA, + "GLL: hhmmss=%s lat=%.2f lon=%.2f mode=%d status=%d mask=%s\n", + field[5], + session->newdata.latitude, + session->newdata.longitude, + session->newdata.mode, + session->gpsdata.status, gpsd_maskdump(mask)); + return mask; +} + +static gps_mask_t processGPGGA(int c UNUSED, char *field[], + struct gps_device_t *session) +/* Global Positioning System Fix Data */ +{ + /* + * GGA,123519,4807.038,N,01131.324,E,1,08,0.9,545.4,M,46.9,M, , *42 + * 1 123519 Fix taken at 12:35:19 UTC + * 2,3 4807.038,N Latitude 48 deg 07.038' N + * 4,5 01131.324,E Longitude 11 deg 31.324' E + * 6 1 Fix quality: 0 = invalid, 1 = GPS, 2 = DGPS, + * 3=PPS (Precise Position Service), + * 4=RTK (Real Time Kinematic) with fixed integers, + * 5=Float RTK, 6=Estimated, 7=Manual, 8=Simulator + * 7 08 Number of satellites being tracked + * 8 0.9 Horizontal dilution of position + * 9,10 545.4,M Altitude, Metres above mean sea level + * 11,12 46.9,M Height of geoid (mean sea level) above WGS84 + * ellipsoid, in Meters + * (empty field) time in seconds since last DGPS update + * (empty field) DGPS station ID number (0000-1023) + */ + gps_mask_t mask; + + session->gpsdata.status = atoi(field[6]); + mask = STATUS_IS; + if (session->gpsdata.status > STATUS_NO_FIX) { + char *altitude; + + merge_hhmmss(field[1], session); + register_fractional_time(field[0], field[1], session); + if (session->driver.nmea.date.tm_year == 0) + gpsd_report(LOG_WARN, + "can't use GGA time until after ZDA or RMC has supplied a year.\n"); + else { + mask |= TIME_IS; + } + do_lat_lon(&field[2], &session->newdata); + mask |= LATLON_IS; + session->gpsdata.satellites_used = atoi(field[7]); + altitude = field[9]; + /* + * SiRF chipsets up to version 2.2 report a null altitude field. + * See . + * If we see this, force mode to 2D at most. + */ + if (altitude[0] == '\0') { + if (session->newdata.mode == MODE_3D) { + session->newdata.mode = + session->gpsdata.status ? MODE_2D : MODE_NO_FIX; + mask |= MODE_IS; + } + } else { + session->newdata.altitude = atof(altitude); + mask |= ALTITUDE_IS; + /* + * This is a bit dodgy. Technically we shouldn't set the mode + * bit until we see GSA. But it may be later in the cycle, + * some devices like the FV-18 don't send it by default, and + * elsewhere in the code we want to be able to test for the + * presence of a valid fix with mode > MODE_NO_FIX. + */ + if (session->newdata.mode < MODE_3D) { + session->newdata.mode = MODE_3D; + mask |= MODE_IS; + } + } + if (strlen(field[11]) > 0) { + session->gpsdata.separation = atof(field[11]); + } else { + session->gpsdata.separation = + wgs84_separation(session->newdata.latitude, + session->newdata.longitude); + } + } + gpsd_report(LOG_DATA, + "GGA: hhmmss=%s lat=%.2f lon=%.2f alt=%.2f mode=%d status=%d mask=%s\n", + field[1], + session->newdata.latitude, + session->newdata.longitude, + session->newdata.altitude, + session->newdata.mode, + session->gpsdata.status, gpsd_maskdump(mask)); + return mask; +} + +static gps_mask_t processGPGSA(int count, char *field[], + struct gps_device_t *session) +/* GPS DOP and Active Satellites */ +{ + /* + * eg1. $GPGSA,A,3,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C + * eg2. $GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*35 + * 1 = Mode: + * M=Manual, forced to operate in 2D or 3D + * A=Automatic, 3D/2D + * 2 = Mode: 1=Fix not available, 2=2D, 3=3D + * 3-14 = PRNs of satellites used in position fix (null for unused fields) + * 15 = PDOP + * 16 = HDOP + * 17 = VDOP + */ + gps_mask_t mask; + + /* + * One chipset called the i.Trek M3 issues GPGSA lines that look like + * this: "$GPGSA,A,1,,,,*32" when it has no fix. This is broken + * in at least two ways: it's got the wrong number of fields, and + * it claims to be a valid sentence (A flag) when it isn't. + * Alarmingly, it's possible this error may be generic to SiRFstarIII. + */ + if (count < 17) { + gpsd_report(LOG_DATA, "GPGSA: malformed, setting ONLINE_IS only.\n"); + mask = ONLINE_IS; + } else { + int i; + session->newdata.mode = atoi(field[2]); + /* + * The first arm of this conditional ignores dead-reckoning + * fixes from an Antaris chipset. which returns E in field 2 + * for a dead-reckoning estimate. Fix by Andreas Stricker. + */ + if (session->newdata.mode == 0 && field[2][0] == 'E') + mask = 0; + else + mask = MODE_IS; + gpsd_report(LOG_PROG, "GPGSA sets mode %d\n", session->newdata.mode); + session->gpsdata.dop.pdop = atof(field[15]); + session->gpsdata.dop.hdop = atof(field[16]); + session->gpsdata.dop.vdop = atof(field[17]); + session->gpsdata.satellites_used = 0; + memset(session->gpsdata.used, 0, sizeof(session->gpsdata.used)); + /* the magic 6 here counts the tag, two mode fields, and the DOP fields */ + for (i = 0; i < count - 6; i++) { + int prn = atoi(field[i + 3]); + if (prn > 0) + session->gpsdata.used[session->gpsdata.satellites_used++] = + prn; + } + mask |= DOP_IS | USED_IS; + gpsd_report(LOG_DATA, + "GPGSA: mode=%d used=%d pdop=%.2f hdop=%.2f vdop=%.2f mask=%s\n", + session->newdata.mode, + session->gpsdata.satellites_used, + session->gpsdata.dop.pdop, + session->gpsdata.dop.hdop, + session->gpsdata.dop.vdop, gpsd_maskdump(mask)); + } + return mask; +} + +static gps_mask_t processGPGSV(int count, char *field[], + struct gps_device_t *session) +/* GPS Satellites in View */ +{ + /* + * GSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75 + * 2 Number of sentences for full data + * 1 Sentence 1 of 2 + * 08 Total number of satellites in view + * 01 Satellite PRN number + * 40 Elevation, degrees + * 083 Azimuth, degrees + * 46 Signal-to-noise ratio in decibels + * + * There my be up to three GSV sentences in a data packet + */ + int n, fldnum; + if (count <= 3) { + gpsd_zero_satellites(&session->gpsdata); + session->gpsdata.satellites_visible = 0; + return 0; + } + if (count % 4 != 0) { + gpsd_report(LOG_WARN, "malformed GPGSV - fieldcount %d %% 4 != 0\n", + count); + gpsd_zero_satellites(&session->gpsdata); + session->gpsdata.satellites_visible = 0; + return 0; + } + + session->driver.nmea.await = atoi(field[1]); + if (sscanf(field[2], "%d", &session->driver.nmea.part) < 1) { + gpsd_zero_satellites(&session->gpsdata); + return 0; + } else if (session->driver.nmea.part == 1) + gpsd_zero_satellites(&session->gpsdata); + + for (fldnum = 4; fldnum < count;) { + if (session->gpsdata.satellites_visible >= MAXCHANNELS) { + gpsd_report(LOG_ERROR, "internal error - too many satellites!\n"); + gpsd_zero_satellites(&session->gpsdata); + break; + } + session->gpsdata.PRN[session->gpsdata.satellites_visible] = + atoi(field[fldnum++]); + session->gpsdata.elevation[session->gpsdata.satellites_visible] = + atoi(field[fldnum++]); + session->gpsdata.azimuth[session->gpsdata.satellites_visible] = + atoi(field[fldnum++]); + session->gpsdata.ss[session->gpsdata.satellites_visible] = + (float)atoi(field[fldnum++]); + /* + * Incrementing this unconditionally falls afoul of chipsets like + * the Motorola Oncore GT+ that emit empty fields at the end of the + * last sentence in a GPGSV set if the number of satellites is not + * a multiple of 4. + */ + if (session->gpsdata.PRN[session->gpsdata.satellites_visible] != 0) + session->gpsdata.satellites_visible++; + } + if (session->driver.nmea.part == session->driver.nmea.await + && atoi(field[3]) != session->gpsdata.satellites_visible) + gpsd_report(LOG_WARN, + "GPGSV field 3 value of %d != actual count %d\n", + atoi(field[3]), session->gpsdata.satellites_visible); + + /* not valid data until we've seen a complete set of parts */ + if (session->driver.nmea.part < session->driver.nmea.await) { + gpsd_report(LOG_PROG, "Partial satellite data (%d of %d).\n", + session->driver.nmea.part, session->driver.nmea.await); + return 0; + } + /* + * This sanity check catches an odd behavior of SiRFstarII receivers. + * When they can't see any satellites at all (like, inside a + * building) they sometimes cough up a hairball in the form of a + * GSV packet with all the azimuth entries 0 (but nonzero + * elevations). This behavior was observed under SiRF firmware + * revision 231.000.000_A2. + */ + for (n = 0; n < session->gpsdata.satellites_visible; n++) + if (session->gpsdata.azimuth[n] != 0) + goto sane; + gpsd_report(LOG_WARN, "Satellite data no good (%d of %d).\n", + session->driver.nmea.part, session->driver.nmea.await); + gpsd_zero_satellites(&session->gpsdata); + return 0; + sane: + session->gpsdata.skyview_time = NAN; + gpsd_report(LOG_DATA, "GSV: Satellite data OK (%d of %d).\n", + session->driver.nmea.part, session->driver.nmea.await); + return SATELLITE_IS; +} + +static gps_mask_t processPGRME(int c UNUSED, char *field[], + struct gps_device_t *session) +/* Garmin Estimated Position Error */ +{ + /* + * $PGRME,15.0,M,45.0,M,25.0,M*22 + * 1 = horizontal error estimate + * 2 = units + * 3 = vertical error estimate + * 4 = units + * 5 = spherical error estimate + * 6 = units + * * + * * Garmin won't say, but the general belief is that these are 50% CEP. + * * We follow the advice at . + * * If this assumption changes here, it should also change in garmin.c + * * where we scale error estimates from Garmin binary packets, and + * * in libgpsd_core.c where we generate $PGRME. + */ + gps_mask_t mask; + if ((strcmp(field[2], "M") != 0) || + (strcmp(field[4], "M") != 0) || (strcmp(field[6], "M") != 0)) { + session->newdata.epx = + session->newdata.epy = + session->newdata.epv = session->gpsdata.epe = 100; + mask = 0; + } else { + session->newdata.epx = session->newdata.epy = + atof(field[1]) * (1 / sqrt(2)) * (GPSD_CONFIDENCE / CEP50_SIGMA); + session->newdata.epv = + atof(field[3]) * (GPSD_CONFIDENCE / CEP50_SIGMA); + session->gpsdata.epe = + atof(field[5]) * (GPSD_CONFIDENCE / CEP50_SIGMA); + mask = HERR_IS | VERR_IS | PERR_IS; + } + + gpsd_report(LOG_DATA, "PGRME: epx=%.2f epy=%.2f epv=%.2f mask=%s\n", + session->newdata.epx, + session->newdata.epy, + session->newdata.epv, gpsd_maskdump(mask)); + return mask; +} + +static gps_mask_t processGPGBS(int c UNUSED, char *field[], + struct gps_device_t *session) +/* NMEA 3.0 Estimated Position Error */ +{ + /* + * $GPGBS,082941.00,2.4,1.5,3.9,25,,-43.7,27.5*65 + * 1) UTC time of the fix associated with this sentence (hhmmss.ss) + * 2) Expected error in latitude (meters) + * 3) Expected error in longitude (meters) + * 4) Expected error in altitude (meters) + * 5) PRN of most likely failed satellite + * 6) Probability of missed detection for most likely failed satellite + * 7) Estimate of bias in meters on most likely failed satellite + * 8) Standard deviation of bias estimate + * 9) Checksum + */ + + /* register fractional time for end-of-cycle detection */ + register_fractional_time(field[0], field[1], session); + + /* check that we're associated with the current fix */ + if (session->driver.nmea.date.tm_hour == DD(field[1]) + && session->driver.nmea.date.tm_min == DD(field[1] + 2) + && session->driver.nmea.date.tm_sec == DD(field[1] + 4)) { + session->newdata.epy = atof(field[2]); + session->newdata.epx = atof(field[3]); + session->newdata.epv = atof(field[4]); + gpsd_report(LOG_DATA, "GBS: epx=%.2f epy=%.2f epv=%.2f mask=%s\n", + session->newdata.epx, + session->newdata.epy, + session->newdata.epv, gpsd_maskdump(HERR_IS | VERR_IS)); + return HERR_IS | VERR_IS; + } else { + gpsd_report(LOG_PROG, + "second in $GPGBS error estimates doesn't match.\n"); + return 0; + } +} + +static gps_mask_t processGPZDA(int c UNUSED, char *field[], + struct gps_device_t *session) +/* Time & Date */ +{ + /* + * $GPZDA,160012.71,11,03,2004,-1,00*7D + * 1) UTC time (hours, minutes, seconds, may have fractional subsecond) + * 2) Day, 01 to 31 + * 3) Month, 01 to 12 + * 4) Year (4 digits) + * 5) Local zone description, 00 to +- 13 hours + * 6) Local zone minutes description, apply same sign as local hours + * 7) Checksum + * + * Note: some devices, like the uBlox ANTARIS 4h, are known to ship ZDAs + * with some fields blank under poorly-understood circumstances (probably + * when they don't have satellite lock yet). + */ + gps_mask_t mask = 0; + + if (field[1][0] == '\0' || field[2][0] == '\0' || field[3][0] == '\0' + || field[4][0] == '\0') { + gpsd_report(LOG_WARN, "malformed ZDA\n"); + } else { + int year, mon, mday; + + merge_hhmmss(field[1], session); + /* + * We don't register fractional time here because want to leave + * ZDA out of end-of-cycle detection. Some devices sensibly emit it only + * when they have a fix, so watching for it can make them look + * like they have a variable fix reporting cycle. + */ + year = atoi(field[4]); + mon = atoi(field[3]); + mday = atoi(field[2]); + if ( (1900 > year ) || (2200 < year ) ) { + gpsd_report(LOG_WARN, "malformed ZDA year: %s\n", field[4]); + } else if ( (1 > mon ) || (12 < mon ) ) { + gpsd_report(LOG_WARN, "malformed ZDA month: %s\n", field[3]); + } else if ( (1 > mday ) || (31 < mday ) ) { + gpsd_report(LOG_WARN, "malformed ZDA day: %s\n", field[2]); + } else { + year -= 1900; + session->driver.nmea.date.tm_year = year; + session->driver.nmea.date.tm_mon = mon - 1; + session->driver.nmea.date.tm_mday = mday; + mask = TIME_IS; + } + }; + gpsd_report(LOG_DATA, "ZDA: mask=%s\n", gpsd_maskdump(mask)); + return mask; +} + +#ifdef TNT_ENABLE +static gps_mask_t processTNTHTM(int c UNUSED, char *field[], + struct gps_device_t *session) +{ + /* + * Proprietary sentence for True North Technologies Magnetic Compass. + * This may also apply to some Honeywell units since they may have been + * designed by True North. + + $PTNTHTM,14223,N,169,N,-43,N,13641,2454*15 + + HTM,x.x,a,x.x,a,x.x,a,x.x,x.x*hh + Fields in order: + 1. True heading (compass measurement + deviation + variation) + 2. magnetometer status character: + C = magnetometer calibration alarm + L = low alarm + M = low warning + N = normal + O = high warning + P = high alarm + V = magnetometer voltage level alarm + 3. pitch angle + 4. pitch status character - see field 2 above + 5. roll angle + 6. roll status character - see field 2 above + 7. dip angle + 8. relative magnitude horizontal component of earth's magnetic field + *hh mandatory nmea_checksum + + By default, angles are reported as 26-bit integers: weirdly, the + technical manual says either 0 to 65535 or -32768 to 32767 can + occur as a range. + */ + gps_mask_t mask; + mask = ONLINE_IS; + + session->gpsdata.attitude.heading = atof(field[1]); + session->gpsdata.attitude.mag_st = *field[2]; + session->gpsdata.attitude.pitch = atof(field[3]); + session->gpsdata.attitude.pitch_st = *field[4]; + session->gpsdata.attitude.roll = atof(field[5]); + session->gpsdata.attitude.roll_st = *field[6]; + session->gpsdata.attitude.yaw = NAN; + session->gpsdata.attitude.yaw_st = '\0'; + session->gpsdata.attitude.dip = atof(field[7]); + session->gpsdata.attitude.mag_len = NAN; + session->gpsdata.attitude.mag_x = atof(field[8]); + session->gpsdata.attitude.mag_y = NAN; + session->gpsdata.attitude.mag_z = NAN; + session->gpsdata.attitude.acc_len = NAN; + session->gpsdata.attitude.acc_x = NAN; + session->gpsdata.attitude.acc_y = NAN; + session->gpsdata.attitude.acc_z = NAN; + session->gpsdata.attitude.gyro_x = NAN; + session->gpsdata.attitude.gyro_y = NAN; + mask |= (ATT_IS); + + gpsd_report(LOG_RAW, "time %.3f, heading %lf (%c).\n", + session->newdata.time, + session->gpsdata.attitude.heading, + session->gpsdata.attitude.mag_st); + return mask; +} +#endif /* TNT_ENABLE */ + +#ifdef OCEANSERVER_ENABLE +static gps_mask_t processOHPR(int c UNUSED, char *field[], + struct gps_device_t *session) +{ + /* + * Proprietary sentence for OceanServer Magnetic Compass. + + OHPR,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x*hh + Fields in order: + 1. Azimuth + 2. Pitch Angle + 3. Roll Angle + 4. Sensor temp, degrees centigrade + 5. Depth (feet) + 6. Magnetic Vector Length + 7-9. 3 axis Magnetic Field readings x,y,z + 10. Acceleration Vector Length + 11-13. 3 axis Acceleration Readings x,y,z + 14. Reserved + 15-16. 2 axis Gyro Output, X,y + 17. Reserved + 18. Reserved + *hh mandatory nmea_checksum + */ + gps_mask_t mask; + mask = ONLINE_IS; + + session->gpsdata.attitude.heading = atof(field[1]); + session->gpsdata.attitude.mag_st = '\0'; + session->gpsdata.attitude.pitch = atof(field[2]); + session->gpsdata.attitude.pitch_st = '\0'; + session->gpsdata.attitude.roll = atof(field[3]); + session->gpsdata.attitude.roll_st = '\0'; + session->gpsdata.attitude.yaw = NAN; + session->gpsdata.attitude.yaw_st = '\0'; + session->gpsdata.attitude.dip = NAN; + session->gpsdata.attitude.temp = atof(field[4]); + session->gpsdata.attitude.depth = atof(field[5]) / METERS_TO_FEET; + session->gpsdata.attitude.mag_len = atof(field[6]); + session->gpsdata.attitude.mag_x = atof(field[7]); + session->gpsdata.attitude.mag_y = atof(field[8]); + session->gpsdata.attitude.mag_z = atof(field[9]); + session->gpsdata.attitude.acc_len = atof(field[10]); + session->gpsdata.attitude.acc_x = atof(field[11]); + session->gpsdata.attitude.acc_y = atof(field[12]); + session->gpsdata.attitude.acc_z = atof(field[13]); + session->gpsdata.attitude.gyro_x = atof(field[15]); + session->gpsdata.attitude.gyro_y = atof(field[16]); + mask |= (ALTITUDE_IS); + + gpsd_report(LOG_RAW, "Heading %lf.\n", session->gpsdata.attitude.heading); + return mask; +} +#endif /* OCEANSERVER_ENABLE */ + +#ifdef ASHTECH_ENABLE +static gps_mask_t processPASHR(int c UNUSED, char *field[], + struct gps_device_t *session) +{ + gps_mask_t mask; + mask = 0; + + if (0 == strcmp("RID", field[1])) { /* Receiver ID */ + (void)snprintf(session->subtype, sizeof(session->subtype) - 1, + "%s ver %s", field[2], field[3]); + gpsd_report(LOG_DATA, "PASHR,RID: subtype=%s mask={}\n", + session->subtype); + return mask; + } else if (0 == strcmp("POS", field[1])) { /* 3D Position */ + mask |= MODE_IS | STATUS_IS | CLEAR_IS; + if (0 == strlen(field[2])) { + /* empty first field means no 3D fix is available */ + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + } else { + /* if we make it this far, we at least have a 3D fix */ + session->newdata.mode = MODE_3D; + if (1 == atoi(field[2])) + session->gpsdata.status = STATUS_DGPS_FIX; + else + session->gpsdata.status = STATUS_FIX; + + session->gpsdata.satellites_used = atoi(field[3]); + merge_hhmmss(field[4], session); + register_fractional_time(field[0], field[4], session); + do_lat_lon(&field[5], &session->newdata); + session->newdata.altitude = atof(field[9]); + session->newdata.track = atof(field[11]); + session->newdata.speed = atof(field[12]) / MPS_TO_KPH; + session->newdata.climb = atof(field[13]); + session->gpsdata.dop.pdop = atof(field[14]); + session->gpsdata.dop.hdop = atof(field[15]); + session->gpsdata.dop.vdop = atof(field[16]); + session->gpsdata.dop.tdop = atof(field[17]); + mask |= (TIME_IS | LATLON_IS | ALTITUDE_IS); + mask |= (SPEED_IS | TRACK_IS | CLIMB_IS); + mask |= DOP_IS; + gpsd_report(LOG_DATA, + "PASHR,POS: hhmmss=%s lat=%.2f lon=%.2f alt=%.f speed=%.2f track=%.2f climb=%.2f mode=%d status=%d pdop=%.2f hdop=%.2f vdop=%.2f tdop=%.2f mask=%s\n", + field[4], session->newdata.latitude, + session->newdata.longitude, session->newdata.altitude, + session->newdata.speed, session->newdata.track, + session->newdata.climb, session->newdata.mode, + session->gpsdata.status, session->gpsdata.dop.pdop, + session->gpsdata.dop.hdop, session->gpsdata.dop.vdop, + session->gpsdata.dop.tdop, gpsd_maskdump(mask)); + } + } else if (0 == strcmp("SAT", field[1])) { /* Satellite Status */ + int i, n, p, u; + n = session->gpsdata.satellites_visible = atoi(field[2]); + u = 0; + for (i = 0; i < n; i++) { + session->gpsdata.PRN[i] = p = atoi(field[3 + i * 5 + 0]); + session->gpsdata.azimuth[i] = atoi(field[3 + i * 5 + 1]); + session->gpsdata.elevation[i] = atoi(field[3 + i * 5 + 2]); + session->gpsdata.ss[i] = atof(field[3 + i * 5 + 3]); + if (field[3 + i * 5 + 4][0] == 'U') + session->gpsdata.used[u++] = p; + } + session->gpsdata.satellites_used = u; + gpsd_report(LOG_DATA, "PASHR,SAT: used=%d mask=%s\n", + session->gpsdata.satellites_used, gpsd_maskdump(mask)); + session->gpsdata.skyview_time = NAN; + mask |= SATELLITE_IS | USED_IS; + } + return mask; +} +#endif /* ASHTECH_ENABLE */ + +/************************************************************************** + * + * Entry points begin here + * + **************************************************************************/ + +/*@ -mayaliasunique @*/ +gps_mask_t nmea_parse(char *sentence, struct gps_device_t * session) +/* parse an NMEA sentence, unpack it into a session structure */ +{ + typedef gps_mask_t(*nmea_decoder) (int count, char *f[], + struct gps_device_t * session); + static struct + { + char *name; + int nf; /* minimum number of fields required to parse */ + nmea_decoder decoder; + } nmea_phrase[] = { + /*@ -nullassign @*/ + { + "PGRMC", 0, NULL}, /* ignore Garmin Sensor Config */ + { + "PGRME", 7, processPGRME}, { + "PGRMI", 0, NULL}, /* ignore Garmin Sensor Init */ + { + "PGRMO", 0, NULL}, /* ignore Garmin Sentence Enable */ + /* + * Basic sentences must come after the PG* ones, otherwise + * Garmins can get stuck in a loop that looks like this: + * + * 1. A Garmin GPS in NMEA mode is detected. + * + * 2. PGRMC is sent to reconfigure to Garmin binary mode. + * If successful, the GPS echoes the phrase. + * + * 3. nmea_parse() sees the echo as RMC because the talker ID is + * ignored, and fails to recognize the echo as PGRMC and ignore it. + * + * 4. The mode is changed back to NMEA, resulting in an infinite loop. + */ + { + "RMC", 8, processGPRMC}, { + "GGA", 13, processGPGGA}, { + "GLL", 7, processGPGLL}, { + "GSA", 17, processGPGSA}, { + "GSV", 0, processGPGSV}, { + "VTG", 0, NULL}, /* ignore Velocity Track made Good */ + { + "ZDA", 7, processGPZDA}, { + "GBS", 7, processGPGBS}, +#ifdef TNT_ENABLE + { + "PTNTHTM", 9, processTNTHTM}, +#endif /* TNT_ENABLE */ +#ifdef ASHTECH_ENABLE + { + "PASHR", 3, processPASHR}, /* general handler for Ashtech */ +#endif /* ASHTECH_ENABLE */ +#ifdef OCEANSERVER_ENABLE + { + "OHPR", 18, processOHPR}, +#endif /* OCEANSERVER_ENABLE */ + /*@ +nullassign @*/ + }; + + int count; + gps_mask_t retval = 0; + unsigned int i, thistag; + char *p, *s, *e; + volatile char *t; + + /* + * We've had reports that on the Garmin GPS-10 the device sometimes + * (1:1000 or so) sends garbage packets that have a valid checksum + * but are like 2 successive NMEA packets merged together in one + * with some fields lost. Usually these are much longer than the + * legal limit for NMEA, so we can cope by just tossing out overlong + * packets. This may be a generic bug of all Garmin chipsets. + */ + if (strlen(sentence) > NMEA_MAX) { + gpsd_report(LOG_WARN, "Overlong packet rejected.\n"); + return ONLINE_IS; + } + + /*@ -usedef @*//* splint 3.1.1 seems to have a bug here */ + /* make an editable copy of the sentence */ + strncpy((char *)session->driver.nmea.fieldcopy, sentence, NMEA_MAX); + /* discard the checksum part */ + for (p = (char *)session->driver.nmea.fieldcopy; + (*p != '*') && (*p >= ' ');) + ++p; + if (*p == '*') + *p++ = ','; /* otherwise we drop the last field */ + *p = '\0'; + e = p; + + /* split sentence copy on commas, filling the field array */ + count = 0; + t = p; /* end of sentence */ + p = (char *)session->driver.nmea.fieldcopy + 1; /* beginning of tag, 'G' not '$' */ + /* while there is a search string and we haven't run off the buffer... */ + while ((p != NULL) && (p <= t)) { + session->driver.nmea.field[count] = p; /* we have a field. record it */ + /*@ -compdef @*/ + if ((p = strchr(p, ',')) != NULL) { /* search for the next delimiter */ + *p = '\0'; /* replace it with a NUL */ + count++; /* bump the counters and continue */ + p++; + } + /*@ +compdef @*/ + } + + /* point remaining fields at empty string, just in case */ + for (i = (unsigned int)count; + i < + (unsigned)(sizeof(session->driver.nmea.field) / + sizeof(session->driver.nmea.field[0])); i++) + session->driver.nmea.field[i] = e; + + /* sentences handlers will tell us whren they have fractional time */ + session->driver.nmea.latch_frac_time = false; + + /* dispatch on field zero, the sentence tag */ + for (thistag = i = 0; + i < (unsigned)(sizeof(nmea_phrase) / sizeof(nmea_phrase[0])); ++i) { + s = session->driver.nmea.field[0]; + if (strlen(nmea_phrase[i].name) == 3) + s += 2; /* skip talker ID */ + if (strcmp(nmea_phrase[i].name, s) == 0) { + if (nmea_phrase[i].decoder != NULL + && (count >= nmea_phrase[i].nf)) { + retval = + (nmea_phrase[i].decoder) (count, + session->driver.nmea.field, + session); + strncpy(session->gpsdata.tag, nmea_phrase[i].name, MAXTAGLEN); + /* + * Must force this to be nz, as we're gong to rely on a zero + * value to mean "no previous tag" later. + */ + thistag = i + 1; + } else + retval = ONLINE_IS; /* unknown sentence */ + break; + } + } + + /* general handler for MKT3301 vendor specifics */ +#ifdef MKT3301_ENABLE + if (strncmp("PMTK", session->driver.nmea.field[0], 4) == 0) + retval = processMKT3301(count, session->driver.nmea.field, session); +#endif /* MKT3301_ENABLE */ + /*@ +usedef @*/ + + /* timestamp recording for fixes happens here */ + if ((retval & TIME_IS) != 0) { + /* + * WARNING: This assumes time is always field 0, and that field 0 + * is a timestamp whenever TIME_IS is set. + */ + session->newdata.time = + (double)mkgmtime(&session->driver.nmea.date) + + session->driver.nmea.subseconds; + gpsd_report(LOG_DATA, + "%s time (nearest sec) is %2f = %d-%d-%dT%d:%d%d\n", + session->driver.nmea.field[0], session->newdata.time, + 1900 + session->driver.nmea.date.tm_year, + session->driver.nmea.date.tm_mon + 1, + session->driver.nmea.date.tm_mday, + session->driver.nmea.date.tm_hour, + session->driver.nmea.date.tm_min, + session->driver.nmea.date.tm_sec); + } + + /* + * The end-of-cycle detector. This code depends on just one + * assumption: if a sentence with a timestamp occurs just before + * start of cycle, then it is always good to trigger a reort on + * that sentence in the future. For devices with a fixed cycle + * this should work perfectly, locking in detection after one + * cycle. Most split-cycle devices (Garmin 48, for example) will + * work fine. Problems will only arise if a a sentence that + * occurs just befiore timestamp increments also occurs in + * mid-cycle, as in the Garmin eXplorist 210; those might jitter. + */ + if (session->driver.nmea.latch_frac_time) { + gpsd_report(LOG_PROG, + "%s reporting cycle started on %.2f.\n", + session->driver.nmea.field[0], + session->driver.nmea.this_frac_time); + if (!GPS_TIME_EQUAL + (session->driver.nmea.this_frac_time, + session->driver.nmea.last_frac_time)) { + uint lasttag = session->driver.nmea.lasttag; + retval |= CLEAR_IS; + gpsd_report(LOG_PROG, + "%s starts a reporting cycle.\n", + session->driver.nmea.field[0]); + /* + * Have we seen a previously timestamped NMEA tag? + * If so, designate as end-of-cycle marker. + */ + if (lasttag > 0 + && (session->driver.nmea.cycle_enders & (1 << lasttag)) == + 0) { + session->driver.nmea.cycle_enders |= (1 << lasttag); + gpsd_report(LOG_PROG, + "tagged %s as a cycle ender.\n", + nmea_phrase[lasttag - 1].name); + } + } + /* here's where we check for end-of-cycle */ + if (session->driver.nmea.cycle_enders & (1 << thistag)) { + gpsd_report(LOG_PROG, + "%s ends a reporting cycle.\n", + session->driver.nmea.field[0]); + retval |= REPORT_IS; + } + session->driver.nmea.lasttag = thistag; + } + + /* we might have a reliable end-of-cycle */ + if (session->driver.nmea.cycle_enders != 0) + session->cycle_end_reliable = true; + + return retval; +} + +/*@ +mayaliasunique @*/ +#endif /* NMEA_ENABLE */ + +void nmea_add_checksum(char *sentence) +/* add NMEA checksum to a possibly *-terminated sentence */ +{ + unsigned char sum = '\0'; + char c, *p = sentence; + + if (*p == '$' || *p == '!') { + p++; + } else { + gpsd_report(LOG_ERROR, "Bad NMEA sentence: '%s'\n", sentence); + } + while (((c = *p) != '*') && (c != '\0')) { + sum ^= c; + p++; + } + *p++ = '*'; + (void)snprintf(p, 5, "%02X\r\n", (unsigned)sum); +} + +ssize_t nmea_write(struct gps_device_t *session, char *buf, size_t len UNUSED) +/* ship a command to the GPS, adding * and correct checksum */ +{ + (void)strlcpy(session->msgbuf, buf, sizeof(session->msgbuf)); + if (session->msgbuf[0] == '$') { + (void)strlcat(session->msgbuf, "*", sizeof(session->msgbuf)); + nmea_add_checksum(session->msgbuf); + } else + (void)strlcat(session->msgbuf, "\r\n", sizeof(session->msgbuf)); + session->msgbuflen = strlen(session->msgbuf); + return gpsd_write(session, session->msgbuf, session->msgbuflen); +} + +ssize_t nmea_send(struct gps_device_t * session, const char *fmt, ...) +{ + char buf[BUFSIZ]; + va_list ap; + + va_start(ap, fmt); + (void)vsnprintf(buf, sizeof(buf) - 5, fmt, ap); + va_end(ap); + return nmea_write(session, buf, strlen(buf)); +} diff --git a/driver_oncore.c b/driver_oncore.c new file mode 100644 index 0000000..bf25d51 --- /dev/null +++ b/driver_oncore.c @@ -0,0 +1,547 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include + +#include "gpsd.h" +#if defined(ONCORE_ENABLE) && defined(BINARY_ENABLE) + +#include "bits.h" + +/*@ +charint @*/ +static char enableEa[] = { 'E', 'a', 1 }; +static char enableBb[] = { 'B', 'b', 1 }; +static char getfirmware[] = { 'C', 'j' }; +static char enableEn[] = + { 'E', 'n', 1, 0, 100, 100, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +/*static char enableAt2[] = { 'A', 't', 2, };*/ +static unsigned char pollAs[] = + { 'A', 's', 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, + 0xff, 0xff, 0xff +}; +static unsigned char pollAt[] = { 'A', 't', 0xff }; +static unsigned char pollAy[] = { 'A', 'y', 0xff, 0xff, 0xff, 0xff }; +static char pollBo[] = { 'B', 'o', 0x01 }; + +/*@ -charint @*/ + +/* + * These routines are specific to this driver + */ + +static gps_mask_t oncore_parse_input(struct gps_device_t *); +static gps_mask_t oncore_dispatch(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t oncore_msg_navsol(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t oncore_msg_utc_offset(struct gps_device_t *, + unsigned char *, size_t); +static gps_mask_t oncore_msg_pps_delay(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t oncore_msg_svinfo(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t oncore_msg_time_raim(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t oncore_msg_firmware(struct gps_device_t *, unsigned char *, + size_t); + +/* + * These methods may be called elsewhere in gpsd + */ +static ssize_t oncore_control_send(struct gps_device_t *, char *, size_t); +static void oncore_event_hook(struct gps_device_t *, event_t); +static bool oncore_set_speed(struct gps_device_t *, speed_t, char, int); +static void oncore_set_mode(struct gps_device_t *, int); + +/* + * Decode the navigation solution message + */ +static gps_mask_t +oncore_msg_navsol(struct gps_device_t *session, unsigned char *buf, + size_t data_len) +{ + gps_mask_t mask; + unsigned char flags; + double lat, lon, alt; + float speed, track, dop; + unsigned int i, j, st, nsv, off; + int Bbused; + struct tm unpacked_date; + unsigned int nsec; + + if (data_len != 76) + return 0; + + mask = ONLINE_IS; + gpsd_report(LOG_IO, "oncore NAVSOL - navigation data\n"); + + flags = (unsigned char)getub(buf, 72); + + /*@ -predboolothers @*/ + if (flags & 0x20) { + session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_3D; + } else if (flags & 0x10) { + session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_2D; + } else { + gpsd_report(LOG_WARN, "oncore NAVSOL no fix - flags 0x%02x\n", flags); + session->newdata.mode = MODE_NO_FIX; + session->gpsdata.status = STATUS_NO_FIX; + } + mask |= MODE_IS; + /*@ +predboolothers @*/ + + /* Unless we have seen non-zero utc offset data, the time is GPS time + * and not UTC time. Do not use it. + */ + if (session->context->leap_seconds) { + unpacked_date.tm_mon = (int)getub(buf, 4) - 1; + unpacked_date.tm_mday = (int)getub(buf, 5); + unpacked_date.tm_year = (int)getbeuw(buf, 6) - 1900; + unpacked_date.tm_hour = (int)getub(buf, 8); + unpacked_date.tm_min = (int)getub(buf, 9); + unpacked_date.tm_sec = (int)getub(buf, 10); + nsec = (uint) getbeul(buf, 11); + + /*@ -unrecog */ + session->newdata.time = (double)timegm(&unpacked_date) + nsec * 1e-9; + /*@ +unrecog */ + mask |= TIME_IS; + gpsd_report(LOG_IO, + "oncore NAVSOL - time: %04d-%02d-%02d %02d:%02d:%02d.%09d\n", + unpacked_date.tm_year + 1900, unpacked_date.tm_mon + 1, + unpacked_date.tm_mday, unpacked_date.tm_hour, + unpacked_date.tm_min, unpacked_date.tm_sec, nsec); + } + + /*@-type@*/ + lat = getbesl(buf, 15) / 3600000.0f; + lon = getbesl(buf, 19) / 3600000.0f; + alt = getbesl(buf, 23) / 100.0f; + speed = getbeuw(buf, 31) / 100.0f; + track = getbeuw(buf, 33) / 10.0f; + dop = getbeuw(buf, 35) / 10.0f; + /*@+type@*/ + + gpsd_report(LOG_IO, + "oncore NAVSOL - %lf %lf %.2lfm-%.2lfm | %.2fm/s %.1fdeg dop=%.1f\n", + lat, lon, alt, wgs84_separation(lat, lon), speed, track, + (float)dop); + + session->newdata.latitude = lat; + session->newdata.longitude = lon; + session->gpsdata.separation = + wgs84_separation(session->newdata.latitude, + session->newdata.longitude); + session->newdata.altitude = alt - session->gpsdata.separation; + session->newdata.speed = speed; + session->newdata.track = track; + + mask |= LATLON_IS | ALTITUDE_IS | SPEED_IS | TRACK_IS; + + gpsd_zero_satellites(&session->gpsdata); + /* Merge the satellite information from the Bb message. */ + Bbused = 0; + nsv = 0; + for (i = st = 0; i < 8; i++) { + int sv, mode, sn, status; + + off = 40 + 4 * i; + sv = (int)getub(buf, off); + mode = (int)getub(buf, off + 1); + sn = (int)getub(buf, off + 2); + status = (int)getub(buf, off + 3); + + gpsd_report(LOG_IO, "%2d %2d %2d %3d %02x\n", i, sv, mode, sn, + status); + + if (sn) { + session->gpsdata.PRN[st] = sv; + session->gpsdata.ss[st] = (double)sn; + for (j = 0; (int)j < session->driver.oncore.visible; j++) + if (session->driver.oncore.PRN[j] == sv) { + session->gpsdata.elevation[st] = + session->driver.oncore.elevation[j]; + session->gpsdata.azimuth[st] = + session->driver.oncore.azimuth[j]; + Bbused |= 1 << j; + break; + } + st++; + if (status & 0x80) + session->gpsdata.used[nsv++] = sv; + } + } + for (j = 0; (int)j < session->driver.oncore.visible; j++) + /*@ -boolops @*/ + if (!(Bbused & (1 << j))) { + session->gpsdata.PRN[st] = session->driver.oncore.PRN[j]; + session->gpsdata.elevation[st] = + session->driver.oncore.elevation[j]; + session->gpsdata.azimuth[st] = session->driver.oncore.azimuth[j]; + st++; + } + /*@ +boolops @*/ + session->gpsdata.skyview_time = session->newdata.time; + session->gpsdata.satellites_used = (int)nsv; + session->gpsdata.satellites_visible = (int)st; + + mask |= SATELLITE_IS | USED_IS; + + /* Some messages can only be polled. As they are not so + * important, would be enough to poll e.g. one message per cycle. + */ + (void)oncore_control_send(session, (char *)pollAs, sizeof(pollAs)); + (void)oncore_control_send(session, (char *)pollAt, sizeof(pollAt)); + (void)oncore_control_send(session, (char *)pollAy, sizeof(pollAy)); + (void)oncore_control_send(session, pollBo, sizeof(pollBo)); + + gpsd_report(LOG_DATA, + "NAVSOL: time=%.2f lat=%.2f lon=%.2f alt=%.2f speed=%.2f track=%.2f mode=%d status=%d visible=%d used=%d mask=%s\n", + session->newdata.time, session->newdata.latitude, + session->newdata.longitude, session->newdata.altitude, + session->newdata.speed, session->newdata.track, + session->newdata.mode, session->gpsdata.status, + session->gpsdata.satellites_used, + session->gpsdata.satellites_visible, gpsd_maskdump(mask)); + return mask; +} + +/** + * GPS Leap Seconds = UTC offset + */ +static gps_mask_t +oncore_msg_utc_offset(struct gps_device_t *session, unsigned char *buf, + size_t data_len) +{ + int utc_offset; + + if (data_len != 8) + return 0; + + gpsd_report(LOG_IO, "oncore UTCTIME - leap seconds\n"); + utc_offset = (int)getub(buf, 4); + if (utc_offset == 0) + return 0; /* that part of almanac not received yet */ + + session->context->leap_seconds = utc_offset; + session->context->valid |= LEAP_SECOND_VALID; + return 0; /* no flag for leap seconds update */ +} + +/** + * PPS delay + */ +static gps_mask_t +oncore_msg_pps_delay(struct gps_device_t *session, unsigned char *buf, + size_t data_len) +{ + double pps_delay; + + if (data_len != 11) + return 0; + + gpsd_report(LOG_IO, "oncore PPS delay\n"); + pps_delay = getbesl(buf, 4) / 1000000.0; + + session->driver.oncore.pps_delay = pps_delay; + return 0; +} + +/** + * GPS Satellite Info + */ +static gps_mask_t +oncore_msg_svinfo(struct gps_device_t *session, unsigned char *buf, + size_t data_len) +{ + unsigned int i, nchan; + unsigned int off; + int sv, el, az; + int j; + + if (data_len != 92) + return 0; + + gpsd_report(LOG_IO, "oncore SVINFO - satellite data\n"); + nchan = (unsigned int)getub(buf, 4); + gpsd_report(LOG_IO, "oncore SVINFO - %d satellites:\n", nchan); + /* Then we clamp the value to not read outside the table. */ + if (nchan > 12) + nchan = 12; + session->driver.oncore.visible = (int)nchan; + for (i = 0; i < nchan; i++) { + /* get info for one channel/satellite */ + off = 5 + 7 * i; + + sv = (int)getub(buf, off); + el = (int)getub(buf, off + 3); + az = (int)getbeuw(buf, off + 4); + + gpsd_report(LOG_IO, "%2d %2d %2d %3d\n", i, sv, el, az); + + /* Store for use when Ea messages come. */ + session->driver.oncore.PRN[i] = sv; + session->driver.oncore.elevation[i] = el; + session->driver.oncore.azimuth[i] = az; + /* If it has an entry in the satellite list, update it! */ + for (j = 0; j < session->gpsdata.satellites_visible; j++) + if (session->gpsdata.PRN[j] == sv) { + session->gpsdata.elevation[j] = el; + session->gpsdata.azimuth[j] = az; + } + } + + gpsd_report(LOG_DATA, "SVINFO: mask={SATELLITE}\n"); + return SATELLITE_IS; +} + +/** + * GPS Time RAIM + */ +static gps_mask_t +oncore_msg_time_raim(struct gps_device_t *session UNUSED, + unsigned char *buf UNUSED, size_t data_len UNUSED) +{ + return 0; +} + +/** + * GPS Firmware + */ +static gps_mask_t +oncore_msg_firmware(struct gps_device_t *session UNUSED, + unsigned char *buf UNUSED, size_t data_len UNUSED) +{ + return 0; +} + +#define ONCTYPE(id2,id3) ((((unsigned int)id2)<<8)|(id3)) + +/** + * Parse the data from the device + */ +/*@ +charint @*/ +gps_mask_t oncore_dispatch(struct gps_device_t * session, unsigned char *buf, + size_t len) +{ + unsigned int type; + + if (len == 0) + return 0; + + type = ONCTYPE(buf[2], buf[3]); + + /* we may need to dump the raw packet */ + gpsd_report(LOG_RAW, "raw oncore packet type 0x%04x length %zd: %s\n", + type, len, gpsd_hexdump_wrapper(buf, len, LOG_WARN)); + + (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), + "MOT-%c%c", type >> 8, type & 0xff); + + session->cycle_end_reliable = true; + + switch (type) { + case ONCTYPE('B', 'b'): + return oncore_msg_svinfo(session, buf, len); + case ONCTYPE('E', 'a'): + return oncore_msg_navsol(session, buf, len) | (CLEAR_IS | REPORT_IS); + case ONCTYPE('E', 'n'): + return oncore_msg_time_raim(session, buf, len); + case ONCTYPE('C', 'j'): + return oncore_msg_firmware(session, buf, len); + case ONCTYPE('B', 'o'): + return oncore_msg_utc_offset(session, buf, len); + case ONCTYPE('A', 's'): + return 0; /* position hold mode */ + case ONCTYPE('A', 't'): + return 0; /* position hold position */ + case ONCTYPE('A', 'y'): + return oncore_msg_pps_delay(session, buf, len); + + default: + /* FIX-ME: This gets noisy in a hurry. Change once your driver works */ + gpsd_report(LOG_WARN, "unknown packet id @@%c%c length %zd: %s\n", + type >> 8, type & 0xff, len, gpsd_hexdump_wrapper(buf, + len, + LOG_WARN)); + return 0; + } +} + +/*@ -charint @*/ + +/********************************************************** + * + * Externally called routines below here + * + **********************************************************/ + +/** + * Write data to the device, doing any required padding or checksumming + */ +/*@ +charint -usedef -compdef @*/ +static ssize_t oncore_control_send(struct gps_device_t *session, + char *msg, size_t msglen) +{ + size_t i; + char checksum = 0; + + session->msgbuf[0] = '@'; + session->msgbuf[1] = '@'; + for (i = 0; i < msglen; i++) { + checksum ^= session->msgbuf[i + 2] = msg[i]; + } + session->msgbuf[msglen + 2] = checksum; + session->msgbuf[msglen + 3] = '\r'; + session->msgbuf[msglen + 4] = '\n'; + session->msgbuflen = msglen + 5; + + gpsd_report(LOG_IO, "writing oncore control type %c%c:%s\n", + msg[0], msg[1], gpsd_hexdump_wrapper(session->msgbuf, + session->msgbuflen, + LOG_IO)); + return gpsd_write(session, session->msgbuf, session->msgbuflen); +} + +/*@ -charint +usedef +compdef @*/ + +static void oncore_event_hook(struct gps_device_t *session, event_t event) +{ + if (event == event_wakeup) + (void)oncore_control_send(session, getfirmware, sizeof(getfirmware)); + + /* + * FIX-ME: It might not be necessary to call this on reactivate. + * Experiment to see if the holds its settings through a close. + */ + if (event == event_identified || event == event_reactivate) { + (void)oncore_control_send(session, enableEa, sizeof(enableEa)); + (void)oncore_control_send(session, enableBb, sizeof(enableBb)); + (void)oncore_control_send(session, enableEn, sizeof(enableEn)); + /*(void)oncore_control_send(session,enableAt2,sizeof(enableAt2)); */ + /*(void)oncore_control_send(session,pollAs,sizeof(pollAs)); */ + (void)oncore_control_send(session, pollBo, sizeof(pollBo)); + } +} + +#ifdef NTPSHM_ENABLE +static double oncore_ntp_offset(struct gps_device_t *session) +{ + /* + * Only one sentence (NAVSOL) ships time. 0.175 seems best at + * 9600 for UT+, not sure what the fudge should be at other baud + * rates or for other models. + */ + return 0.175; +} +#endif /* NTPSHM_ENABLE */ + +#ifdef ALLOW_RECONFIGURE +static bool oncore_set_speed(struct gps_device_t *session UNUSED, + speed_t speed UNUSED, + char parity UNUSED, int stopbits UNUSED) +{ + /* + * Set port operating mode, speed, parity, stopbits etc. here. + * Note: parity is passed as 'N'/'E'/'O', but you should program + * defensively and allow 0/1/2 as well. + */ + return false; +} + +/* + * Switch between NMEA and binary mode, if supported + */ +static void oncore_set_mode(struct gps_device_t *session, int mode) +{ + if (mode == MODE_NMEA) { + /* send the mode switch control string */ + /* oncore_to_nmea(session->gpsdata.gps_fd,session->gpsdata.baudrate); */ + session->gpsdata.dev.driver_mode = MODE_NMEA; + /* + * Anticipatory switching works only when the packet getter is the + * generic one and it recognizes packets of the type this driver + * is expecting. This should be the normal case. + */ + (void)gpsd_switch_driver(session, "Generic NMEA"); + } else { + session->back_to_nmea = false; + session->gpsdata.dev.driver_mode = MODE_BINARY; + } +} +#endif /* ALLOW_RECONFIGURE */ + +static gps_mask_t oncore_parse_input(struct gps_device_t *session) +{ + gps_mask_t st; + + if (session->packet.type == ONCORE_PACKET) { + st = oncore_dispatch(session, session->packet.outbuffer, + session->packet.outbuflen); + session->gpsdata.dev.driver_mode = MODE_BINARY; + return st; +#ifdef NMEA_ENABLE + } else if (session->packet.type == NMEA_PACKET) { + st = nmea_parse((char *)session->packet.outbuffer, session); + session->gpsdata.dev.driver_mode = MODE_NMEA; + return st; +#endif /* NMEA_ENABLE */ + } else + return 0; +} + +/* This is everything we export */ +/* *INDENT-OFF* */ +const struct gps_type_t oncore_binary = { + /* Full name of type */ + .type_name = "oncore binary", + /* associated lexer packet type */ + .packet_type = ONCORE_PACKET, + /* Response string that identifies device (not active) */ + .trigger = NULL, + /* Number of satellite channels supported by the device */ + .channels = 12, + /* Startup-time device detector */ + .probe_detect = NULL, + /* Wakeup to be done before each baud hunt */ + .get_packet = generic_get, + /* Parse message packets */ + .parse_packet = oncore_parse_input, + /* RTCM handler (using default routine) */ + .rtcm_writer = pass_rtcm, + /* Fire on various lifetime events */ + .event_hook = oncore_event_hook, +#ifdef ALLOW_RECONFIGURE + /* Speed (baudrate) switch */ + .speed_switcher = oncore_set_speed, + /* Switch to NMEA mode */ + .mode_switcher = oncore_set_mode, + /* Message delivery rate switcher (not active) */ + .rate_switcher = NULL, + /* Minimum cycle time of the device */ + .min_cycle = 1, + /* Undo actions at configure_event time */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + /* Control string sender - should provide checksum and headers/trailer */ + .control_send = oncore_control_send, +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = oncore_ntp_offset, +#endif /* NTPSHM_ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* defined(ONCORE_ENABLE) && defined(BINARY_ENABLE) */ diff --git a/driver_proto.c b/driver_proto.c new file mode 100644 index 0000000..c13d362 --- /dev/null +++ b/driver_proto.c @@ -0,0 +1,560 @@ +/* + * A prototype driver. Doesn't run, doesn't even compile. + * + * For new driver authors: replace "_PROTO_" and "_proto_" with the name of + * your new driver. That will give you a skeleton with all the required + * functions defined. + * + * Once that is done, you will likely have to define a large number of + * flags and masks. From there, you will be able to start extracting + * useful quantities. There are roughed-in decoders for the navigation + * solution, satellite status and gps-utc offset. These are the 3 key + * messages that gpsd needs. Some protocols transmit error estimates + * separately from the navigation solution; if developing a driver for + * such a protocol you will need to add a decoder function for that + * message. + * + * For anyone hacking this driver skeleton: "_PROTO_" and "_proto_" are now + * reserved tokens. We suggest that they only ever be used as prefixes, + * but if they are used infix, they must be used in a way that allows a + * driver author to find-and-replace to create a unique namespace for + * driver functions. + * + * If using vi, ":%s/_PROTO_/MYDRIVER/g" and ":%s/_proto_/mydriver/g" + * should produce a source file that comes very close to being useful. + * You will also need to add hooks for your new driver to: + * Makefile.am + * drivers.c + * gpsd.h-tail + * libgpsd_core.c + * packet.c + * packet_states.h + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#include +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include + +#include "gpsd.h" +#if defined(_PROTO__ENABLE) && defined(BINARY_ENABLE) + +#include "bits.h" + +static gps_mask_t _proto__parse_input(struct gps_device_t *); +static gps_mask_t _proto__dispatch(struct gps_device_t *, unsigned char *, size_t ); +static gps_mask_t _proto__msg_navsol(struct gps_device_t *, unsigned char *, size_t ); +static gps_mask_t _proto__msg_utctime(struct gps_device_t *, unsigned char *, size_t ); +static gps_mask_t _proto__msg_svinfo(struct gps_device_t *, unsigned char *, size_t ); +static gps_mask_t _proto__msg_raw(struct gps_device_t *, unsigned char *, size_t ); + +/* + * These methods may be called elsewhere in gpsd + */ +static ssize_t _proto__control_send(struct gps_device_t *, char *, size_t); +static bool _proto__probe_detect(struct gps_device_t *); +static void _proto__event_hook(struct gps_device_t *, event_t); +static bool _proto__set_speed(struct gps_device_t *, speed_t, char, int); +static void _proto__set_mode(struct gps_device_t *, int); + +/* + * Decode the navigation solution message + */ +static gps_mask_t +_proto__msg_navsol(struct gps_device_t *session, unsigned char *buf, size_t data_len) +{ + gps_mask_t mask; + int flags; + double Px, Py, Pz, Vx, Vy, Vz; + + if (data_len != _PROTO__NAVSOL_MSG_LEN) + return 0; + + gpsd_report(LOG_IO, "_proto_ NAVSOL - navigation data\n"); + /* if this protocol has a way to test message validity, use it */ + flags = GET_FLAGS(); + if ((flags & _PROTO__SOLUTION_VALID) == 0) + return 0; + + mask = ONLINE_IS; + + /* extract ECEF navigation solution here */ + /* or extract the local tangential plane (ENU) solution */ + [Px, Py, Pz, Vx, Vy, Vz] = GET_ECEF_FIX(); + ecef_to_wgs84fix(&session->newdata, &session->separation, + Px, Py, Pz, Vx, Vy, Vz); + mask |= LATLON_IS | ALTITUDE_IS | SPEED_IS | TRACK_IS | CLIMB_IS ; + + session->newdata.epx = GET_LONGITUDE_ERROR(); + session->newdata.epy = GET_LATITUDE_ERROR(); + session->newdata.eps = GET_SPEED_ERROR(); + session->gpsdata.satellites_used = GET_SATELLITES_USED(); + /* + * Do *not* clear DOPs in a navigation solution message; + * instead, opportunistically pick up whatever it gives + * us and replace whatever values we computed from the + * visibility matrix for he last skyview. The reason to trust + * the chip returns over what we compute is that some + * chips have internal deweighting albums to throw out sats + * that increase DOP. + */ + session->gpsdata.dop.hdop = GET_HDOP(); + session->gpsdata.dop.vdop = GET_VDOP(); + /* other DOP if available */ + mask |= DOP_IS; + + session->newdata.mode = GET_FIX_MODE(); + session->gpsdata.status = GET_FIX_STATUS(); + + /* + * Mix in CLEAR_IS to clue the daemon in about when to clear fix + * information. Mix in REPORT_IS when the sentence is reliably + * the last in a reporting cycle. + */ + mask |= MODE_IS | STATUS_IS | REPORT_IS; + + /* + * At the end of each packet-cracking function, report at LOG_DATA level + * the fields it potentially set and the transfer mask. Doing this + * makes it relatively easy to track down data-management problems. + */ + gpsd_report(LOG_DATA, "NAVSOL: time=%.2f, lat=%.2f lon=%.2f alt=%.2f mode=%d status=%d mask=%s\n", + session->newdata.time, + session->newdata.latitude, + session->newdata.longitude, + session->newdata.altitude, + session->newdata.mode, + session->gpsdata.status, + gpsd_maskdump(mask)); + + return mask; +} + +/** + * GPS Leap Seconds + */ +static gps_mask_t +_proto__msg_utctime(struct gps_device_t *session, unsigned char *buf, size_t data_len) +{ + double t; + + if (data_len != UTCTIME_MSG_LEN) + return 0; + + gpsd_report(LOG_IO, "_proto_ UTCTIME - navigation data\n"); + /* if this protocol has a way to test message validity, use it */ + flags = GET_FLAGS(); + if ((flags & _PROTO__TIME_VALID) == 0) + return 0; + + tow = GET_MS_TIMEOFWEEK(); + gps_week = GET_WEEKNUMBER(); + session->context->gps_week = gps_week; + session->context->leap_seconds = GET_GPS_LEAPSECONDS(); + session->context->gps_tow = tow / 1000.0; + + t = gpstime_to_unix(gps_week, session->context->gps_tow) + - session->context->leap_seconds; + session->newdata.time = t; + + return TIME_IS | ONLINE_IS; +} + +/** + * GPS Satellite Info + */ +static gps_mask_t +_proto__msg_svinfo(struct gps_device_t *session, unsigned char *buf, size_t data_len) +{ + unsigned char i, st, nchan, nsv; + unsigned int tow; + + if (data_len != SVINFO_MSG_LEN ) + return 0; + + gpsd_report(LOG_IO, "_proto_ SVINFO - navigation data\n"); + /* if this protocol has a way to test message validity, use it */ + flags = GET_FLAGS(); + if ((flags & _PROTO__SVINFO_VALID) == 0) + return 0; + + /* + * some protocols have a variable length message listing only visible + * satellites, even if there are less than the number of channels. others + * have a fixed length message and send empty records for idle channels + * that are not tracking or searching. whatever the case, nchan should + * be set to the number of satellites which might be visible. + */ + nchan = GET_NUMBER_OF_CHANNELS(); + if ((nchan < 1) || (nchan > MAXCHANNELS)) { + gpsd_report(LOG_INF, "too many channels reported\n"); + return 0; + } + gpsd_zero_satellites(&session->gpsdata); + nsv = 0; /* number of actually used satellites */ + for (i = st = 0; i < nchan; i++) { + /* get info for one channel/satellite */ + int off = GET_CHANNEL_STATUS(i); + + session->gpsdata.PRN[i] = PRN_THIS_CHANNEL_IS_TRACKING(i); + session->gpsdata.ss[i] = (float)SIGNAL_STRENGTH_FOR_CHANNEL(i); + session->gpsdata.elevation[i] = SV_ELEVATION_FOR_CHANNEL(i); + session->gpsdata.azimuth[i] = SV_AZIMUTH_FOR_CHANNEL(i); + + if (CHANNEL_USED_IN_SOLUTION(i)) + session->gpsdata.used[nsv++] = session->gpsdata.PRN[i]; + + if(session->gpsdata.PRN[i]) + st++; + } + /* if the satellite-info setence gives you UTC time, use it */ + session->gpsdata.skyview_time = NaN; + session->gpsdata.satellites_used = nsv; + session->gpsdata.satellites_visible = st; + gpsd_report(LOG_DATA, + "SVINFO: visible=%d used=%d mask={SATELLITE|USED}\n", + session->gpsdata.satellites_visible, + session->gpsdata.satellites_used); + return SATELLITE_IS | USED_IS; +} + +/** + * Raw measurements + */ +static gps_mask_t +_proto__msg_raw(struct gps_device_t *session, unsigned char *buf, size_t data_len) +{ + unsigned char i, st, nchan, nsv; + unsigned int tow; + + if (data_len != RAW_MSG_LEN ) + return 0; + + gpsd_report(LOG_IO, "_proto_ RAW - raw measurements\n"); + /* if this protocol has a way to test message validity, use it */ + flags = GET_FLAGS(); + if ((flags & _PROTO__SVINFO_VALID) == 0) + return 0; + + /* + * not all chipsets emit the same information. some of these observables + * can be easily converted into others. these are suggestions for the + * quantities you may wish to try extract. chipset documentation may say + * something like "this message contains information required to generate + * a RINEX file." assign NAN for unavailable data. + */ + nchan = GET_NUMBER_OF_CHANNELS(); + if ((nchan < 1) || (nchan > MAXCHANNELS)) { + gpsd_report(LOG_INF, "too many channels reported\n"); + return 0; + } + + for (i = 0; i < n; i++){ + session->gpsdata.PRN[i] = GET_PRN(); + session->gpsdata.ss[i] = GET_SIGNAL() + session->gpsdata.raw.satstat[i] = GET_FLAGS(); + session->gpsdata.raw.pseudorange[i] = GET_PSEUDORANGE(); + session->gpsdata.raw.doppler[i] = GET_DOPPLER(); + session->gpsdata.raw.carrierphase[i] = GET_CARRIER_PHASE(); + session->gpsdata.raw.mtime[i] = GET_MEASUREMENT_TIME(); + session->gpsdata.raw.codephase[i] = GET_CODE_PHASE(); + session->gpsdata.raw.deltarange[i] = GET_DELTA_RANGE(); + } + return RAW_IS; +} + +/** + * Parse the data from the device + */ +/*@ +charint @*/ +gps_mask_t _proto__dispatch(struct gps_device_t *session, unsigned char *buf, size_t len) +{ + size_t i; + int type, used, visible, retmask = 0; + + if (len == 0) + return 0; + + /* + * Set this if the driver reliably signals end of cycle. + * The core library zeroes it just before it calls each driver's + * packet analyzer. + */ + session->cycle_end_reliable = true; + if (msgid == MY_START_OF_CYCLE) + retmask |= CLEAR_IS; + else if (msgid == MY_END_OF_CYCLE) + retmask |= REPORT_IS; + + type = GET_MESSAGE_TYPE(); + + /* we may need to dump the raw packet */ + gpsd_report(LOG_RAW, "raw _proto_ packet type 0x%02x length %d: %s\n", + type, len, gpsd_hexdump_wrapper(buf, len, LOG_WARN)); + + /* + * The tag field is only 8 bytes; be careful you do not overflow. + * Using an abbreviation (eg. "italk" -> "itk") may be useful. + */ + (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), + "_PROTO_%02x", type); + + switch (type) + { + /* Deliver message to specific decoder based on message type */ + + default: + /* This gets noisy in a hurry. Change once your driver works */ + gpsd_report(LOG_WARN, "unknown packet id %d length %d: %s\n", + type, len, gpsd_hexdump_wrapper(buf, len, LOG_WARN)); + return 0; + } +} +/*@ -charint @*/ + +/********************************************************** + * + * Externally called routines below here + * + **********************************************************/ + +static bool _proto__probe_detect(struct gps_device_t *session) +{ + /* + * This method is used to elicit a positively identifying + * response from a candidate device. Some drivers may use + * this to test for the presence of a certain kernel module. + */ + int test, satisfied; + + /* Your testing code here */ + test=satisfied=0; + if (test==satisfied) + return true; + return false; +} + +#ifdef ALLOW_CONTROLSEND +/** + * Write data to the device, doing any required padding or checksumming + */ +/*@ +charint -usedef -compdef @*/ +static ssize_t _proto__control_send(struct gps_device_t *session, + char *msg, size_t msglen) +{ + bool ok; + + /* CONSTRUCT THE MESSAGE */ + + /* + * This copy to a public assembly buffer + * enables gpsmon to snoop the control message + * after it has been sent. + */ + session->msgbuflen = msglen; + (void)memcpy(session->msgbuf, msg, msglen); + + /* we may need to dump the message */ + return gpsd_write(session, session->msgbuf, session->msgbuflen); + gpsd_report(LOG_IO, "writing _proto_ control type %02x:%s\n", + msg[0], gpsd_hexdump_wrapper(session->msgbuf, session->msgbuflen, LOG_IO)); + return gpsd_write(session, session->msgbuf, session->msgbuflen); +} +/*@ -charint +usedef +compdef @*/ +#endif /* ALLOW_CONTROLSEND */ + +#ifdef ALLOW_RECONFIGURE +static void _proto__event_hook(struct gps_device_t *session, event_t event) +{ + if (event == event_wakeup) { + /* + * Code to make the device ready to communicate. This is + * run every time we are about to try a different baud + * rate in the autobaud sequence. Only needed if the + * device is in some kind of sleeping state. + */ + } + if (event == event_identified) { + /* + * Fires when the first full packet is recognized from a + * previously unidentified device. The session packet counter + * is zeroed. If your device has a default cycle time other + * than 1 second, set session->device->gpsdata.cycle here. If + * possible, get the software version and store it in + * session->subtype. + */ + } + if (event == event_configure) { + /* + * Change sentence mix and set reporting modes as needed. + * Called immediately after event_identified fires, then just + * after every packet received thereafter, but you probably + * only want to take actions on the first few packets after + * the session packet counter has been zeroed, + * + * Remember that session->packet.counter is available when you + * write this hook; you can use this fact to interleave configuration + * sends with the first few packet reads, which is useful for + * devices with small receive buffers. + */ + } else if (event == event_driver_switch) { + /* + * Fires when the driver on a device is changed *after* it + * has been identified. + */ + } else if (event == event_deactivate) { + /* + * Fires when the device is deactivated. Usr this to revert + * whatever was done at event_identify and event_configure + * time. + */ + } else if (event == event_reactivate) { + /* + * Fires when a device is reactivated after having been closed. + * Use this hook for re-establishing device settings that + * it doesn't hold through closes. + */ + } +} + +/* + * This is the entry point to the driver. When the packet sniffer recognizes + * a packet for this driver, it calls this method which passes the packet to + * the binary processor or the nmea processor, depending on the session type. + */ +static gps_mask_t _proto__parse_input(struct gps_device_t *session) +{ + gps_mask_t st; + + if (session->packet.type == _PROTO__PACKET) { + st = _proto__dispatch(session, session->packet.outbuffer, session->packet.outbuflen); + session->gpsdata.driver_mode = MODE_BINARY; + return st; +#ifdef NMEA_ENABLE + } else if (session->packet.type == NMEA_PACKET) { + st = nmea_parse((char *)session->packet.outbuffer, session); + session->gpsdata.driver_mode = MODE_NMEA; + return st; +#endif /* NMEA_ENABLE */ + } else + return 0; +} + +static bool _proto__set_speed(struct gps_device_t *session, + speed_t speed, char parity, int stopbits) +{ + /* + * Set port operating mode, speed, parity, stopbits etc. here. + * Note: parity is passed as 'N'/'E'/'O', but you should program + * defensively and allow 0/1/2 as well. + */ +} + +/* + * Switch between NMEA and binary mode, if supported + */ +static void _proto__set_mode(struct gps_device_t *session, int mode) +{ + if (mode == MODE_NMEA) { + // _proto__to_nmea(session->gpsdata.gps_fd,session->gpsdata.baudrate); /* send the mode switch control string */ + session->gpsdata.driver_mode = MODE_NMEA; + /* + * Anticipatory switching works only when the packet getter is the + * generic one and it recognizes packets of the type this driver + * is expecting. This should be the normal case. + */ + (void)gpsd_switch_driver(session, "Generic NMEA"); + } else { + session->back_to_nmea = false; + session->gpsdata.driver_mode = MODE_BINARY; + } +} +#endif /* ALLOW_RECONFIGURE */ + +#ifdef NTPSHM_ENABLE +static double _proto_ntp_offset(struct gps_device_t *session) +{ + /* + * If NTP notification is enabled, the GPS will occasionally NTP + * its notion of the time. This will lag behind actual time by + * some amount which has to be determined by observation vs. (say + * WWVB radio broadcasts) and, furthermore, may differ by baud + * rate. This method is for computing the NTP fudge factor. If + * it's absent, an offset of 0.0 will be assumed, effectively + * falling back on what's in ntp.conf. When it returns NAN, + * nothing will be sent to NTP. + */ + return MAGIC_CONSTANT; +} +#endif /* NTPSHM_ENABLE */ + +static void _proto__wrapup(struct gps_device_t *session) +{ +} + +/* The methods in this code take parameters and have */ +/* return values that conform to the requirements AT */ +/* THE TIME THE CODE WAS WRITTEN. */ +/* */ +/* These values may well have changed by the time */ +/* you read this and methods could have been added */ +/* or deleted. Unused methods can be set to NULL. */ +/* */ +/* The latest version can be found by inspecting */ +/* the contents of struct gps_type_t in gpsd.h. */ +/* */ +/* This always contains the correct definitions that */ +/* any driver must use to compile. */ + +/* This is everything we export */ +/* *INDENT-OFF* */ +const struct gps_type_t _proto__binary = { + /* Full name of type */ + .type_name = "_proto_ binary", + /* Associated lexer packet type */ + .packet_type = _PROTO__PACKET, + /* Response string that identifies device (not active) */ + .trigger = NULL, + /* Number of satellite channels supported by the device */ + .channels = 12, + /* Startup-time device detector */ + .probe_detect = _proto__probe_detect, + /* Packet getter (using default routine) */ + .get_packet = generic_get, + /* Parse message packets */ + .parse_packet = _proto__parse_input, + /* RTCM handler (using default routine) */ + .rtcm_writer = pass_rtcm, + /* fire on various lifetime events */ + .event_hook = _proto__event_hook, +#ifdef ALLOW_RECONFIGURE + /* Speed (baudrate) switch */ + .speed_switcher = _proto__set_speed, + /* Switch to NMEA mode */ + .mode_switcher = _proto__set_mode, + /* Message delivery rate switcher (not active) */ + .rate_switcher = NULL, + /* Minimum cycle time of the device */ + .min_cycle = 1, +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + /* Control string sender - should provide checksum and headers/trailer */ + .control_send = _proto__control_send, +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = _proto_ntp_offset, +#endif /* NTPSHM_ENABLE */ +/* *INDENT-ON* */ +}; +#endif /* defined(_PROTO__ENABLE) && defined(BINARY_ENABLE) */ + diff --git a/driver_rtcm2.c b/driver_rtcm2.c new file mode 100644 index 0000000..a8941df --- /dev/null +++ b/driver_rtcm2.c @@ -0,0 +1,356 @@ +/***************************************************************************** + +This is a decoder for RTCM-104 2.x, an obscure and complicated serial +protocol used for broadcasting pseudorange corrections from +differential-GPS reference stations. The applicable +standard is + +RTCM RECOMMENDED STANDARDS FOR DIFFERENTIAL NAVSTAR GPS SERVICE, +RTCM PAPER 194-93/SC 104-STD + +Ordering instructions are accessible from +under "Publications". This describes version 2.1 of the RTCM specification. +RTCM-104 was later incrementally revised up to a 2.3 level before being +completely redesigned as level 3.0. + +Also applicable is ITU-R M.823: "Technical characteristics of +differential transmissions for global navigation satellite systems +from maritime radio beacons in the frequency band 283.5 - 315 kHz in +region 1 and 285 - 325 kHz in regions 2 & 3." + +The RTCM 2.x protocol uses as a transport layer the GPS satellite downlink +protocol described in IS-GPS-200, the Navstar GPS Interface +Specification. This code relies on the lower-level packet-assembly +code for that protocol in isgps.c. + +The lower layer's job is done when it has assembled a message of up to +33 words of clean parity-checked data. At this point this upper layer +takes over. struct rtcm2_msg_t is overlaid on the buffer and the bitfields +are used to extract pieces of it. Those pieces are copied and (where +necessary) reassembled into a struct rtcm2_t. + +This code and the contents of isgps.c are evolved from code by Wolfgang +Rupprecht. Wolfgang's decoder was loosely based on one written by +John Sager in 1999 (in particular the dump function emits a close +descendant of Sager's dump format). Here are John Sager's original +notes: + +The RTCM decoder prints a legible representation of the input data. +The RTCM SC-104 specification is copyrighted, so I cannot +quote it - in fact, I have never read it! Most of the information +used to develop the decoder came from publication ITU-R M.823. +This is a specification of the data transmitted from LF DGPS +beacons in the 300kHz band. M.823 contains most of those parts of +RTCM SC-104 directly relevant to the air interface (there +are one or two annoying and vital omissions!). Information +about the serial interface format was gleaned from studying +the output of a beacon receiver test program made available on +Starlink's website. + +This file is Copyright (c) 2010 by the GPSD project +BSD terms apply: see the file COPYING in the distribution root for details. + +*****************************************************************************/ + +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include /* for round() */ + +#include "gpsd.h" +#include "driver_rtcm2.h" + +#ifdef RTCM104V2_ENABLE + +#define PREAMBLE_PATTERN 0x66 + +static unsigned int tx_speed[] = { 25, 50, 100, 110, 150, 200, 250, 300 }; + +#define DIMENSION(a) (unsigned)(sizeof(a)/sizeof(a[0])) + +void rtcm2_unpack( /*@out@*/ struct rtcm2_t *tp, char *buf) +/* break out the raw bits into the content fields */ +{ + int len; + unsigned int n, w; + struct rtcm2_msg_t *msg = (struct rtcm2_msg_t *)buf; + + tp->type = msg->w1.msgtype; + tp->length = msg->w2.frmlen; + tp->zcount = msg->w2.zcnt * ZCOUNT_SCALE; + tp->refstaid = msg->w1.refstaid; + tp->seqnum = msg->w2.sqnum; + tp->stathlth = msg->w2.stathlth; + + len = (int)tp->length; + n = 0; + switch (tp->type) { + case 1: + case 9: + { + struct b_correction_t *m = &msg->msg_type.type1.corrections[0]; + + while (len >= 0) { + if (len >= 2) { + tp->ranges.sat[n].ident = m->w3.satident1; + tp->ranges.sat[n].udre = m->w3.udre1; + tp->ranges.sat[n].issuedata = m->w4.issuedata1; + tp->ranges.sat[n].rangerr = m->w3.pc1 * + (m->w3.scale1 ? PCLARGE : PCSMALL); + tp->ranges.sat[n].rangerate = m->w4.rangerate1 * + (m->w3.scale1 ? RRLARGE : RRSMALL); + n++; + } + if (len >= 4) { + tp->ranges.sat[n].ident = m->w4.satident2; + tp->ranges.sat[n].udre = m->w4.udre2; + tp->ranges.sat[n].issuedata = m->w6.issuedata2; + tp->ranges.sat[n].rangerr = m->w5.pc2 * + (m->w4.scale2 ? PCLARGE : PCSMALL); + tp->ranges.sat[n].rangerate = m->w5.rangerate2 * + (m->w4.scale2 ? RRLARGE : RRSMALL); + n++; + } + if (len >= 5) { + tp->ranges.sat[n].ident = m->w6.satident3; + tp->ranges.sat[n].udre = m->w6.udre3; + tp->ranges.sat[n].issuedata = m->w7.issuedata3; + /*@ -shiftimplementation @*/ + tp->ranges.sat[n].rangerr = + ((m->w6.pc3_h << 8) | (m->w7.pc3_l)) * + (m->w6.scale3 ? PCLARGE : PCSMALL); + tp->ranges.sat[n].rangerate = + m->w7.rangerate3 * (m->w6.scale3 ? RRLARGE : RRSMALL); + /*@ +shiftimplementation @*/ + n++; + } + len -= 5; + m++; + } + tp->ranges.nentries = n; + } + break; + case 3: + { + struct rtcm2_msg3 *m = &msg->msg_type.type3; + + if ((tp->ecef.valid = len >= 4)) { + tp->ecef.x = ((m->w3.x_h << 8) | (m->w4.x_l)) * XYZ_SCALE; + tp->ecef.y = ((m->w4.y_h << 16) | (m->w5.y_l)) * XYZ_SCALE; + tp->ecef.z = ((m->w5.z_h << 24) | (m->w6.z_l)) * XYZ_SCALE; + } + } + break; + case 4: + if ((tp->reference.valid = len >= 2)) { + struct rtcm2_msg4 *m = &msg->msg_type.type4; + + tp->reference.system = + (m->w3.dgnss == 0) ? NAVSYSTEM_GPS : + ((m->w3.dgnss == 1) ? NAVSYSTEM_GLONASS : NAVSYSTEM_UNKNOWN); + tp->reference.sense = + (m->w3.dat != 0) ? SENSE_GLOBAL : SENSE_LOCAL; + if (m->w3.datum_alpha_char1) { + tp->reference.datum[n++] = (char)(m->w3.datum_alpha_char1); + } + if (m->w3.datum_alpha_char2) { + tp->reference.datum[n++] = (char)(m->w3.datum_alpha_char2); + } + if (m->w4.datum_sub_div_char1) { + tp->reference.datum[n++] = (char)(m->w4.datum_sub_div_char1); + } + if (m->w4.datum_sub_div_char2) { + tp->reference.datum[n++] = (char)(m->w4.datum_sub_div_char2); + } + if (m->w4.datum_sub_div_char3) { + tp->reference.datum[n++] = (char)(m->w4.datum_sub_div_char3); + } + tp->reference.datum[n++] = '\0'; + if (len >= 4) { + tp->reference.dx = m->w5.dx * DXYZ_SCALE; + tp->reference.dy = + ((m->w5.dy_h << 8) | m->w6.dy_l) * DXYZ_SCALE; + tp->reference.dz = m->w6.dz * DXYZ_SCALE; + } else + tp->reference.sense = SENSE_INVALID; + } + break; + case 5: + for (n = 0; n < (unsigned)len; n++) { + struct consat_t *csp = &tp->conhealth.sat[n]; + struct b_health_t *m = &msg->msg_type.type5.health[n]; + + csp->ident = m->sat_id; + csp->iodl = m->issue_of_data_link != 0; + csp->health = m->data_health; + /*@+ignoresigns@*/ + csp->snr = (int)(m->cn0 ? (m->cn0 + CNR_OFFSET) : SNR_BAD); + /*@-ignoresigns@*/ + csp->health_en = m->health_enable != 0; + csp->new_data = m->new_nav_data != 0; + csp->los_warning = m->loss_warn != 0; + csp->tou = m->time_unhealthy * TU_SCALE; + } + tp->conhealth.nentries = n; + break; + case 7: + for (w = 0; w < (unsigned)len; w++) { + struct station_t *np = &tp->almanac.station[n]; + struct b_station_t *mp = &msg->msg_type.type7.almanac[w]; + + np->latitude = mp->w3.lat * LA_SCALE; + /*@-shiftimplementation@*/ + np->longitude = ((mp->w3.lon_h << 8) | mp->w4.lon_l) * LO_SCALE; + /*@+shiftimplementation@*/ + np->range = mp->w4.range; + np->frequency = + (((mp->w4.freq_h << 6) | mp->w5.freq_l) * FREQ_SCALE) + + FREQ_OFFSET; + np->health = mp->w5.health; + np->station_id = mp->w5.station_id, + np->bitrate = tx_speed[mp->w5.bit_rate]; + n++; + } + tp->almanac.nentries = (unsigned)(len / 3); + break; + case 16: + /*@ -boolops @*/ + for (w = 0; w < (unsigned)len; w++) { + if (!msg->msg_type.type16.txt[w].byte1) { + break; + } + tp->message[n++] = (char)(msg->msg_type.type16.txt[w].byte1); + if (!msg->msg_type.type16.txt[w].byte2) { + break; + } + tp->message[n++] = (char)(msg->msg_type.type16.txt[w].byte2); + if (!msg->msg_type.type16.txt[w].byte3) { + break; + } + tp->message[n++] = (char)(msg->msg_type.type16.txt[w].byte3); + } + /*@ +boolops @*/ + tp->message[n++] = '\0'; + break; + + default: + memcpy(tp->words, msg->msg_type.rtcm2_msgunk, + (RTCM2_WORDS_MAX - 2) * sizeof(isgps30bits_t)); + break; + } +} + +static bool preamble_match(isgps30bits_t * w) +{ + return (((struct rtcm2_msghw1 *)w)->preamble == PREAMBLE_PATTERN); +} + +static bool length_check(struct gps_packet_t *lexer) +{ + return lexer->isgps.bufindex >= 2 + && lexer->isgps.bufindex >= + ((struct rtcm2_msg_t *)lexer->isgps.buf)->w2.frmlen + 2u; +} + +enum isgpsstat_t rtcm2_decode(struct gps_packet_t *lexer, unsigned int c) +{ + return isgps_decode(lexer, + preamble_match, length_check, RTCM2_WORDS_MAX, c); +} + +void rtcm2_sager_dump(const struct rtcm2_t *rtcm, /*@out@*/ char buf[], + size_t buflen) +/* dump the contents of a parsed RTCM104 message */ +{ + unsigned int n; + + (void)snprintf(buf, buflen, "H\t%u\t%u\t%0.1f\t%u\t%u\t%u\n", + rtcm->type, + rtcm->refstaid, + rtcm->zcount, rtcm->seqnum, rtcm->length, rtcm->stathlth); + + switch (rtcm->type) { + case 1: + case 9: + for (n = 0; n < rtcm->ranges.nentries; n++) { + const struct rangesat_t *rsp = &rtcm->ranges.sat[n]; + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "S\t%u\t%u\t%u\t%0.1f\t%0.3f\t%0.3f\n", + rsp->ident, + rsp->udre, + rsp->issuedata, + rtcm->zcount, rsp->rangerr, rsp->rangerate); + } + break; + + case 3: + if (rtcm->ecef.valid) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "R\t%.2f\t%.2f\t%.2f\n", + rtcm->ecef.x, rtcm->ecef.y, rtcm->ecef.z); + break; + + case 4: + if (rtcm->reference.valid) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "D\t%s\t%1d\t%s\t%.1f\t%.1f\t%.1f\n", + (rtcm->reference.system == NAVSYSTEM_GPS) ? "GPS" + : ((rtcm->reference.system == + NAVSYSTEM_GLONASS) ? "GLONASS" : "UNKNOWN"), + rtcm->reference.sense, rtcm->reference.datum, + rtcm->reference.dx, rtcm->reference.dy, + rtcm->reference.dz); + break; + + case 5: + for (n = 0; n < rtcm->conhealth.nentries; n++) { + const struct consat_t *csp = &rtcm->conhealth.sat[n]; + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "C\t%2u\t%1u\t%1u\t%2d\t%1u\t%1u\t%1u\t%2u\n", + csp->ident, + (unsigned)csp->iodl, + (unsigned)csp->health, + csp->snr, + (unsigned)csp->health_en, + (unsigned)csp->new_data, + (unsigned)csp->los_warning, csp->tou); + } + break; + + case 6: /* NOP msg */ + (void)strlcat(buf, "N\n", buflen); + break; + + case 7: + for (n = 0; n < rtcm->almanac.nentries; n++) { + const struct station_t *ssp = &rtcm->almanac.station[n]; + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "A\t%.4f\t%.4f\t%u\t%.1f\t%u\t%u\t%u\n", + ssp->latitude, + ssp->longitude, + ssp->range, + ssp->frequency, + ssp->health, ssp->station_id, ssp->bitrate); + } + break; + case 16: + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "T\t\"%s\"\n", rtcm->message); + break; + + default: + for (n = 0; n < rtcm->length; n++) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "U\t0x%08x\n", rtcm->words[n]); + break; + } + + (void)strlcat(buf, ".\n", buflen); +} + +#endif /* RTCM104V2_ENABLE */ diff --git a/driver_rtcm2.h b/driver_rtcm2.h new file mode 100644 index 0000000..b918d61 --- /dev/null +++ b/driver_rtcm2.h @@ -0,0 +1,499 @@ +/***************************************************************************** + +This is a decoder for RTCM-104 2.x, an obscure and complicated serial +protocol used for broadcasting pseudorange corrections from +differential-GPS reference stations. The applicable +standard is + +RTCM RECOMMENDED STANDARDS FOR DIFFERENTIAL NAVSTAR GPS SERVICE, +RTCM PAPER 194-93/SC 104-STD + +Ordering instructions are accessible from +under "Publications". This describes version 2.1 of the RTCM specification. +RTCM-104 was later incrementally revised up to a 2.3 level before being +completely redesigned as level 3.0. + +Also applicable is ITU-R M.823: "Technical characteristics of +differential transmissions for global navigation satellite systems +from maritime radio beacons in the frequency band 283.5 - 315 kHz in +region 1 and 285 - 325 kHz in regions 2 & 3." + +The RTCM 2.x protocol uses as a transport layer the GPS satellite +downlink protocol described in IS-GPS-200, the Navstar GPS Interface +Specification. This code relies on the lower-level packet-assembly +code for that protocol in isgps.c. + +The lower layer's job is done when it has assembled a message of up to +33 words of clean parity-checked data. At this point this upper layer +takes over. struct rtcm2_msg_t is overlaid on the buffer and the bitfields +are used to extract pieces of it. Those pieces are copied and (where +necessary) reassembled into a struct rtcm2_t. + +This code and the contents of isgps.c are evolved from code by Wolfgang +Rupprecht. Wolfgang's decoder was loosely based on one written by +John Sager in 1999 (in particular the dump function emits a close +descendant of Sager's dump format). Here are John Sager's original +notes: + +The RTCM decoder prints a legible representation of the input data. +The RTCM SC-104 specification is copyrighted, so I cannot +quote it - in fact, I have never read it! Most of the information +used to develop the decoder came from publication ITU-R M.823. +This is a specification of the data transmitted from LF DGPS +beacons in the 300kHz band. M.823 contains most of those parts of +RTCM SC-104 directly relevant to the air interface (there +are one or two annoying and vital omissions!). Information +about the serial interface format was gleaned from studying +the output of a beacon receiver test program made available on +Starlink's website. + +This file is Copyright (c) 2010 by the GPSD project +BSD terms apply: see the file COPYING in the distribution root for details. + +*****************************************************************************/ + +#ifndef _GPSD_RTCM2_H_ +#define _GPSD_RTCM2_H_ + +/* + * Structures for interpreting words in an RTCM-104 2.x message (after + * parity checking and removing inversion). Note, these structures + * are overlayed on the raw data in order to decode them into + * bitfields; this will fail horribly if your C compiler ever + * introduces padding between or before bit fields, or between + * 8-bit-aligned bitfields and character arrays. + * + * (In practice, the only class of machines on which this is likely + * to fail are word-aligned architectures without barrel shifters. + * Very few of these are left in 2008.) + * + * The RTCM 2.1 standard is less explicit than it should be about signed-integer + * representations. Two's complement is specified for prc and rrc (msg1wX), + * but not everywhere. + */ + +#define ZCOUNT_SCALE 0.6 /* sec */ +#define PCSMALL 0.02 /* meters */ +#define PCLARGE 0.32 /* meters */ +#define RRSMALL 0.002 /* meters/sec */ +#define RRLARGE 0.032 /* meters/sec */ + +#define MAXPCSMALL (0x7FFF * PCSMALL) /* 16-bits signed */ +#define MAXRRSMALL (0x7F * RRSMALL) /* 8-bits signed */ + +#define XYZ_SCALE 0.01 /* meters */ +#define DXYZ_SCALE 0.1 /* meters */ +#define LA_SCALE (90.0/32767.0) /* degrees */ +#define LO_SCALE (180.0/32767.0) /* degrees */ +#define FREQ_SCALE 0.1 /* kHz */ +#define FREQ_OFFSET 190.0 /* kHz */ +#define CNR_OFFSET 24 /* dB */ +#define TU_SCALE 5 /* minutes */ + +#pragma pack(1) + +#ifndef WORDS_BIGENDIAN /* little-endian, like x86 */ + +struct rtcm2_msg_t { + struct rtcm2_msghw1 { /* header word 1 */ + uint parity:6; + uint refstaid:10; /* reference station ID */ + uint msgtype:6; /* RTCM message type */ + uint preamble:8; /* fixed at 01100110 */ + uint _pad:2; + } w1; + + struct rtcm2_msghw2 { /* header word 2 */ + uint parity:6; + uint stathlth:3; /* station health */ + uint frmlen:5; + uint sqnum:3; + uint zcnt:13; + uint _pad:2; + } w2; + + union { + /* msg 1 - differential gps corrections */ + struct rtcm2_msg1 { + struct b_correction_t { + struct { /* msg 1 word 3 */ + uint parity:6; + int pc1:16; + uint satident1:5; /* satellite ID */ + uint udre1:2; + uint scale1:1; + uint _pad:2; + } w3; + + struct { /* msg 1 word 4 */ + uint parity:6; + uint satident2:5; /* satellite ID */ + uint udre2:2; + uint scale2:1; + uint issuedata1:8; + int rangerate1:8; + uint _pad:2; + } w4; + + struct { /* msg 1 word 5 */ + uint parity:6; + int rangerate2:8; + int pc2:16; + uint _pad:2; + } w5; + + struct { /* msg 1 word 6 */ + uint parity:6; + int pc3_h:8; + uint satident3:5; /* satellite ID */ + uint udre3:2; + uint scale3:1; + uint issuedata2:8; + uint _pad:2; + } w6; + + struct { /* msg 1 word 7 */ + uint parity:6; + uint issuedata3:8; + int rangerate3:8; + uint pc3_l:8; /* NOTE: uint for low byte */ + uint _pad:2; + } w7; + } corrections[(RTCM2_WORDS_MAX - 2) / 5]; + } type1; + + /* msg 3 - reference station parameters */ + struct rtcm2_msg3 { + struct { + uint parity:6; + uint x_h:24; + uint _pad:2; + } w3; + struct { + uint parity:6; + uint y_h:16; + uint x_l:8; + uint _pad:2; + } w4; + struct { + uint parity:6; + uint z_h:8; + uint y_l:16; + uint _pad:2; + } w5; + + struct { + uint parity:6; + uint z_l:24; + uint _pad:2; + } w6; + } type3; + + /* msg 4 - reference station datum */ + struct rtcm2_msg4 { + struct { + uint parity:6; + uint datum_alpha_char2:8; + uint datum_alpha_char1:8; + uint spare:4; + uint dat:1; + uint dgnss:3; + uint _pad:2; + } w3; + struct { + uint parity:6; + uint datum_sub_div_char2:8; + uint datum_sub_div_char1:8; + uint datum_sub_div_char3:8; + uint _pad:2; + } w4; + struct { + uint parity:6; + uint dy_h:8; + uint dx:16; + uint _pad:2; + } w5; + struct { + uint parity:6; + uint dz:24; + uint dy_l:8; + uint _pad:2; + } w6; + } type4; + + /* msg 5 - constellation health */ + struct rtcm2_msg5 { + struct b_health_t { + uint parity:6; + uint unassigned:2; + uint time_unhealthy:4; + uint loss_warn:1; + uint new_nav_data:1; + uint health_enable:1; + uint cn0:5; + uint data_health:3; + uint issue_of_data_link:1; + uint sat_id:5; + uint reserved:1; + uint _pad:2; + } health[MAXHEALTH]; + } type5; + + /* msg 6 - null message */ + + /* msg 7 - beacon almanac */ + struct rtcm2_msg7 { + struct b_station_t { + struct { + uint parity:6; + int lon_h:8; + int lat:16; + uint _pad:2; + } w3; + struct { + uint parity:6; + uint freq_h:6; + uint range:10; + uint lon_l:8; + uint _pad:2; + } w4; + struct { + uint parity:6; + uint encoding:1; + uint sync_type:1; + uint mod_mode:1; + uint bit_rate:3; + /* + * ITU-R M.823-2 page 9 and RTCM-SC104 v2.1 pages + * 4-21 and 4-22 are in conflict over the next two + * field sizes. ITU says 9+3, RTCM says 10+2. + * The latter correctly decodes the USCG station + * id's so I'll use that one here. -wsr + */ + uint station_id:10; + uint health:2; + uint freq_l:6; + uint _pad:2; + } w5; + } almanac[(RTCM2_WORDS_MAX - 2)/3]; + } type7; + + /* msg 16 - text msg */ + struct rtcm2_msg16 { + struct { + uint parity:6; + uint byte3:8; + uint byte2:8; + uint byte1:8; + uint _pad:2; + } txt[RTCM2_WORDS_MAX-2]; + } type16; + + /* unknown message */ + isgps30bits_t rtcm2_msgunk[RTCM2_WORDS_MAX-2]; + } msg_type; +}; + +#endif /* LITTLE_ENDIAN */ + +#ifdef WORDS_BIGENDIAN +/* This struct was generated from the above using invert-bitfields.pl */ +#ifndef S_SPLINT_S /* splint thinks it's a duplicate definition */ + +struct rtcm2_msg_t { + struct rtcm2_msghw1 { /* header word 1 */ + uint _pad:2; + uint preamble:8; /* fixed at 01100110 */ + uint msgtype:6; /* RTCM message type */ + uint refstaid:10; /* reference station ID */ + uint parity:6; + } w1; + + struct rtcm2_msghw2 { /* header word 2 */ + uint _pad:2; + uint zcnt:13; + uint sqnum:3; + uint frmlen:5; + uint stathlth:3; /* station health */ + uint parity:6; + } w2; + + union { + /* msg 1 - differential gps corrections */ + struct rtcm2_msg1 { + struct b_correction_t { + struct { /* msg 1 word 3 */ + uint _pad:2; + uint scale1:1; + uint udre1:2; + uint satident1:5; /* satellite ID */ + int pc1:16; + uint parity:6; + } w3; + + struct { /* msg 1 word 4 */ + uint _pad:2; + int rangerate1:8; + uint issuedata1:8; + uint scale2:1; + uint udre2:2; + uint satident2:5; /* satellite ID */ + uint parity:6; + } w4; + + struct { /* msg 1 word 5 */ + uint _pad:2; + int pc2:16; + int rangerate2:8; + uint parity:6; + } w5; + + struct { /* msg 1 word 6 */ + uint _pad:2; + uint issuedata2:8; + uint scale3:1; + uint udre3:2; + uint satident3:5; /* satellite ID */ + int pc3_h:8; + uint parity:6; + } w6; + + struct { /* msg 1 word 7 */ + uint _pad:2; + uint pc3_l:8; /* NOTE: uint for low byte */ + int rangerate3:8; + uint issuedata3:8; + uint parity:6; + } w7; + } corrections[(RTCM2_WORDS_MAX - 2) / 5]; + } type1; + + /* msg 3 - reference station parameters */ + struct rtcm2_msg3 { + struct { + uint _pad:2; + uint x_h:24; + uint parity:6; + } w3; + struct { + uint _pad:2; + uint x_l:8; + uint y_h:16; + uint parity:6; + } w4; + struct { + uint _pad:2; + uint y_l:16; + uint z_h:8; + uint parity:6; + } w5; + + struct { + uint _pad:2; + uint z_l:24; + uint parity:6; + } w6; + } type3; + + /* msg 4 - reference station datum */ + struct rtcm2_msg4 { + struct { + uint _pad:2; + uint dgnss:3; + uint dat:1; + uint spare:4; + uint datum_alpha_char1:8; + uint datum_alpha_char2:8; + uint parity:6; + } w3; + struct { + uint _pad:2; + uint datum_sub_div_char3:8; + uint datum_sub_div_char1:8; + uint datum_sub_div_char2:8; + uint parity:6; + } w4; + struct { + uint _pad:2; + uint dx:16; + uint dy_h:8; + uint parity:6; + } w5; + struct { + uint _pad:2; + uint dy_l:8; + uint dz:24; + uint parity:6; + } w6; + } type4; + + /* msg 5 - constellation health */ + struct rtcm2_msg5 { + struct b_health_t { + uint _pad:2; + uint reserved:1; + uint sat_id:5; + uint issue_of_data_link:1; + uint data_health:3; + uint cn0:5; + uint health_enable:1; + uint new_nav_data:1; + uint loss_warn:1; + uint time_unhealthy:4; + uint unassigned:2; + uint parity:6; + } health[MAXHEALTH]; + } type5; + + /* msg 6 - null message */ + + /* msg 7 - beacon almanac */ + struct rtcm2_msg7 { + struct b_station_t { + struct { + uint _pad:2; + int lat:16; + int lon_h:8; + uint parity:6; + } w3; + struct { + uint _pad:2; + uint lon_l:8; + uint range:10; + uint freq_h:6; + uint parity:6; + } w4; + struct { + uint _pad:2; + uint freq_l:6; + uint health:2; + uint station_id:10; + /* see comments in LE struct above. */ + uint bit_rate:3; + uint mod_mode:1; + uint sync_type:1; + uint encoding:1; + uint parity:6; + } w5; + } almanac[(RTCM2_WORDS_MAX - 2)/3]; + } type7; + + /* msg 16 - text msg */ + struct rtcm2_msg16 { + struct { + uint _pad:2; + uint byte1:8; + uint byte2:8; + uint byte3:8; + uint parity:6; + } txt[RTCM2_WORDS_MAX-2]; + } type16; + + /* unknown message */ + isgps30bits_t rtcm2_msgunk[RTCM2_WORDS_MAX-2]; + } msg_type; +}; + +#endif /* S_SPLINT_S */ +#endif /* BIG ENDIAN */ +#endif /* _GPSD_RTCM2_H_ */ diff --git a/driver_rtcm3.c b/driver_rtcm3.c new file mode 100644 index 0000000..a46a55b --- /dev/null +++ b/driver_rtcm3.c @@ -0,0 +1,928 @@ +/***************************************************************************** + +This is a decoder for RTCM-104 3.x, a serial protocol used for +broadcasting pseudorange corrections from differential-GPS reference +stations. The applicable specification is RTCM 10403.1: RTCM Paper +177-2006-SC104-STD. This obsolesces the esrlier RTCM-104 2.x +specifications. The specification document is proprietary; ordering +instructions are accessible from +under "Publications". + +Unike the RTCM 2.x protocol, RTCM3.x does not use the strange +sliding-bit-window IS-GPS-200 protocol as a transport layer, but is a +self-contained byte-oriented packet protocol. Packet recognition is +handled in the GPSD packet-getter state machine; this code is +concerned with unpacking the packets into well-behaved C structures, +coping with odd field lengths and fields that may overlap byte +boudaries. These report structures live in gps.h. + +Note that the unpacking this module does is probably useful only for +RTCM reporting and diagnostic tools. It is not necessary when +passing RTCM corrections to a GPS, which normally should just be +passed an entire correction packet for processing by their internal +firmware. + +This file is Copyright (c) 2010 by the GPSD project +BSD terms apply: see the file COPYING in the distribution root for details. + +*****************************************************************************/ + +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include +#include "gpsd_config.h" +#ifndef S_SPLINT_S +#ifdef HAVE_ARPA_INET +#include /* for ntohl(3) and friends */ +#endif /* HAVE_ARPA_INET */ +#endif /* S_SPLINT_S */ + +#include "gpsd.h" +#include "bits.h" + +#ifdef RTCM104V3_ENABLE + +/* scaling constants for RTCM3 real number types */ +#define PSEUDORANGE_RESOLUTION 0.2 /* DF011 */ +#define PSEUDORANGE_DIFF_RESOLUTION 0.0005 /* DF012 */ +#define CARRIER_NOISE_RATIO_UNITS 0.25 /* DF015 */ +#define ANTENNA_POSITION_RESOLUTION 0.0001 /* DF025-027 */ +#define ANTENNA_DEGREE_RESOLUTION 25e-6 /* DF062 */ +#define GPS_EPOCH_TIME_RESOLUTION 0.1 /* DF065 */ +#define PHASE_CORRECTION_RESOLUTION 0.5 /* DF069-070 */ + +/* Other magic values */ +#define INVALID_PSEUDORANGE 0x80000 /* DF012 */ + +/* Large case statements make GNU indent very confused */ +/* *INDENT-OFF* */ +/*@ -type @*//* re-enable when we're ready to take this live */ + +void rtcm3_unpack( /*@out@*/ struct rtcm3_t *rtcm, char *buf) +/* break out the raw bits into the scaled report-structure fields */ +{ + unsigned int n, n2; + int bitcount = 0; + unsigned int i; + signed long temp; + + /*@ -evalorder -sefparams -mayaliasunique @*/ +#define ugrab(width) (bitcount += width, ubits(buf, bitcount-width, width)) +#define sgrab(width) (bitcount += width, sbits(buf, bitcount-width, width)) + assert(ugrab(8) == 0xD3); + assert(ugrab(6) == 0x00); + + rtcm->length = (uint) ugrab(10); + rtcm->type = (uint) ugrab(12); + + switch (rtcm->type) { + case 1001: /* GPS Basic RTK, L1 Only */ + rtcm->rtcmtypes.rtcm3_1001.header.station_id = (uint) ugrab(12); + rtcm->rtcmtypes.rtcm3_1001.header.tow = (time_t) ugrab(30); + rtcm->rtcmtypes.rtcm3_1001.header.sync = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1001.header.satcount = (ushort) ugrab(5); + rtcm->rtcmtypes.rtcm3_1001.header.smoothing = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1001.header.interval = (ushort) ugrab(3); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1001.header.satcount; i++) { + rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].ident = (ushort) ugrab(6); + rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.indicator = + (unsigned char)ugrab(1); + temp = (unsigned long)ugrab(24); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.locktime = + (unsigned char)sgrab(7); + } + assert(bitcount == + 64 + 58 * rtcm->rtcmtypes.rtcm3_1001.header.satcount); + break; + + case 1002: /* GPS Extended RTK, L1 Only */ + rtcm->rtcmtypes.rtcm3_1002.header.station_id = (uint) ugrab(12); + rtcm->rtcmtypes.rtcm3_1002.header.tow = (time_t) ugrab(30); + rtcm->rtcmtypes.rtcm3_1002.header.sync = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1002.header.satcount = (ushort) ugrab(5); + rtcm->rtcmtypes.rtcm3_1002.header.smoothing = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1002.header.interval = (ushort) ugrab(3); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1002.header.satcount; i++) { + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].ident = (ushort) ugrab(6); + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.indicator = + (unsigned char)ugrab(1); + temp = (unsigned long)ugrab(24); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.locktime = + (unsigned char)sgrab(7); + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.ambiguity = + (bool) ugrab(8); + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.CNR = + (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS; + } + assert(bitcount == + 64 + 74 * rtcm->rtcmtypes.rtcm3_1002.header.satcount); + break; + + case 1003: /* GPS Basic RTK, L1 & L2 */ + rtcm->rtcmtypes.rtcm3_1003.header.station_id = (uint) ugrab(12); + rtcm->rtcmtypes.rtcm3_1003.header.tow = (time_t) ugrab(30); + rtcm->rtcmtypes.rtcm3_1003.header.sync = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1003.header.satcount = (ushort) ugrab(5); + rtcm->rtcmtypes.rtcm3_1003.header.smoothing = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1003.header.interval = (ushort) ugrab(3); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1003.header.satcount; i++) { + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].ident = (ushort) ugrab(6); + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.indicator = + (unsigned char)ugrab(1); + temp = (unsigned long)ugrab(24); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.locktime = + (unsigned char)sgrab(7); + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.indicator = + (unsigned char)ugrab(2); + temp = (unsigned long)ugrab(24); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.locktime = + (unsigned char)sgrab(7); + } + assert(bitcount == + 64 + 101 * rtcm->rtcmtypes.rtcm3_1003.header.satcount); + break; + + case 1004: /* GPS Extended RTK, L1 & L2 */ + rtcm->rtcmtypes.rtcm3_1004.header.station_id = (uint) ugrab(12); + rtcm->rtcmtypes.rtcm3_1004.header.tow = (time_t) ugrab(30); + rtcm->rtcmtypes.rtcm3_1004.header.sync = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1004.header.satcount = (ushort) ugrab(5); + rtcm->rtcmtypes.rtcm3_1004.header.smoothing = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1004.header.interval = (ushort) ugrab(3); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1004.header.satcount; i++) { + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].ident = (ushort) ugrab(6); + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.indicator = + (bool) ugrab(1); + temp = (unsigned long)ugrab(24); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.locktime = + (unsigned char)sgrab(7); + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.ambiguity = + (bool) ugrab(8); + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.CNR = + (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS; + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.indicator = + (unsigned char)ugrab(2); + temp = (unsigned long)ugrab(24); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.locktime = + (unsigned char)sgrab(7); + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.ambiguity = + (bool) ugrab(8); + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.CNR = + (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS; + } + assert(bitcount == + 64 + 125 * rtcm->rtcmtypes.rtcm3_1004.header.satcount); + break; + + case 1005: /* Stationary Antenna Reference Point, No Height Information */ + rtcm->rtcmtypes.rtcm3_1005.station_id = (unsigned short)ugrab(12); + ugrab(6); /* reserved */ + if ((bool) ugrab(1)) + rtcm->rtcmtypes.rtcm3_1005.system = NAVSYSTEM_GPS; + else if ((bool) ugrab(1)) + rtcm->rtcmtypes.rtcm3_1005.system = NAVSYSTEM_GLONASS; + else if ((bool) ugrab(1)) + rtcm->rtcmtypes.rtcm3_1005.system = NAVSYSTEM_GALILEO; + rtcm->rtcmtypes.rtcm3_1005.reference_station = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1005.ecef_x = + sgrab(38) * ANTENNA_POSITION_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1005.single_receiver = ugrab(1); + ugrab(1); + rtcm->rtcmtypes.rtcm3_1005.ecef_y = + sgrab(38) * ANTENNA_POSITION_RESOLUTION; + ugrab(2); + rtcm->rtcmtypes.rtcm3_1005.ecef_z = + sgrab(38) * ANTENNA_POSITION_RESOLUTION; + assert(bitcount == 152); + break; + + case 1006: /* Stationary Antenna Reference Point, with Height Information */ + rtcm->rtcmtypes.rtcm3_1006.station_id = (unsigned short)ugrab(12); + ugrab(6); /* reserved */ + if ((bool) ugrab(1)) + rtcm->rtcmtypes.rtcm3_1006.system = NAVSYSTEM_GPS; + else if ((bool) ugrab(1)) + rtcm->rtcmtypes.rtcm3_1006.system = NAVSYSTEM_GLONASS; + else if ((bool) ugrab(1)) + rtcm->rtcmtypes.rtcm3_1006.system = NAVSYSTEM_GALILEO; + rtcm->rtcmtypes.rtcm3_1006.reference_station = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1006.ecef_x = + sgrab(38) * ANTENNA_POSITION_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1006.single_receiver = ugrab(1); + ugrab(1); + rtcm->rtcmtypes.rtcm3_1006.ecef_y = + sgrab(38) * ANTENNA_POSITION_RESOLUTION; + ugrab(2); + rtcm->rtcmtypes.rtcm3_1006.ecef_z = + sgrab(38) * ANTENNA_POSITION_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1006.height = + ugrab(16) * ANTENNA_POSITION_RESOLUTION; + assert(bitcount == 168); + break; + + case 1007: /* Antenna Descriptor */ + rtcm->rtcmtypes.rtcm3_1007.station_id = (unsigned short)ugrab(12); + n = (unsigned long)ugrab(8); + (void)memcpy(rtcm->rtcmtypes.rtcm3_1007.descriptor, buf + 4, n); + rtcm->rtcmtypes.rtcm3_1007.descriptor[n] = '\0'; + bitcount += 8 * n; + rtcm->rtcmtypes.rtcm3_1007.setup_id = ugrab(8); + assert(bitcount == (int)(40 + 8 * n)); + break; + + case 1008: /* Antenna Descriptor & Serial Number */ + rtcm->rtcmtypes.rtcm3_1008.station_id = (unsigned short)ugrab(12); + n = (unsigned long)ugrab(8); + (void)memcpy(rtcm->rtcmtypes.rtcm3_1008.descriptor, buf + 4, n); + rtcm->rtcmtypes.rtcm3_1008.descriptor[n] = '\0'; + bitcount += 8 * n; + rtcm->rtcmtypes.rtcm3_1008.setup_id = ugrab(8); + n2 = (unsigned long)ugrab(8); + (void)memcpy(rtcm->rtcmtypes.rtcm3_1008.serial, buf + 6 + n, n2); + rtcm->rtcmtypes.rtcm3_1008.serial[n2] = '\0'; + bitcount += 8 * n2; + assert(bitcount == (int)(48 + 8 * (n + n2))); + break; + + case 1009: /* GLONASS Basic RTK, L1 Only */ + rtcm->rtcmtypes.rtcm3_1009.header.station_id = + (unsigned short)ugrab(12); + rtcm->rtcmtypes.rtcm3_1009.header.tow = (time_t) ugrab(27); + rtcm->rtcmtypes.rtcm3_1009.header.sync = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1009.header.satcount = (ushort) ugrab(5); + rtcm->rtcmtypes.rtcm3_1009.header.smoothing = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1009.header.interval = (ushort) ugrab(3); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1009.header.satcount; i++) { + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].ident = (ushort) ugrab(6); + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.indicator = + (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.channel = + (ushort) ugrab(5); + temp = (unsigned long)ugrab(25); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.locktime = + (unsigned char)sgrab(7); + } + assert(bitcount == + 61 + 64 * rtcm->rtcmtypes.rtcm3_1009.header.satcount); + break; + + case 1010: /* GLONASS Extended RTK, L1 Only */ + rtcm->rtcmtypes.rtcm3_1010.header.station_id = + (unsigned short)ugrab(12); + rtcm->rtcmtypes.rtcm3_1010.header.tow = (time_t) ugrab(27); + rtcm->rtcmtypes.rtcm3_1010.header.sync = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1010.header.satcount = (ushort) ugrab(5); + rtcm->rtcmtypes.rtcm3_1010.header.smoothing = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1010.header.interval = (ushort) ugrab(3); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1010.header.satcount; i++) { + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].ident = (ushort) ugrab(6); + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.indicator = + (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.channel = + (ushort) ugrab(5); + temp = (unsigned long)ugrab(25); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.locktime = + (unsigned char)sgrab(7); + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.ambiguity = + (bool) ugrab(7); + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.CNR = + (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS; + } + assert(bitcount == + 61 + 79 * rtcm->rtcmtypes.rtcm3_1010.header.satcount); + break; + + case 1011: /* GLONASS Basic RTK, L1 & L2 */ + rtcm->rtcmtypes.rtcm3_1011.header.station_id = + (unsigned short)ugrab(12); + rtcm->rtcmtypes.rtcm3_1011.header.tow = (time_t) ugrab(27); + rtcm->rtcmtypes.rtcm3_1011.header.sync = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1011.header.satcount = (ushort) ugrab(5); + rtcm->rtcmtypes.rtcm3_1011.header.smoothing = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1011.header.interval = (ushort) ugrab(3); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1011.header.satcount; i++) { + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].ident = (ushort) ugrab(6); + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.indicator = + (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.channel = + (ushort) ugrab(5); + temp = (unsigned long)ugrab(25); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.locktime = + (unsigned char)sgrab(7); + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.ambiguity = + (bool) ugrab(7); + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.CNR = + (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS; + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.indicator = + (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.channel = + (ushort) ugrab(5); + temp = (unsigned long)ugrab(25); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.locktime = + (unsigned char)sgrab(7); + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.ambiguity = + (bool) ugrab(7); + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.CNR = + (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS; + } + assert(bitcount == + 61 + 107 * rtcm->rtcmtypes.rtcm3_1011.header.satcount); + break; + + case 1012: /* GLONASS Extended RTK, L1 & L2 */ + rtcm->rtcmtypes.rtcm3_1012.header.station_id = + (unsigned short)ugrab(12); + rtcm->rtcmtypes.rtcm3_1012.header.tow = (time_t) ugrab(27); + rtcm->rtcmtypes.rtcm3_1012.header.sync = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1012.header.satcount = (ushort) ugrab(5); + rtcm->rtcmtypes.rtcm3_1012.header.smoothing = (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1012.header.interval = (ushort) ugrab(3); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1012.header.satcount; i++) { + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].ident = (ushort) ugrab(6); + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.indicator = + (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.channel = + (ushort) ugrab(5); + temp = (unsigned long)ugrab(25); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.locktime = + (unsigned char)sgrab(7); + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.indicator = + (bool) ugrab(1); + temp = (unsigned long)ugrab(25); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.pseudorange = 0; + else + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.pseudorange = + temp * PSEUDORANGE_RESOLUTION; + temp = (long)sgrab(20); + if (temp == INVALID_PSEUDORANGE) + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.rangediff = 0; + else + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.rangediff = + temp * PSEUDORANGE_DIFF_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.locktime = + (unsigned char)sgrab(7); + } + assert(bitcount == + 61 + 130 * rtcm->rtcmtypes.rtcm3_1012.header.satcount); + break; + + case 1013: /* System Parameters */ + rtcm->rtcmtypes.rtcm3_1013.station_id = (unsigned short)ugrab(12); + rtcm->rtcmtypes.rtcm3_1013.mjd = (unsigned short)ugrab(16); + rtcm->rtcmtypes.rtcm3_1013.sod = (unsigned short)ugrab(17); + rtcm->rtcmtypes.rtcm3_1013.ncount = (unsigned long)ugrab(5); + rtcm->rtcmtypes.rtcm3_1013.leapsecs = (unsigned char)ugrab(8); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1013.ncount; i++) { + rtcm->rtcmtypes.rtcm3_1013.announcements[i].id = + (unsigned short)ugrab(12); + rtcm->rtcmtypes.rtcm3_1013.announcements[i].sync = + (bool) ugrab(1); + rtcm->rtcmtypes.rtcm3_1013.announcements[i].interval = + (unsigned short)ugrab(16); + } + assert(bitcount == 70 + 29 * rtcm->rtcmtypes.rtcm3_1013.ncount); + break; + + case 1014: + rtcm->rtcmtypes.rtcm3_1014.network_id = (int)ugrab(8); + rtcm->rtcmtypes.rtcm3_1014.subnetwork_id = (int)ugrab(4); + rtcm->rtcmtypes.rtcm3_1014.stationcount = (char)ugrab(5); + rtcm->rtcmtypes.rtcm3_1014.master_id = (int)ugrab(12); + rtcm->rtcmtypes.rtcm3_1014.aux_id = (int)ugrab(12); + rtcm->rtcmtypes.rtcm3_1014.d_lat = + (unsigned short)ugrab(20) * ANTENNA_DEGREE_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1014.d_lon = + (unsigned short)ugrab(21) * ANTENNA_DEGREE_RESOLUTION; + rtcm->rtcmtypes.rtcm3_1014.d_alt = (unsigned short)ugrab(23) / 1000; + assert(bitcount == 117); + break; + + case 1015: + break; + + case 1016: + break; + + case 1017: + break; + + case 1018: + break; + + case 1019: + break; + + case 1020: + break; + + case 1029: + rtcm->rtcmtypes.rtcm3_1029.station_id = (unsigned short)ugrab(12); + rtcm->rtcmtypes.rtcm3_1029.mjd = (unsigned short)ugrab(16); + rtcm->rtcmtypes.rtcm3_1029.sod = (unsigned short)ugrab(17); + rtcm->rtcmtypes.rtcm3_1029.len = (unsigned long)ugrab(7); + n = rtcm->rtcmtypes.rtcm3_1029.unicode_units = + (unsigned long)ugrab(8); + (void)memcpy(rtcm->rtcmtypes.rtcm3_1029.text, buf + 9, n); + bitcount += 8 * n; + assert(bitcount == (int)(72 + 8 * n)); + break; + } +#undef sgrab +#undef ugrab + /*@ +evalorder +sefparams +mayaliasunique @*/ +} + +void rtcm3_dump(struct rtcm3_t *rtcm, FILE * fp) +/* dump the contents of a parsed RTCM104 message */ +{ + int i; + + char *systems[] = { "GPS", "Glonass", "Galileo", "unknown" }; + + (void)fprintf(fp, "%u (%u):\n", rtcm->type, rtcm->length); + +#define BOOL(c) (c!=0 ? 't' : 'f') +#define CODE(x) (unsigned int)(x) +#define INT(x) (unsigned int)(x) + switch (rtcm->type) { + case 1001: + (void)fprintf(fp, + " #station_id=%u, tow=%d sync=%c smoothing=%c interval=%u satcount=%u", + rtcm->rtcmtypes.rtcm3_1001.header.station_id, + (int)rtcm->rtcmtypes.rtcm3_1001.header.tow, + BOOL(rtcm->rtcmtypes.rtcm3_1001.header.sync), + BOOL(rtcm->rtcmtypes.rtcm3_1001.header.smoothing), + rtcm->rtcmtypes.rtcm3_1001.header.interval, + rtcm->rtcmtypes.rtcm3_1001.header.satcount); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1001.header.satcount; i++) { + (void)fprintf(fp, + " ident=%u\n L1: ind=%u prange=%8.1f delta=%6.4f lockt=%u\n", + rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].ident, + CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]. + L1.indicator), + rtcm->rtcmtypes.rtcm3_1001.rtk_data[i]. + L1.pseudorange, + rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1001.rtk_data[i]. + L1.locktime)); + } + break; + + case 1002: + (void)fprintf(fp, + " #station_id=%u, tow=%d sync=%c smoothing=%c interval=%u satcount=%u", + rtcm->rtcmtypes.rtcm3_1002.header.station_id, + (int)rtcm->rtcmtypes.rtcm3_1002.header.tow, + BOOL(rtcm->rtcmtypes.rtcm3_1002.header.sync), + BOOL(rtcm->rtcmtypes.rtcm3_1002.header.smoothing), + rtcm->rtcmtypes.rtcm3_1002.header.interval, + rtcm->rtcmtypes.rtcm3_1002.header.satcount); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1002.header.satcount; i++) { + (void)fprintf(fp, + " ident=%u\n L1: ind=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n", + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].ident, + CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]. + L1.indicator), + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i]. + L1.pseudorange, + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1002.rtk_data[i]. + L1.locktime), + INT(rtcm->rtcmtypes.rtcm3_1002.rtk_data[i]. + L1.ambiguity), + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.CNR); + } + break; + + case 1003: + (void)fprintf(fp, + " #station_id=%u, tow=%d sync=%c smoothing=%c interval=%u satcount=%u", + rtcm->rtcmtypes.rtcm3_1003.header.station_id, + (int)rtcm->rtcmtypes.rtcm3_1003.header.tow, + BOOL(rtcm->rtcmtypes.rtcm3_1003.header.sync), + BOOL(rtcm->rtcmtypes.rtcm3_1003.header.smoothing), + rtcm->rtcmtypes.rtcm3_1003.header.interval, + rtcm->rtcmtypes.rtcm3_1003.header.satcount); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1003.header.satcount; i++) { + (void)fprintf(fp, + " ident=%u\n L1: ind=%u prange=%8.1f delta=%6.4f lockt=%u\n L2: ind=%u prange=%8.1f delta=%6.4f lockt=%u\n", + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].ident, + CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]. + L1.indicator), + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]. + L1.pseudorange, + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]. + L1.locktime), + CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]. + L2.indicator), + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]. + L2.pseudorange, + rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]. + L2.locktime)); + } + break; + + case 1004: + (void)fprintf(fp, + " #station_id=%u, tow=%d sync=%c smoothing=%c interval=%u satcount=%u\n", + rtcm->rtcmtypes.rtcm3_1004.header.station_id, + (int)rtcm->rtcmtypes.rtcm3_1004.header.tow, + BOOL(rtcm->rtcmtypes.rtcm3_1004.header.sync), + BOOL(rtcm->rtcmtypes.rtcm3_1004.header.smoothing), + rtcm->rtcmtypes.rtcm3_1004.header.interval, + rtcm->rtcmtypes.rtcm3_1004.header.satcount); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1004.header.satcount; i++) { + (void)fprintf(fp, + " ident=%u\n L1: ind=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n L2: ind=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n", + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].ident, + CODE(rtcm->rtcmtypes.rtcm3_1004.rtk_data[i]. + L1.indicator), + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i]. + L1.pseudorange, + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1004.rtk_data[i]. + L1.locktime), + INT(rtcm->rtcmtypes.rtcm3_1002.rtk_data[i]. + L1.ambiguity), + rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.CNR, + CODE(rtcm->rtcmtypes.rtcm3_1004.rtk_data[i]. + L2.indicator), + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i]. + L2.pseudorange, + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1004.rtk_data[i]. + L2.locktime), + INT(rtcm->rtcmtypes.rtcm3_1004.rtk_data[i]. + L2.ambiguity), + rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.CNR); + } + break; + + case 1005: + (void)fprintf(fp, + " station_id=%u, %s refstation=%c sro=%c x=%f y=%f z=%f\n", + rtcm->rtcmtypes.rtcm3_1005.station_id, + systems[rtcm->rtcmtypes.rtcm3_1005.system], + BOOL(rtcm->rtcmtypes.rtcm3_1005.reference_station), + BOOL(rtcm->rtcmtypes.rtcm3_1005.single_receiver), + rtcm->rtcmtypes.rtcm3_1005.ecef_x, + rtcm->rtcmtypes.rtcm3_1005.ecef_y, + rtcm->rtcmtypes.rtcm3_1005.ecef_z); + break; + + case 1006: + (void)fprintf(fp, + " station_id=%u, %s refstation=%c sro=%c x=%f y=%f z=%f a=%f\n", + rtcm->rtcmtypes.rtcm3_1006.station_id, + systems[rtcm->rtcmtypes.rtcm3_1006.system], + BOOL(rtcm->rtcmtypes.rtcm3_1006.reference_station), + BOOL(rtcm->rtcmtypes.rtcm3_1006.single_receiver), + rtcm->rtcmtypes.rtcm3_1006.ecef_x, + rtcm->rtcmtypes.rtcm3_1006.ecef_y, + rtcm->rtcmtypes.rtcm3_1006.ecef_z, + rtcm->rtcmtypes.rtcm3_1006.height); + break; + + case 1007: + (void)fprintf(fp, + " station_id=%u, desc=%s setup-id=%u\n", + rtcm->rtcmtypes.rtcm3_1007.station_id, + rtcm->rtcmtypes.rtcm3_1007.descriptor, + INT(rtcm->rtcmtypes.rtcm3_1007.setup_id)); + break; + + case 1008: + (void)fprintf(fp, + " station_id=%u, desc=%s setup-id=%u serial=%s\n", + rtcm->rtcmtypes.rtcm3_1008.station_id, + rtcm->rtcmtypes.rtcm3_1008.descriptor, + INT(rtcm->rtcmtypes.rtcm3_1008.setup_id), + rtcm->rtcmtypes.rtcm3_1008.serial); + break; + + case 1009: + (void)fprintf(fp, + " #station_id=%u, tow=%d sync=%c smooting=%c interval=%u satcount=%u", + rtcm->rtcmtypes.rtcm3_1009.header.station_id, + (int)rtcm->rtcmtypes.rtcm3_1009.header.tow, + BOOL(rtcm->rtcmtypes.rtcm3_1009.header.sync), + BOOL(rtcm->rtcmtypes.rtcm3_1009.header.smoothing), + rtcm->rtcmtypes.rtcm3_1009.header.interval, + rtcm->rtcmtypes.rtcm3_1009.header.satcount); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1009.header.satcount; i++) { + (void)fprintf(fp, + " ident=%u\n L1: ind=%u channel=%u prange=%8.1f delta=%6.4f lockt=%u\n", + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].ident, + CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]. + L1.indicator), + INT(rtcm->rtcmtypes.rtcm3_1009.rtk_data[i]. + L1.channel), + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i]. + L1.pseudorange, + rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1009.rtk_data[i]. + L1.locktime)); + } + break; + + case 1010: + (void)fprintf(fp, + " #station_id=%u, tow=%d sync=%c smooting=%c interval=%u satcount=%u", + rtcm->rtcmtypes.rtcm3_1010.header.station_id, + (int)rtcm->rtcmtypes.rtcm3_1010.header.tow, + BOOL(rtcm->rtcmtypes.rtcm3_1010.header.sync), + BOOL(rtcm->rtcmtypes.rtcm3_1010.header.smoothing), + rtcm->rtcmtypes.rtcm3_1010.header.interval, + rtcm->rtcmtypes.rtcm3_1010.header.satcount); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1010.header.satcount; i++) { + (void)fprintf(fp, + " ident=%u\n L1: ind=%u channel=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n", + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].ident, + CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]. + L1.indicator), + INT(rtcm->rtcmtypes.rtcm3_1010.rtk_data[i]. + L1.channel), + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i]. + L1.pseudorange, + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1010.rtk_data[i]. + L1.locktime), + INT(rtcm->rtcmtypes.rtcm3_1010.rtk_data[i]. + L1.ambiguity), + rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.CNR); + } + break; + + case 1011: + (void)fprintf(fp, + " #station_id=%u, tow=%d sync=%c smooting=%c interval=%u satcount=%u", + rtcm->rtcmtypes.rtcm3_1011.header.station_id, + (int)rtcm->rtcmtypes.rtcm3_1011.header.tow, + BOOL(rtcm->rtcmtypes.rtcm3_1011.header.sync), + BOOL(rtcm->rtcmtypes.rtcm3_1011.header.smoothing), + rtcm->rtcmtypes.rtcm3_1011.header.interval, + rtcm->rtcmtypes.rtcm3_1011.header.satcount); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1011.header.satcount; i++) { + (void)fprintf(fp, + " ident=%u\n L1: ind=%u channel=%u prange=%8.1f delta=%6.4f lockt=%u\n L2: ind=%u prange=%8.1f delta=%6.4f lockt=%u\n", + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].ident, + CODE(rtcm->rtcmtypes.rtcm3_1011.rtk_data[i]. + L1.indicator), + INT(rtcm->rtcmtypes.rtcm3_1011.rtk_data[i]. + L1.channel), + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i]. + L1.pseudorange, + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1011.rtk_data[i]. + L1.locktime), + CODE(rtcm->rtcmtypes.rtcm3_1011.rtk_data[i]. + L2.indicator), + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i]. + L2.pseudorange, + rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1011.rtk_data[i]. + L2.locktime)); + } + break; + + case 1012: + (void)fprintf(fp, + " #station_id=%u, tow=%d sync=%c smooting=%c interval=%u satcount=%u", + rtcm->rtcmtypes.rtcm3_1012.header.station_id, + (int)rtcm->rtcmtypes.rtcm3_1012.header.tow, + BOOL(rtcm->rtcmtypes.rtcm3_1012.header.sync), + BOOL(rtcm->rtcmtypes.rtcm3_1012.header.smoothing), + rtcm->rtcmtypes.rtcm3_1012.header.interval, + rtcm->rtcmtypes.rtcm3_1012.header.satcount); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1012.header.satcount; i++) { + (void)fprintf(fp, + " ident=%u\n L1: ind=%u channel=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n L2: ind=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n", + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].ident, + CODE(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i]. + L1.indicator), + INT(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i]. + L1.channel), + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i]. + L1.pseudorange, + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i]. + L1.locktime), + INT(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i]. + L1.ambiguity), + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.CNR, + CODE(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i]. + L2.indicator), + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i]. + L2.pseudorange, + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.rangediff, + INT(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i]. + L2.locktime), + INT(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i]. + L2.ambiguity), + rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.CNR); + } + break; + + case 1013: + (void)fprintf(fp, + " station_id=%u, mjd=%u sec=%u leapsecs=%u ncount=%u\n", + rtcm->rtcmtypes.rtcm3_1013.station_id, + rtcm->rtcmtypes.rtcm3_1013.mjd, + rtcm->rtcmtypes.rtcm3_1013.sod, + INT(rtcm->rtcmtypes.rtcm3_1013.leapsecs), + INT(rtcm->rtcmtypes.rtcm3_1013.ncount)); + for (i = 0; i < rtcm->rtcmtypes.rtcm3_1013.ncount; i++) + (void)fprintf(fp, + " id=%u sync=%c interval=%u\n", + rtcm->rtcmtypes.rtcm3_1013.announcements[i].id, + BOOL(rtcm->rtcmtypes.rtcm3_1013. + announcements[i].sync), + rtcm->rtcmtypes.rtcm3_1013. + announcements[i].interval); + break; + + case 1014: + (void)fprintf(fp, + " netid=%u subnetid=%u statcount=%u master=%u aux=%u lat=%f, lon=%f, alt=%f\n", + rtcm->rtcmtypes.rtcm3_1014.network_id, + rtcm->rtcmtypes.rtcm3_1014.subnetwork_id, + (uint) rtcm->rtcmtypes.rtcm3_1014.stationcount, + rtcm->rtcmtypes.rtcm3_1014.master_id, + rtcm->rtcmtypes.rtcm3_1014.aux_id, + rtcm->rtcmtypes.rtcm3_1014.d_lat, + rtcm->rtcmtypes.rtcm3_1014.d_lon, + rtcm->rtcmtypes.rtcm3_1014.d_alt); + break; + + case 1015: + break; + + case 1016: + break; + + case 1017: + break; + + case 1018: + break; + + case 1019: + break; + + case 1020: + break; + + case 1029: + (void)fprintf(fp, + " station_id=%u, mjd=%u sec=%u len=%u units=%u msg=%s\n", + rtcm->rtcmtypes.rtcm3_1029.station_id, + rtcm->rtcmtypes.rtcm3_1029.mjd, + rtcm->rtcmtypes.rtcm3_1029.sod, + INT(rtcm->rtcmtypes.rtcm3_1029.len), + INT(rtcm->rtcmtypes.rtcm3_1029.unicode_units), + (char *)rtcm->rtcmtypes.rtcm3_1029.text); + break; + + default: + (void)fprintf(fp, " Unknown content\n"); + break; + } +#undef CODE +#undef BOOL +#undef INT +} + +/* *INDENT-ON* */ +/*@ +type @*/ + +#endif /* RTCM104V3_ENABLE */ diff --git a/driver_sirf.c b/driver_sirf.c new file mode 100644 index 0000000..9582e7d --- /dev/null +++ b/driver_sirf.c @@ -0,0 +1,1380 @@ +/* + * This is the gpsd driver for SiRF GPSes operating in binary mode. + * It also handles uBlox, a SiRF derivative. + * + * The advantage: Reports climb/sink rate (raw-mode clients won't see this). + * The disadvantages: Doesn't return PDOP or VDOP, just HDOP. + * + * Chris Kuethe, our SiRF expert, tells us: + * + * "I don't see any indication in any of my material that PDOP, GDOP + * or VDOP are output. There are quantities called Estimated + * {Horizontal Position, Vertical Position, Time, Horizonal Velocity} + * Error, but those are apparently only valid when SiRFDRive is + * active." + * + * "(SiRFdrive is their Dead Reckoning augmented firmware. It + * allows you to feed odometer ticks, gyro and possibly + * accelerometer inputs to the chip to allow it to continue + * to navigate in the absence of satellite information, and + * to improve fixes when you do have satellites.)" + * + * "[When we need RINEX data, we can get it from] SiRF Message #5. + * If it's no longer implemented on your receiver, messages + * 7, 28, 29 and 30 will give you the same information." + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#include +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include + +#include "gpsd.h" +#include "bits.h" +#include "timebase.h" +#if defined(SIRF_ENABLE) && defined(BINARY_ENABLE) + +#define HI(n) ((n) >> 8) +#define LO(n) ((n) & 0xff) + +#ifdef ALLOW_RECONFIGURE +/*@ +charint @*/ +/* message to enable: + * MID 7 Clock Status + * MID 8 50Bps subframe data + * MID 17 Differential Corrections + * MID 28 Nav Lib Measurement Data + * MID 29 Nav Lib DGPS Data + * MID 30 Nav Lib SV State Data + * MID 31 Nav Lib Initialization data + * at 1Hz rate */ +static unsigned char enablesubframe[] = { + 0xa0, 0xa2, 0x00, 0x19, + 0x80, /* MID 128 initialize Data Source */ + 0x00, 0x00, 0x00, 0x00, /* EXEF X */ + 0x00, 0x00, 0x00, 0x00, /* ECEF Y */ + 0x00, 0x00, 0x00, 0x00, /* ECEF Z */ + 0x00, 0x00, 0x00, 0x00, /* clock drift */ + 0x00, 0x00, 0x00, 0x00, /* time of week */ + 0x00, 0x00, /* week number */ + 0x0C, /* Chans 1-12 */ + /* change the next 0x10 to 0x08 + * for factory reset */ + 0x10, + 0x00, 0x00, 0xb0, 0xb3 +}; + +static unsigned char disablesubframe[] = { + 0xa0, 0xa2, 0x00, 0x19, + 0x80, /* MID 128 initialize Data Source */ + 0x00, 0x00, 0x00, 0x00, /* EXEF X */ + 0x00, 0x00, 0x00, 0x00, /* ECEF Y */ + 0x00, 0x00, 0x00, 0x00, /* ECEF Z */ + 0x00, 0x00, 0x00, 0x00, /* clock drift */ + 0x00, 0x00, 0x00, 0x00, /* time of week */ + 0x00, 0x00, /* week number */ + 0x0C, /* Chans 1-12 */ + + 0x00, + 0x00, 0x00, 0xb0, 0xb3 +}; + +static unsigned char modecontrol[] = { + 0xa0, 0xa2, 0x00, 0x0e, + 0x88, /* MID 136 Mode Control */ + 0x00, 0x00, /* pad bytes */ + 0x00, /* degraded mode off */ + 0x00, 0x00, /* pad bytes */ + 0x00, 0x00, /* altitude */ + 0x00, /* altitude hold auto */ + 0x00, /* use last computed alt */ + 0x00, /* reserved */ + 0x00, /* disable degraded mode */ + 0x00, /* disable dead reckoning */ + 0x01, /* enable track smoothing */ + 0x00, 0x00, 0xb0, 0xb3 +}; + +/* enable 1 PPS Time MID 52 * + * using Set Message Rate MID 166 */ +static unsigned char enablemid52[] = { + 0xa0, 0xa2, 0x00, 0x08, + 0xa6, /* MID 166 */ + 0x00, /* enable/disable one message */ + 0x34, /* MID 52 */ + 0x01, /* sent once per second */ + 0x00, 0x00, 0x00, 0x00, /* unused, set to zero */ + 0x00, 0xdb, 0xb0, 0xb3 +}; + +/*@ -charint @*/ +#endif /* ALLOW_RECONFIGURE */ + + +static gps_mask_t sirf_msg_debug(unsigned char *, size_t); +static gps_mask_t sirf_msg_errors(unsigned char *, size_t); + +static gps_mask_t sirf_msg_navdata(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t sirf_msg_navsol(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t sirf_msg_nlmd(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t sirf_msg_ppstime(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t sirf_msg_svinfo(struct gps_device_t *, unsigned char *, + size_t); +#ifdef ALLOW_RECONFIGURE +static gps_mask_t sirf_msg_swversion(struct gps_device_t *, unsigned char *, + size_t); +static gps_mask_t sirf_msg_sysparam(struct gps_device_t *, unsigned char *, + size_t); +#endif /* ALLOW_RECONFIGURE */ +static gps_mask_t sirf_msg_ublox(struct gps_device_t *, unsigned char *, + size_t); + + +static bool sirf_write(int fd, unsigned char *msg) +{ + unsigned int crc; + size_t i, len; + bool ok; + + len = (size_t) ((msg[2] << 8) | msg[3]); + + /* calculate CRC */ + crc = 0; + for (i = 0; i < len; i++) + crc += (int)msg[4 + i]; + crc &= 0x7fff; + + /* enter CRC after payload */ + msg[len + 4] = (unsigned char)((crc & 0xff00) >> 8); + msg[len + 5] = (unsigned char)(crc & 0x00ff); + + gpsd_report(LOG_IO, "SiRF: Writing control type %02x:%s\n", msg[4], + gpsd_hexdump_wrapper(msg, len + 8, LOG_IO)); + ok = (write(fd, msg, len + 8) == (ssize_t) (len + 8)); + if (!ok) { + gpsd_report(LOG_WARN, "SiRF: Writing error.\n"); + } + (void)tcdrain(fd); + return (ok); +} + +#ifdef ALLOW_CONTROLSEND +static ssize_t sirf_control_send(struct gps_device_t *session, char *msg, + size_t len) +{ + /*@ +charint +matchanyintegral -initallelements -mayaliasunique @*/ + session->msgbuf[0] = (char)0xa0; + session->msgbuf[1] = (char)0xa2; + session->msgbuf[2] = (len >> 8) & 0xff; + session->msgbuf[3] = len & 0xff; + memcpy(session->msgbuf + 4, msg, len); + session->msgbuf[len + 6] = (char)0xb0; + session->msgbuf[len + 7] = (char)0xb3; + session->msgbuflen = len + 8; + + /* *INDENT-OFF* */ + return sirf_write(session->gpsdata.gps_fd, + (unsigned char *)session->msgbuf) ? (int)session->msgbuflen : -1; + /* *INDENT-ON* */ + /*@ -charint -matchanyintegral +initallelements +mayaliasunique @*/ +} +#endif /* ALLOW_CONTROLSEND */ + +#ifdef ALLOW_RECONFIGURE +static bool sirf_speed(int ttyfd, speed_t speed, char parity, int stopbits) +/* change speed in binary mode */ +{ + /*@ +charint @*/ + static unsigned char msg[] = { + 0xa0, 0xa2, 0x00, 0x09, + 0x86, /* byte 4: + * Set Binary Serial Port + * MID 134 */ + 0x00, 0x00, 0x12, 0xc0, /* bytes 5-8: 4800 bps */ + 0x08, /* byte 9: 8 data bits */ + 0x01, /* byte 10: 1 stop bit */ + 0x00, /* byte 11: no parity */ + 0x00, /* byte 12: reserved pad */ + 0x00, 0x00, 0xb0, 0xb3 + }; + /*@ -charint @*/ + gpsd_report(LOG_PROG, "SiRF: sirf_speed(%d,%c,%d)\n", + speed, parity, stopbits); + if (9600 > speed) { + gpsd_report(LOG_WARN, "NTPD: SiRF may lag at less than 9600bps\n"); + } + + switch (parity) { + case 'E': + case 2: + parity = (char)2; + break; + case 'O': + case 1: + parity = (char)1; + break; + case 'N': + case 0: + default: + parity = (char)0; + break; + } + msg[7] = (unsigned char)HI(speed); + msg[8] = (unsigned char)LO(speed); + msg[10] = (unsigned char)stopbits; + msg[11] = (unsigned char)parity; + return (sirf_write(ttyfd, msg)); +} + +static bool sirf_to_nmea(int ttyfd, speed_t speed) +/* switch from binary to NMEA at specified baud */ +{ + /*@ +charint @*/ + static unsigned char msg[] = { 0xa0, 0xa2, 0x00, 0x18, + 0x81, 0x02, + 0x01, 0x01, /* GGA */ + 0x00, 0x00, /* suppress GLL */ + 0x01, 0x01, /* GSA */ + 0x05, 0x01, /* GSV */ + 0x01, 0x01, /* RMC */ + 0x00, 0x00, /* suppress VTG */ + 0x00, 0x01, /* suppress MSS */ + 0x00, 0x01, /* suppress EPE */ + 0x00, 0x01, /* suppress EPE */ + 0x00, 0x01, /* suppress ZDA */ + 0x00, 0x00, /* unused */ + 0x12, 0xc0, /* 4800 bps */ + 0xb0, 0xb3 + }; + /*@ -charint @*/ + + msg[26] = (unsigned char)HI(speed); + msg[27] = (unsigned char)LO(speed); + return (sirf_write(ttyfd, msg)); +} + +static void sirfbin_mode(struct gps_device_t *session, int mode) +{ + char parity = '0'; + if (mode == MODE_NMEA) { + (void)sirf_to_nmea(session->gpsdata.gps_fd, + session->gpsdata.dev.baudrate); + } else if (mode == MODE_BINARY) { + switch (session->gpsdata.dev.parity) { + default: + case 'N': + parity = '0'; + break; + case 'O': + parity = '1'; + break; + case 'E': + parity = '2'; + break; + + } + // gpsd only supports 8[NO]1 or 7[EO]2 + // thus the strange us of stopbits + (void)nmea_send(session, + "$PSRF100,0,%d,%d,%d,%c", + session->gpsdata.dev.baudrate, + 9 - session->gpsdata.dev.stopbits, + session->gpsdata.dev.stopbits, parity); + (void)usleep(333); /* guessed settling time */ + session->gpsdata.dev.driver_mode = MODE_BINARY; + } + session->back_to_nmea = false; +} +#endif /* ALLOW_RECONFIGURE */ + +static ssize_t sirf_get(struct gps_device_t *session) +{ + ssize_t len = generic_get(session); + + if (session->packet.type == SIRF_PACKET) { + session->gpsdata.dev.driver_mode = MODE_BINARY; + } else if (session->packet.type == NMEA_PACKET) { + session->gpsdata.dev.driver_mode = MODE_NMEA; + (void)gpsd_switch_driver(session, "Generic NMEA"); + } else { + /* should never happen */ + gpsd_report(LOG_PROG, "SiRF: Unexpected packet type %d\n", + session->packet.type); + (void)gpsd_switch_driver(session, "Generic NMEA"); + } + + return len; +} + +static gps_mask_t sirf_msg_debug(unsigned char *buf, size_t len) +{ + char msgbuf[MAX_PACKET_LENGTH * 3 + 2]; + int i; + + bzero(msgbuf, (int)sizeof(msgbuf)); + + /*@ +charint @*/ + if (0xe1 == buf[0]) { /* Development statistics messages */ + for (i = 2; i < (int)len; i++) + (void)snprintf(msgbuf + strlen(msgbuf), + sizeof(msgbuf) - strlen(msgbuf), + "%c", buf[i] ^ 0xff); + gpsd_report(LOG_PROG, "SiRF: DEV 0xe1: %s\n", msgbuf); + } else if (0xff == (unsigned char)buf[0]) { /* Debug messages */ + for (i = 1; i < (int)len; i++) + if (isprint(buf[i])) + (void)snprintf(msgbuf + strlen(msgbuf), + sizeof(msgbuf) - strlen(msgbuf), "%c", buf[i]); + else + (void)snprintf(msgbuf + strlen(msgbuf), + sizeof(msgbuf) - strlen(msgbuf), + "\\x%02x", (unsigned int)buf[i]); + gpsd_report(LOG_PROG, "SiRF: DBG 0xff: %s\n", msgbuf); + } + /*@ -charint @*/ + return 0; +} + +static gps_mask_t sirf_msg_errors(unsigned char *buf, size_t len UNUSED) +{ + switch (getbeuw(buf, 1)) { + case 2: + gpsd_report(LOG_PROG, + "SiRF: EID 0x0a type 2: Subframe %u error on PRN %u\n", + getbeul(buf, 9), getbeul(buf, 5)); + break; + + case 4107: + gpsd_report(LOG_PROG, + "SiRF: EID 0x0a type 4107: neither KF nor LSQ fix.\n"); + break; + + default: + gpsd_report(LOG_PROG, "SiRF: EID 0x0a: Error MID %d\n", + getbeuw(buf, 1)); + break; + } + return 0; +} + +/* Navigation Library Measurement Data MID 28 */ +static gps_mask_t sirf_msg_nlmd(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + + double gps_tow = 0.0; + + if (len != 56) + return 0; + + /* oh barf, SiRF claims to be IEEE754 but supports two + * different double orders, neither IEEE754 */ + /* Todo - decode the time, since this is the first MID with a + * good time stamp this will be good for ntpshm time */ + gpsd_report(LOG_PROG, "SiRF: MID 0x1c, NLMD, gps_tow: %f, %s\n", + (double)gps_tow, gpsd_hexdump_wrapper(&gps_tow, 8, LOG_PROG)); + + return 0; +} + +#ifdef ALLOW_RECONFIGURE +static gps_mask_t sirf_msg_swversion(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + double fv; + + if (len < 20) + return 0; + + (void)strlcpy(session->subtype, (char *)buf + 1, + sizeof(session->subtype)); + fv = atof((char *)(buf + 1)); + if (fv < 231) { + session->driver.sirf.driverstate |= SIRF_LT_231; + if (fv > 200) + sirfbin_mode(session, 0); + } else if (fv < 232) { + session->driver.sirf.driverstate |= SIRF_EQ_231; + } else { + gpsd_report(LOG_PROG, "SiRF: Enabling PPS message...\n"); + (void)sirf_write(session->gpsdata.gps_fd, enablemid52); + session->driver.sirf.driverstate |= SIRF_GE_232; + session->context->valid |= LEAP_SECOND_VALID; + } + if (strstr((char *)(buf + 1), "ES")) + gpsd_report(LOG_INF, "SiRF: Firmware has XTrac capability\n"); + gpsd_report(LOG_PROG, "SiRF: fv: %0.2f, Driver state flags are: %0x\n", + fv, session->driver.sirf.driverstate); +#ifdef NTPSHM_ENABLE + session->driver.sirf.time_seen = 0; +#endif /* NTPSHM_ENABLE */ + if (session->gpsdata.dev.baudrate >= 38400) { + gpsd_report(LOG_PROG, "SiRF: Enabling subframe transmission...\n"); + (void)sirf_write(session->gpsdata.gps_fd, enablesubframe); + } + gpsd_report(LOG_DATA, "SiRF: FV 0x06: subtype='%s' mask={DEVICEID}\n", + session->subtype); + return DEVICEID_IS; +} +#endif /* ALLOW_RECONFIGURE */ + +static gps_mask_t sirf_msg_navdata(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + unsigned int i, words[10], chan, svid; + + if (len != 43) + return 0; + + chan = (unsigned int)getub(buf, 1); + svid = (unsigned int)getub(buf, 2); + + for (i = 0; i < 10; i++) { + words[i] = (unsigned int)getbeul(buf, 4 * i + 3); + } + + (void)gpsd_interpret_subframe_raw(session, words); + +#ifdef ALLOW_RECONFIGURE + if (session->gpsdata.dev.baudrate < 38400) { + gpsd_report(LOG_PROG, "SiRF: Disabling subframe transmission...\n"); + (void)sirf_write(session->gpsdata.gps_fd, disablesubframe); + } +#endif /* ALLOW_RECONFIGURE */ + return 0; +} + +#define SIRF_CHANNELS 12 /* max channels allowed in SiRF format */ + +static gps_mask_t sirf_msg_svinfo(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + int st, i, j, cn; + gps_mask_t mask = 0; + + if (len != 188) + return 0; + + gpsd_zero_satellites(&session->gpsdata); + session->context->gps_week = (unsigned short)getbesw(buf, 1); + session->context->gps_tow = (double)getbeul(buf, 3) * 1e-2; + /*@ ignore @*//*@ splint is confused @ */ + session->gpsdata.skyview_time + = + gpstime_to_unix(session->context->gps_week, session->context->gps_tow) + - session->context->leap_seconds; + /*@ end @*/ + for (i = st = 0; i < SIRF_CHANNELS; i++) { + int off = 8 + 15 * i; + bool good; + session->gpsdata.PRN[st] = (int)getub(buf, off); + session->gpsdata.azimuth[st] = + (int)(((unsigned)getub(buf, off + 1) * 3) / 2.0); + session->gpsdata.elevation[st] = + (int)((unsigned)getub(buf, off + 2) / 2.0); + cn = 0; + for (j = 0; j < 10; j++) + cn += (int)getub(buf, off + 5 + j); + + session->gpsdata.ss[st] = (float)(cn / 10.0); + good = session->gpsdata.PRN[st] != 0 && + session->gpsdata.azimuth[st] != 0 && + session->gpsdata.elevation[st] != 0; +#ifdef __UNUSED__ + gpsd_report(LOG_PROG, + "SiRF: PRN=%2d El=%3.2f Az=%3.2f ss=%3d stat=%04x %c\n", + getub(buf, off), + getub(buf, off + 2) / 2.0, + (getub(buf, off + 1) * 3) / 2.0, + cn / 10, getbeuw(buf, off + 3), good ? '*' : ' '); +#endif /* UNUSED */ + if (good != 0) + st += 1; + } + session->gpsdata.satellites_visible = st; +#ifdef NTPSHM_ENABLE + if (st <= 3) { + gpsd_report(LOG_PROG, + "SiRF: NTPD not enough satellites seen: %d\n", st); + } else { + /* SiRF says if 3 sats in view the time is good */ + if (0 == (session->driver.sirf.time_seen & TIME_SEEN_GPS_1)) { + gpsd_report(LOG_RAW, "SiRF: NTPD just seen GPS_1\n"); + } + gpsd_report(LOG_PROG, + "SiRF: NTPD valid time MID 0x04, seen=0x%02x, time:%.2lf, leap:%d\n", + session->driver.sirf.time_seen, + session->gpsdata.skyview_time, + session->context->leap_seconds); + session->driver.sirf.time_seen |= TIME_SEEN_GPS_1; + mask |= TIME_IS; + /* + * This time stamp, at 4800bps, is so close to 1 sec old as to + * be confusing to ntpd, but ntpshm_put() will ignore it if a better + * time already seen + */ + } +#endif /* NTPSHM_ENABLE */ + gpsd_report(LOG_DATA, "SiRF: MTD 0x04: visible=%d mask={SATELLITE}\n", + session->gpsdata.satellites_visible); + return SATELLITE_IS | mask; +} + +#ifdef NTPSHM_ENABLE +static double sirf_ntp_offset(struct gps_device_t *session) +/* return NTP time-offset fudge factor for this device */ +{ + double retval = NAN; + + /* we need to have seen UTC time with a valid leap-year offset */ + if ((session->driver.sirf.time_seen & TIME_SEEN_UTC_2) != 0) { + retval = NAN; + } + + /* the PPS time message */ + else if (strcmp(session->gpsdata.tag, "MID52") == 0) { + retval = 0.3; + } + + /* uBlox EMND message */ + else if (strcmp(session->gpsdata.tag, "MID98") == 0) { + retval = 0.570; + } +#ifdef __UNUSED__ + /* geodetic-data message */ + else if (strcmp(session->gpsdata.tag, "MID41") == 0) { + retval = 0.570; + } +#endif /* __UNUSED__ */ + + /* the Navigation Solution message */ + else if (strcmp(session->gpsdata.tag, "MID2") == 0) { + if (session->sourcetype == source_usb) { + retval = 0.640; /* USB, expect +/- 50mS jitter */ + } else { + switch (session->gpsdata.dev.baudrate) { + default: + retval = 0.704; /* WAG */ + break; + case 4800: + retval = 0.704; /* fudge valid at 4800bps */ + break; + case 9600: + retval = 0.688; + break; + case 19200: + retval = 0.484; + break; + case 38400: + retval = 0.845; /* 0.388; ?? */ + break; + } + } + } + + return retval; +} +#endif /* NTPSHM_ENABLE */ + +static gps_mask_t sirf_msg_navsol(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + int i; + unsigned short navtype; + gps_mask_t mask = 0; + + if (len != 41) + return 0; + + session->gpsdata.satellites_used = (int)getub(buf, 28); + memset(session->gpsdata.used, 0, sizeof(session->gpsdata.used)); + for (i = 0; i < SIRF_CHANNELS; i++) + session->gpsdata.used[i] = (int)getub(buf, 29 + i); + /* position/velocity is bytes 1-18 */ + ecef_to_wgs84fix(&session->newdata, &session->gpsdata.separation, + getbesl(buf, 1) * 1.0, getbesl(buf, 5) * 1.0, + getbesl(buf, 9) * 1.0, getbesw(buf, 13) / 8.0, + getbesw(buf, 15) / 8.0, getbesw(buf, 17) / 8.0); + /* fix status is byte 19 */ + navtype = (unsigned short)getub(buf, 19); + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + if ((navtype & 0x80) != 0) + session->gpsdata.status = STATUS_DGPS_FIX; + else if ((navtype & 0x07) > 0 && (navtype & 0x07) < 7) + session->gpsdata.status = STATUS_FIX; + if ((navtype & 0x07) == 4 || (navtype & 0x07) == 6) + session->newdata.mode = MODE_3D; + else if (session->gpsdata.status != 0) + session->newdata.mode = MODE_2D; + if (session->newdata.mode == MODE_3D) + mask |= ALTITUDE_IS | CLIMB_IS; + gpsd_report(LOG_PROG, + "SiRF: MND 0x02: Navtype = 0x%0x, Status = %d, mode = %d\n", + navtype, session->gpsdata.status, session->newdata.mode); + /* byte 20 is HDOP, see below */ + /* byte 21 is "mode 2", not clear how to interpret that */ + session->context->gps_week = (unsigned short)getbesw(buf, 22); + session->context->gps_tow = (double)getbeul(buf, 24) * 1e-2; + /*@ ignore @*//*@ splint is confused @ */ + session->newdata.time = + gpstime_to_unix(session->context->gps_week, + session->context->gps_tow) - + session->context->leap_seconds; + /*@ end @*/ +#ifdef NTPSHM_ENABLE + if (session->newdata.mode <= MODE_NO_FIX) { + gpsd_report(LOG_PROG, "SiRF: NTPD no fix, mode: %d\n", + session->newdata.mode); + } else { + if (0 == (session->driver.sirf.time_seen & TIME_SEEN_GPS_2)) { + gpsd_report(LOG_PROG, "SiRF: NTPD SEEN_GPS_2\n"); + } + gpsd_report(LOG_PROG, + "SiRF: NTPD valid time MID 0x02, seen=0x%02x, time;%.2lf, leap:%d\n", + session->driver.sirf.time_seen, + session->newdata.time, session->context->leap_seconds); + session->driver.sirf.time_seen |= TIME_SEEN_GPS_2; + } +#endif /* NTPSHM_ENABLE */ + /* fix quality data */ + session->gpsdata.dop.hdop = (double)getub(buf, 20) / 5.0; + mask |= + TIME_IS | LATLON_IS | ALTITUDE_IS | TRACK_IS | SPEED_IS | STATUS_IS | + MODE_IS | DOP_IS | USED_IS; + gpsd_report(LOG_DATA, + "SiRF: MND 0x02: time=%.2f lat=%.2f lon=%.2f alt=%.2f track=%.2f speed=%.2f mode=%d status=%d hdop=%.2f used=%d mask=%s\n", + session->newdata.time, session->newdata.latitude, + session->newdata.longitude, session->newdata.altitude, + session->newdata.track, session->newdata.speed, + session->newdata.mode, session->gpsdata.status, + session->gpsdata.dop.hdop, session->gpsdata.satellites_used, + gpsd_maskdump(mask)); + return mask; +} + +#ifdef __UNUSED__ +/*************************************************************************** + We've stopped interpreting GND (0x29) for the following reasons: + +1) Versions of SiRF firmware still in wide circulation (and likely to be + so for a while) don't report a valid time field, leading to annoying + twice-per-second jitter in client displays. + +2) What we wanted out of this that MND didn't give us was horizontal and + vertical error estimates. But we have to do our own error estimation by + computing DOPs from the skyview covariance matrix anyway, because we + want separate epx and epy errors a la NMEA 3.0. + +3) The fix-merge logic in gpsd.c is (unavoidably) NMEA-centric and + thinks multiple sentences in one cycle should be treated as + incremental updates. This leads to various silly results when (as + in GND) a subsequent sentence is (a) intended to be a complete fix + in itself, and (b) frequently broken. + +4) Ignoring this dodgy sentence allows us to go to a nice clean single + fix update per cycle. + +Code left in place in case we need to reverse this decision. + +***************************************************************************/ +static gps_mask_t sirf_msg_geodetic(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + unsigned short navtype; + gps_mask_t mask = 0; + double eph; + + if (len != 91) + return 0; + + session->gpsdata.sentence_length = 91; + (void)strlcpy(session->gpsdata.tag, "GND", MAXTAGLEN + 1); + + navtype = (unsigned short)getbeuw(buf, 3); + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + if (navtype & 0x80) + session->gpsdata.status = STATUS_DGPS_FIX; + else if ((navtype & 0x07) > 0 && (navtype & 0x07) < 7) + session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_NO_FIX; + if ((navtype & 0x07) == 4 || (navtype & 0x07) == 6) + session->newdata.mode = MODE_3D; + else if (session->gpsdata.status) + session->newdata.mode = MODE_2D; + gpsd_report(LOG_PROG, + "SiRF: GND 0x29: Navtype = 0x%0x, Status = %d, mode = %d\n", + navtype, session->gpsdata.status, session->newdata.mode); + mask |= STATUS_IS | MODE_IS; + + session->newdata.latitude = getbesl(buf, 23) * 1e-7; + session->newdata.longitude = getbesl(buf, 27) * 1e-7; + if (session->newdata.latitude != 0 && session->newdata.latitude != 0) + mask |= LATLON_IS; + + if ((eph = getbesl(buf, 50) * 1e-2) > 0) { + session->newdata.epx = session->newdata.epy = eph / sqrt(2); + mask |= HERR_IS; + } + if ((session->newdata.epv = getbesl(buf, 54) * 1e-2) > 0) + mask |= VERR_IS; + if ((session->newdata.eps = getbesw(buf, 62) * 1e-2) > 0) + mask |= SPEEDERR_IS; + + /* HDOP should be available at byte 89, but in 231 it's zero. */ + //session->gpsdata.dop.hdop = (unsigned int)getub(buf, 89) * 0.2; + + if ((session->newdata.mode > MODE_NO_FIX) + && (session->driver.sirf.driverstate & SIRF_GE_232)) { + struct tm unpacked_date; + double subseconds; + /* + * Early versions of the SiRF protocol manual don't document + * this sentence at all. Some that do incorrectly + * describe UTC Day, Hour, and Minute as 2-byte quantities, + * not 1-byte. Chris Kuethe, our SiRF expert, tells us: + * + * "The Geodetic Navigation packet (0x29) was not fully + * implemented in firmware prior to version 2.3.2. So for + * anyone running 231.000.000 or earlier (including ES, + * SiRFDRive, XTrac trains) you won't get UTC time. I don't + * know what's broken in firmwares before 2.3.1..." + * + * To work around the incomplete implementation of this + * packet in 231, we used to assume that only the altitude field + * from this packet is valid. But even this doesn't necessarily + * seem to be the case. Instead, we do our own computation + * of geoid separation now. + * + * UTC is left all zeros in 231 and older firmware versions, + * and misdocumented in version 1.4 of the Protocol Reference. + * Documented: Real: + * UTC year 2 2 + * UTC month 1 1 + * UTC day 2 1 + * UTC hour 2 1 + * UTC minute 2 1 + * UTC second 2 2 + * 11 8 + * + * Documentation of this field was corrected in the 1.6 version + * of the protocol manual. + */ + unpacked_date.tm_year = (int)getbeuw(buf, 11) - 1900; + unpacked_date.tm_mon = (int)getub(buf, 13) - 1; + unpacked_date.tm_mday = (int)getub(buf, 14); + unpacked_date.tm_hour = (int)getub(buf, 15); + unpacked_date.tm_min = (int)getub(buf, 16); + unpacked_date.tm_sec = 0; + subseconds = getbeuw(buf, 17) * 1e-3; + /*@ -compdef -unrecog */ + session->newdata.time = (double)timegm(&unpacked_date) + subseconds; + /*@ +compdef +unrecog */ + gpsd_report(LOG_PROG, "SiRF: GND 0x29 UTC: %lf\n", + session->newdata.time); +#ifdef NTPSHM_ENABLE + if (session->newdata.mode <= MODE_NO_FIX) { + gpsd_report(LOG_PROG, "SiRF: NTPD no fix, mode: $d\n", + session->newdata.mode); + } else if (0 == unpacked_date.tm_year) { + gpsd_report(LOG_PROG, "SiRF: NTPD no year\n", + session->newdata.mode); + } else { + if (0 == (session->driver.sirf.time_seen & TIME_SEEN_UTC_1)) { + gpsd_report(LOG_RAW, "SiRF: NTPD just SEEN_UTC 1\n"); + } + gpsd_report(LOG_PROG, + "SiRF: NTPD valid time MID 0x29, seen=0x%02x\n", + session->driver.sirf.time_seen); + session->driver.sirf.time_seen |= TIME_SEEN_UTC_1; + } + +#endif /* NTPSHM_ENABLE */ + /* skip 4 bytes of satellite map */ + session->newdata.altitude = getbesl(buf, 35) * 1e-2; + /* skip 1 byte of map datum */ + session->newdata.speed = getbeuw(buf, 40) * 1e-2; + session->newdata.track = getbeuw(buf, 42) * 1e-2; + /* skip 2 bytes of magnetic variation */ + session->newdata.climb = getbesw(buf, 46) * 1e-2; + mask |= TIME_IS | SPEED_IS | TRACK_IS; + if (session->newdata.mode == MODE_3D) + mask |= ALTITUDE_IS | CLIMB_IS; + } + gpsd_report(LOG_DATA, + "SiRF: GND 0x29: time=%.2f lat=%.2f lon=%.2f alt=%.2f track=%.2f speed=%.2f mode=%d status=%d mask=%s\n", + session->newdata.time, + session->newdata.latitude, + session->newdata.longitude, + session->newdata.altitude, + session->newdata.track, + session->newdata.speed, + session->newdata.mode, + session->gpsdata.status, gpsd_maskdump(mask)); + return mask; +} +#endif /* __UNUSED__ */ + +#ifdef ALLOW_RECONFIGURE +static gps_mask_t sirf_msg_sysparam(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + + if (len != 65) + return 0; + + /* save these to restore them in the revert method */ + session->driver.sirf.nav_parameters_seen = true; + session->driver.sirf.altitude_hold_mode = (unsigned char)getub(buf, 5); + session->driver.sirf.altitude_hold_source = (unsigned char)getub(buf, 6); + session->driver.sirf.altitude_source_input = getbesw(buf, 7); + session->driver.sirf.degraded_mode = (unsigned char)getub(buf, 9); + session->driver.sirf.degraded_timeout = (unsigned char)getub(buf, 10); + session->driver.sirf.dr_timeout = (unsigned char)getub(buf, 11); + session->driver.sirf.track_smooth_mode = (unsigned char)getub(buf, 12); + gpsd_report(LOG_PROG, "SiRF: Setting Navigation Parameters\n"); + (void)sirf_write(session->gpsdata.gps_fd, modecontrol); + return 0; +} +#endif /* ALLOW_RECONFIGURE */ + +static gps_mask_t sirf_msg_ublox(struct gps_device_t *session, + unsigned char *buf, size_t len UNUSED) +{ + gps_mask_t mask; + unsigned short navtype; + + if (len != 39) + return 0; + + /* this packet is only sent by uBlox firmware from version 1.32 */ + mask = LATLON_IS | ALTITUDE_IS | SPEED_IS | TRACK_IS | CLIMB_IS | + STATUS_IS | MODE_IS | DOP_IS; + session->newdata.latitude = getbesl(buf, 1) * RAD_2_DEG * 1e-8; + session->newdata.longitude = getbesl(buf, 5) * RAD_2_DEG * 1e-8; + session->gpsdata.separation = + wgs84_separation(session->newdata.latitude, + session->newdata.longitude); + session->newdata.altitude = + getbesl(buf, 9) * 1e-3 - session->gpsdata.separation; + session->newdata.speed = getbesl(buf, 13) * 1e-3; + session->newdata.climb = getbesl(buf, 17) * 1e-3; + session->newdata.track = getbesl(buf, 21) * RAD_2_DEG * 1e-8; + + navtype = (unsigned short)getub(buf, 25); + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + if (navtype & 0x80) + session->gpsdata.status = STATUS_DGPS_FIX; + else if ((navtype & 0x07) > 0 && (navtype & 0x07) < 7) + session->gpsdata.status = STATUS_FIX; + if ((navtype & 0x07) == 4 || (navtype & 0x07) == 6) + session->newdata.mode = MODE_3D; + else if (session->gpsdata.status) + session->newdata.mode = MODE_2D; + gpsd_report(LOG_PROG, + "SiRF: EMND 0x62: Navtype = 0x%0x, Status = %d, mode = %d\n", + navtype, session->gpsdata.status, session->newdata.mode); + + if (navtype & 0x40) { /* UTC corrected timestamp? */ + struct tm unpacked_date; + double subseconds; + mask |= TIME_IS; + unpacked_date.tm_year = (int)getbeuw(buf, 26) - 1900; + unpacked_date.tm_mon = (int)getub(buf, 28) - 1; + unpacked_date.tm_mday = (int)getub(buf, 29); + unpacked_date.tm_hour = (int)getub(buf, 30); + unpacked_date.tm_min = (int)getub(buf, 31); + unpacked_date.tm_sec = 0; + subseconds = ((unsigned short)getbeuw(buf, 32)) * 1e-3; + /*@ -compdef */ + session->newdata.time = (double)mkgmtime(&unpacked_date) + subseconds; + /*@ +compdef */ +#ifdef NTPSHM_ENABLE + if (0 == (session->driver.sirf.time_seen & TIME_SEEN_UTC_2)) { + gpsd_report(LOG_RAW, "SiRF: NTPD just SEEN_UTC_2\n"); + } + gpsd_report(LOG_PROG, + "SiRF: NTPD valid time MID 0x62, seen=0x%02x\n", + session->driver.sirf.time_seen); + session->driver.sirf.time_seen |= TIME_SEEN_UTC_2; +#endif /* NTPSHM_ENABLE */ + session->context->valid |= LEAP_SECOND_VALID; + } + + session->gpsdata.dop.gdop = (int)getub(buf, 34) / 5.0; + session->gpsdata.dop.pdop = (int)getub(buf, 35) / 5.0; + session->gpsdata.dop.hdop = (int)getub(buf, 36) / 5.0; + session->gpsdata.dop.vdop = (int)getub(buf, 37) / 5.0; + session->gpsdata.dop.tdop = (int)getub(buf, 38) / 5.0; + session->driver.sirf.driverstate |= UBLOX; + gpsd_report(LOG_DATA, + "SiRF: EMD 0x62: time=%.2f lat=%.2f lon=%.2f alt=%.f speed=%.2f track=%.2f climb=%.2f mode=%d status=%d gdop=%.2f pdop=%.2f hdop=%.2f vdop=%.2f tdop=%.2f mask=%s\n", + session->newdata.time, session->newdata.latitude, + session->newdata.longitude, session->newdata.altitude, + session->newdata.speed, session->newdata.track, + session->newdata.climb, session->newdata.mode, + session->gpsdata.status, session->gpsdata.dop.gdop, + session->gpsdata.dop.pdop, session->gpsdata.dop.hdop, + session->gpsdata.dop.vdop, session->gpsdata.dop.tdop, + gpsd_maskdump(mask)); + return mask; +} + +static gps_mask_t sirf_msg_ppstime(struct gps_device_t *session, + unsigned char *buf, size_t len) +{ + gps_mask_t mask = 0; + + if (len != 19) + return 0; + + gpsd_report(LOG_PROG, "SiRF: PPS 0x34: Status = 0x%02x\n", + getub(buf, 14)); + if (((int)getub(buf, 14) & 0x07) == 0x07) { /* valid UTC time? */ + struct tm unpacked_date; + unpacked_date.tm_hour = (int)getub(buf, 1); + unpacked_date.tm_min = (int)getub(buf, 2); + unpacked_date.tm_sec = (int)getub(buf, 3); + unpacked_date.tm_mday = (int)getub(buf, 4); + unpacked_date.tm_mon = (int)getub(buf, 5) - 1; + unpacked_date.tm_year = (int)getbeuw(buf, 6) - 1900; + /*@ -compdef */ + session->newdata.time = (double)mkgmtime(&unpacked_date); + /*@ +compdef */ + session->context->leap_seconds = (int)getbeuw(buf, 8); + if (LEAP_SECONDS > session->context->leap_seconds) { + /* something wrong */ + gpsd_report(LOG_ERROR, "SiRF: Invalid leap_seconds: %d\n", + session->context->leap_seconds); + session->context->leap_seconds = LEAP_SECONDS; + session->context->valid &= ~LEAP_SECOND_VALID; + } else { + session->context->valid |= LEAP_SECOND_VALID; + } +#ifdef NTPSHM_ENABLE + if (0 == (session->driver.sirf.time_seen & TIME_SEEN_UTC_2)) { + gpsd_report(LOG_RAW, "SiRF: NTPD just SEEN_UTC_2\n"); + } + gpsd_report(LOG_PROG, + "SiRF: NTPD valid time MID 0x34, seen=0x%02x\n", + session->driver.sirf.time_seen); + session->driver.sirf.time_seen |= TIME_SEEN_UTC_2; +#endif /* NTPSHM_ENABLE */ + mask |= TIME_IS; + } + return mask; +} + +gps_mask_t sirf_parse(struct gps_device_t * session, unsigned char *buf, + size_t len) +{ + + if (len == 0) + return 0; + + buf += 4; + len -= 8; + gpsd_report(LOG_RAW, "SiRF: Raw packet type 0x%02x length %zd: %s\n", + buf[0], len, gpsd_hexdump_wrapper(buf, len, LOG_RAW)); + (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), + "MID%d", (int)buf[0]); + + /* could change if the set of messages we enable does */ + session->cycle_end_reliable = true; + + switch (buf[0]) { + case 0x02: /* Measure Navigation Data Out MID 2 */ + if ((session->driver.sirf.driverstate & UBLOX) == 0) + return sirf_msg_navsol(session, buf, + len) | (CLEAR_IS | REPORT_IS); + else { + gpsd_report(LOG_PROG, + "SiRF: MND 0x02 skipped, uBlox flag is on.\n"); + return 0; + } + case 0x04: /* Measured tracker data out MID 4 */ + return sirf_msg_svinfo(session, buf, len); + + case 0x05: /* Raw Tracker Data Out MID 5 */ + gpsd_report(LOG_PROG, "SiRF: unused Raw Tracker Data 0x05\n"); + return 0; + +#ifdef ALLOW_RECONFIGURE + case 0x06: /* Software Version String MID 6 */ + return sirf_msg_swversion(session, buf, len); +#endif /* ALLOW_RECONFIGURE */ + + case 0x07: /* Clock Status Data MID 7 */ + gpsd_report(LOG_PROG, "SiRF: unused CLK 0x07\n"); + return 0; + + case 0x08: /* subframe data MID 8 */ + /* extract leap-second from this */ + /* + * Chris Kuethe says: + * "Message 8 is generated as the data is received. It is not + * buffered on the chip. So when you enable message 8, you'll + * get one subframe every 6 seconds. Of the data received, the + * almanac and ephemeris are buffered and stored, so you can + * query them at will. Alas, the time parameters are not + * stored, which is really lame, as the UTC-GPS correction + * changes 1 second every few years. Maybe." + */ + return sirf_msg_navdata(session, buf, len); + + case 0x09: /* CPU Throughput MID 9 */ + gpsd_report(LOG_PROG, + "SiRF: THR 0x09: SegStatMax=%.3f, SegStatLat=%3.f, AveTrkTime=%.3f, Last MS=%u\n", + (float)getbeuw(buf, 1) / 186, (float)getbeuw(buf, + 3) / 186, + (float)getbeuw(buf, 5) / 186, getbeuw(buf, 7)); + return 0; + + case 0x0a: /* Error ID Data MID 10 */ + return sirf_msg_errors(buf, len); + + case 0x0b: /* Command Acknowledgement MID 11 */ + gpsd_report(LOG_PROG, "SiRF: ACK 0x0b: %02x\n", getub(buf, 1)); + return 0; + + case 0x0c: /* Command NAcknowledgement MID 12 */ + gpsd_report(LOG_PROG, "SiRF: NAK 0x0c: %02x\n", getub(buf, 1)); + return 0; + + case 0x0d: /* Visible List MID 13 */ + gpsd_report(LOG_PROG, "SiRF: unused VIS 0x0d\n"); + return 0; + + case 0x0e: /* Almanac Data MID 14 */ + gpsd_report(LOG_PROG, "SiRF: unused ALM 0x0e: %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return 0; + + case 0x0f: /* Ephemeris Data MID 15 */ + gpsd_report(LOG_PROG, "SiRF: unused EPH 0x0f: %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return 0; + + case 0x11: /* Differential Corrections MID 17 */ + gpsd_report(LOG_PROG, "SiRF: unused DIFF 0x11: %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return 0; + + case 0x12: /* OK To Send MID 18 */ + gpsd_report(LOG_PROG, "SiRF: OTS 0x12: send indicator = %d\n", + getub(buf, 1)); + return 0; + +#ifdef ALLOW_RECONFIGURE + case 0x13: /* Navigation Parameters MID 19 */ + return sirf_msg_sysparam(session, buf, len); +#endif /* ALLOW_RECONFIGURE */ + + case 0x1b: /* DGPS status (undocumented) MID 27 */ + gpsd_report(LOG_PROG, "SiRF: unused DGPSF 0x1b %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return 0; + + case 0x1c: /* Navigation Library Measurement Data MID 28 */ + gpsd_report(LOG_PROG, "SiRF: NLMD 0x1c: %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return sirf_msg_nlmd(session, buf, len); + + case 0x1d: /* Navigation Library DGPS Data MID 29 */ + gpsd_report(LOG_PROG, "SiRF: unused NLDG 0x1d: %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return 0; + + case 0x1e: /* Navigation Library SV State Data MID 30 */ + gpsd_report(LOG_PROG, "SiRF: unused NLSV 0x1e: %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return 0; + + case 0x1f: /* Navigation Library Initialization Data MID 31 */ + gpsd_report(LOG_PROG, "SiRF: unused NLID 0x1f: %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return 0; + + case 0x29: /* Geodetic Navigation Information MID 41 */ + gpsd_report(LOG_PROG, "SiRF: unused GND 0x29: %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return 0; + + case 0x32: /* SBAS corrections MID 50 */ + gpsd_report(LOG_PROG, "SiRF: unused SBAS 0x32: %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return 0; + + case 0x34: /* PPS Time MID 52 */ + /* + * Carl Carter from SiRF writes: "We do not output on the + * second (unless you are using MID 52). We make + * measurements in the receiver in time with an internal + * counter that is not slaved to GPS time, so the measurements + * are made at a time that wanders around the second. Then, + * after the measurements are made (all normalized to the same + * point in time) we dispatch the navigation software to make + * a solution, and that solution comes out some 200 to 300 ms + * after the measurement time. So you may get a message at + * 700 ms after the second that uses measurements time tagged + * 450 ms after the second. And if some other task jumps up + * and delays things, that message may not come out until 900 + * ms after the second. Things can get out of sync to the + * point that if you try to resolve the GPS time of our 1 PPS + * pulses using the navigation messages, you will find it + * impossible to be consistent. That is why I added + * MID 52 to our system -- it is tied to the creation of the 1 + * PPS and always comes out right around the top of the + * second." + */ + return sirf_msg_ppstime(session, buf, len); + + case 0x62: /* uBlox Extended Measured Navigation Data MID 98 */ + gpsd_report(LOG_PROG, "SiRF: uBlox EMND 0x62: %s.\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return sirf_msg_ublox(session, buf, len) | (CLEAR_IS | REPORT_IS); + + case 0x80: /* Initialize Data Source MID 128 */ + gpsd_report(LOG_PROG, "SiRF: unused INIT 0x80: %s\n", + gpsd_hexdump_wrapper(buf, len, LOG_PROG)); + return 0; + + case 0xe1: /* Development statistics messages MID 225 */ + /* FALLTHROUGH */ + case 0xff: /* Debug messages MID 255 */ + (void)sirf_msg_debug(buf, len); + return 0; + + default: + gpsd_report(LOG_WARN, "SiRF: Unknown packet id %d length %zd: %s\n", + buf[0], len, gpsd_hexdump_wrapper(buf, len, LOG_WARN)); + return 0; + } +} + +static gps_mask_t sirfbin_parse_input(struct gps_device_t *session) +{ + gps_mask_t st; + + if (session->packet.type == SIRF_PACKET) { + st = sirf_parse(session, session->packet.outbuffer, + session->packet.outbuflen); + session->gpsdata.dev.driver_mode = MODE_BINARY; + return st; +#ifdef NMEA_ENABLE + } else if (session->packet.type == NMEA_PACKET) { + st = nmea_parse((char *)session->packet.outbuffer, session); + session->gpsdata.dev.driver_mode = MODE_NMEA; + return st; +#endif /* NMEA_ENABLE */ + } else + return 0; +} + +static void sirfbin_event_hook(struct gps_device_t *session, event_t event) +{ + if (event == event_identified || event == event_reactivate) { + if (session->packet.type == NMEA_PACKET) { + gpsd_report(LOG_PROG, "SiRF: Switching chip mode to binary.\n"); + (void)nmea_send(session, + "$PSRF100,0,%d,8,1,0", + session->gpsdata.dev.baudrate); + } + /* do this every time */ + { + /*@ +charint @*/ + /* Poll Navigation Parameters MID 152 + * query for MID 19 */ + static unsigned char navparams[] = { + 0xa0, 0xa2, 0x00, 0x02, + 0x98, /* MID 152 */ + 0x00, + 0x00, 0x00, 0xb0, 0xb3 + }; + /* DGPS Source MID 133 */ + static unsigned char dgpscontrol[] = { + 0xa0, 0xa2, 0x00, 0x07, + 0x85, /* MID 133 */ + 0x01, /* use SBAS */ + 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb0, 0xb3 + }; + /* Set SBAS Parameters MID 170 */ + static unsigned char sbasparams[] = { + 0xa0, 0xa2, 0x00, 0x06, + 0xaa, /* MID 170 */ + 0x00, /* SBAS PRN */ + 0x01, /* SBAS Mode */ + 0x00, /* Auto PRN */ + 0x00, 0x00, + 0x00, 0x00, 0xb0, 0xb3 + }; + /* Poll Software Version MID 132 */ + static unsigned char versionprobe[] = { + 0xa0, 0xa2, 0x00, 0x02, + 0x84, /* MID 132 */ + 0x00, /* unused */ + 0x00, 0x00, 0xb0, 0xb3 + }; + /* Set Message Rate MID 166 */ + static unsigned char requestecef[] = { + 0xa0, 0xa2, 0x00, 0x08, + 0xa6, /* MID 166 */ + 0x00, /* enable 1 */ + 0x02, /* MID 2 */ + 0x01, /* once per Sec */ + 0x00, 0x00, /* unused */ + 0x00, 0x00, /* unused */ + 0x00, 0x00, 0xb0, 0xb3 + }; + /* Set Message Rate MID 166 */ + static unsigned char requesttracker[] = { + 0xa0, 0xa2, 0x00, 0x08, + 0xa6, /* MID 166 */ + 0x00, /* enable 1 */ + 0x04, /* MID 4 */ + 0x03, /* every 3 sec */ + 0x00, 0x00, /* unused */ + 0x00, 0x00, /* unused */ + 0x00, 0x00, 0xb0, 0xb3 + }; + /* unset MID 29 0x1d */ + /* we do not decode it, so don't send it */ + static unsigned char unsetmid29[] = { + 0xa0, 0xa2, 0x00, 0x08, + 0xa6, /* MID 166 */ + 0x00, /* enable 1 */ + 0x1d, /* MID 29 */ + 0x00, /* never */ + 0x00, 0x00, /* unused */ + 0x00, 0x00, /* unused */ + 0x00, 0x00, 0xb0, 0xb3 + }; + /* unset MID 30 0x1e */ + /* we do not decode it, so don't send it */ + static unsigned char unsetmid30[] = { + 0xa0, 0xa2, 0x00, 0x08, + 0xa6, /* MID 166 */ + 0x00, /* enable 1 */ + 0x1e, /* MID 30 */ + 0x00, /* never */ + 0x00, 0x00, /* unused */ + 0x00, 0x00, /* unused */ + 0x00, 0x00, 0xb0, 0xb3 + }; + /*@ -charint @*/ + + gpsd_report(LOG_PROG, "SiRF: baudrate: %d\n", + session->gpsdata.dev.baudrate); + (void)usleep(3330); /* guessed settling time */ + gpsd_report(LOG_PROG, "SiRF: unset MID 30...\n"); + (void)sirf_write(session->gpsdata.gps_fd, unsetmid30); + (void)usleep(3330); /* guessed settling time */ + + gpsd_report(LOG_PROG, + "SiRF: Requesting periodic ecef reports...\n"); + (void)sirf_write(session->gpsdata.gps_fd, requestecef); + gpsd_report(LOG_PROG, + "SiRF: Requesting periodic tracker reports...\n"); + (void)sirf_write(session->gpsdata.gps_fd, requesttracker); + gpsd_report(LOG_PROG, + "SiRF: Setting DGPS control to use SBAS...\n"); + (void)sirf_write(session->gpsdata.gps_fd, dgpscontrol); + gpsd_report(LOG_PROG, + "SiRF: Setting SBAS to auto/integrity mode...\n"); + (void)sirf_write(session->gpsdata.gps_fd, sbasparams); + + gpsd_report(LOG_PROG, "SiRF: unset MID 29...\n"); + (void)sirf_write(session->gpsdata.gps_fd, unsetmid29); + + gpsd_report(LOG_PROG, "SiRF: Probing for firmware version...\n"); + (void)sirf_write(session->gpsdata.gps_fd, versionprobe); + gpsd_report(LOG_PROG, + "SiRF: Requesting navigation parameters...\n"); + (void)sirf_write(session->gpsdata.gps_fd, navparams); + } + } + if (event == event_deactivate) { + + /*@ +charint @*/ + static unsigned char moderevert[] = { 0xa0, 0xa2, 0x00, 0x0e, + 0x88, + 0x00, 0x00, /* pad bytes */ + 0x00, /* degraded mode */ + 0x00, 0x00, /* pad bytes */ + 0x00, 0x00, /* altitude source */ + 0x00, /* altitude hold mode */ + 0x00, /* use last computed alt */ + 0x00, /* reserved */ + 0x00, /* degraded mode timeout */ + 0x00, /* dead reckoning timeout */ + 0x00, /* track smoothing */ + 0x00, 0x00, 0xb0, 0xb3 + }; + /*@ -charint -shiftimplementation @*/ + putbyte(moderevert, 7, session->driver.sirf.degraded_mode); + putbeword(moderevert, 10, session->driver.sirf.altitude_source_input); + putbyte(moderevert, 12, session->driver.sirf.altitude_hold_mode); + putbyte(moderevert, 13, session->driver.sirf.altitude_hold_source); + putbyte(moderevert, 15, session->driver.sirf.degraded_timeout); + putbyte(moderevert, 16, session->driver.sirf.dr_timeout); + putbyte(moderevert, 17, session->driver.sirf.track_smooth_mode); + /*@ +shiftimplementation @*/ + gpsd_report(LOG_PROG, "SiRF: Reverting navigation parameters...\n"); + (void)sirf_write(session->gpsdata.gps_fd, moderevert); + } +} + +#ifdef ALLOW_RECONFIGURE +static bool sirfbin_speed(struct gps_device_t *session, + speed_t speed, char parity, int stopbits) +{ + return sirf_speed(session->gpsdata.gps_fd, speed, parity, stopbits); +} +#endif /* ALLOW_RECONFIGURE */ + +/* this is everything we export */ +/* *INDENT-OFF* */ +const struct gps_type_t sirf_binary = +{ + .type_name = "SiRF binary", /* full name of type */ + .packet_type = SIRF_PACKET, /* associated lexer packet type */ + .trigger = NULL, /* no trigger */ + .channels = SIRF_CHANNELS, /* consumer-grade GPS */ + .probe_detect = NULL, /* no probe */ + .get_packet = sirf_get, /* be prepared for SiRF or NMEA */ + .parse_packet = sirfbin_parse_input,/* parse message packets */ + .rtcm_writer = pass_rtcm, /* send RTCM data straight */ + .event_hook = sirfbin_event_hook,/* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = sirfbin_speed, /* we can change baud rate */ + .mode_switcher = sirfbin_mode, /* there's a mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = sirf_control_send,/* how to send a control string */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = sirf_ntp_offset, +#endif /* NTP_SHM_ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* defined(SIRF_ENABLE) && defined(BINARY_ENABLE) */ diff --git a/driver_superstar2.c b/driver_superstar2.c new file mode 100644 index 0000000..03bab59 --- /dev/null +++ b/driver_superstar2.c @@ -0,0 +1,617 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include + +#include "gpsd_config.h" + +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include + +#include "gpsd.h" + +#if defined(SUPERSTAR2_ENABLE) && defined(BINARY_ENABLE) +#include "bits.h" +#include "driver_superstar2.h" + +/* + * These routines are specific to this driver + */ + +static gps_mask_t superstar2_parse_input(struct gps_device_t *); +static gps_mask_t superstar2_dispatch(struct gps_device_t *, + unsigned char *, size_t); +static gps_mask_t superstar2_msg_ack(struct gps_device_t *, + unsigned char *, size_t); +static gps_mask_t superstar2_msg_navsol_lla(struct gps_device_t *, + unsigned char *, size_t); +static gps_mask_t superstar2_msg_timing(struct gps_device_t *, + unsigned char *, size_t); +static gps_mask_t superstar2_msg_svinfo(struct gps_device_t *, + unsigned char *, size_t); +static gps_mask_t superstar2_msg_iono_utc(struct gps_device_t *, + unsigned char *, size_t); +static gps_mask_t superstar2_msg_ephemeris(struct gps_device_t *, + unsigned char *, size_t); + +/* + * These methods may be called elsewhere in gpsd + */ +static ssize_t superstar2_control_send(struct gps_device_t *, char *, size_t); +static void superstar2_event_hook(struct gps_device_t *, event_t); +static bool superstar2_set_speed(struct gps_device_t *, speed_t, char, int); +static void superstar2_set_mode(struct gps_device_t *, int); +static ssize_t superstar2_write(struct gps_device_t *, char *, size_t); + + +/* + * Decode the message ACK message + */ +static gps_mask_t +superstar2_msg_ack(struct gps_device_t *session UNUSED, + unsigned char *buf, size_t data_len) +{ + if (data_len == 11) + gpsd_report(LOG_PROG, + "superstar2 #126 - " + "ACK %d %d %d %d %d\n", + buf[5], buf[6], buf[7], buf[8], buf[9]); + return 0; +} + +/* + * Decode the navigation solution message. The ECEF version is intentionally + * unhandled. By suppressing evaluation of it, we gain the desirable feature + * that the fix update is atomic and exactly once per cycle. + */ + + +static gps_mask_t +superstar2_msg_navsol_lla(struct gps_device_t *session, + unsigned char *buf, size_t data_len) +{ + gps_mask_t mask; + unsigned char flags; + union int_float i_f; + union long_double l_d; + double d; + struct tm tm; + + if (data_len != 77) + return 0; + + gpsd_report(LOG_PROG, "superstar2 #20 - user navigation data\n"); + mask = 0; + + /*@ +charint @*/ + flags = (unsigned char)getub(buf, 72); + if ((flags & 0x0f) != 0x03) /* mode 3 is navigation */ + return mask; + /*@ -charint @*/ + + /* extract time data */ + (void)memset(&tm, '\0', sizeof(tm)); + tm.tm_hour = (int)getub(buf, 4) & 0x1f; + tm.tm_min = (int)getub(buf, 5); + d = getled(buf, 6); + tm.tm_sec = (int)d; + tm.tm_mday = (int)getub(buf, 14); + tm.tm_mon = (int)getub(buf, 15) - 1; + tm.tm_year = (int)getleuw(buf, 16) - 1900; + session->newdata.time = timegm(&tm) + (d - tm.tm_sec); + mask |= TIME_IS; + + /* extract the local tangential plane (ENU) solution */ + session->newdata.latitude = getled(buf, 18) * RAD_2_DEG; + session->newdata.longitude = getled(buf, 26) * RAD_2_DEG; + session->newdata.altitude = getlef(buf, 34); + session->newdata.speed = getlef(buf, 38); + session->newdata.track = getlef(buf, 42) * RAD_2_DEG; + session->newdata.climb = getlef(buf, 54); + mask |= LATLON_IS | ALTITUDE_IS | SPEED_IS | TRACK_IS | CLIMB_IS; + + session->gpsdata.satellites_used = (int)getub(buf, 71) & 0x0f; + /*@i3@*/ session->gpsdata.dop.hdop = getleuw(buf, 66) * 0.1; + /*@i3@*/ session->gpsdata.dop.vdop = getleuw(buf, 68) * 0.1; + /* other DOP if available */ + mask |= DOP_IS | USED_IS; + + flags = (unsigned char)getub(buf, 70); + switch (flags & 0x1f) { + case 2: + session->newdata.mode = MODE_3D; + session->gpsdata.status = STATUS_FIX; + break; + case 4: + session->newdata.mode = MODE_3D; + session->gpsdata.status = STATUS_DGPS_FIX; + break; + case 5: + session->newdata.mode = MODE_2D; + session->gpsdata.status = STATUS_DGPS_FIX; + break; + case 3: + case 6: + session->newdata.mode = MODE_2D; + session->gpsdata.status = STATUS_FIX; + break; + default: + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + } + + mask |= MODE_IS | STATUS_IS; + gpsd_report(LOG_DATA, + "NAVSOL_LLA: time=%.2f lat=%.2f lon=%.2f alt=%.2f track=%.2f speed=%.2f climb=%.2f mode=%d status=%d hdop=%.2f hdop=%.2f used=%d mask=%s\n", + session->newdata.time, + session->newdata.latitude, + session->newdata.longitude, + session->newdata.altitude, + session->newdata.track, + session->newdata.speed, + session->newdata.climb, + session->newdata.mode, + session->gpsdata.status, + session->gpsdata.dop.hdop, + session->gpsdata.dop.vdop, + session->gpsdata.satellites_used, gpsd_maskdump(mask)); + return mask; +} + +/** + * GPS Satellite Info + */ +static gps_mask_t +superstar2_msg_svinfo(struct gps_device_t *session, + unsigned char *buf, size_t data_len) +{ + int i, st, nchan, nsv; + + if (data_len != 67) + return 0; + + gpsd_report(LOG_PROG, "superstar2 #33 - satellite data\n"); + + nchan = 12; + gpsd_zero_satellites(&session->gpsdata); + nsv = 0; /* number of actually used satellites */ + for (i = st = 0; i < nchan; i++) { + /* get info for one channel/satellite */ + int off = i * 5 + 5; + unsigned int porn; + if ((porn = (unsigned int)getub(buf, off) & 0x1f) == 0) + porn = (unsigned int)(getub(buf, off + 3) >> 1) + 87; + + session->gpsdata.PRN[i] = (int)porn; + session->gpsdata.ss[i] = (float)getub(buf, off + 4); + session->gpsdata.elevation[i] = (int)getsb(buf, off + 1); + session->gpsdata.azimuth[i] = (unsigned short)getub(buf, off + 2) + + ((unsigned short)(getub(buf, off + 3) & 0x1) << 1); + + /*@ +charint @*/ + if ((getub(buf, off) & 0x60) == 0x60) + session->gpsdata.used[nsv++] = session->gpsdata.PRN[i]; + /*@ -charint @*/ + + if (session->gpsdata.PRN[i]) + st++; + } + session->gpsdata.skyview_time = NAN; + session->gpsdata.satellites_used = nsv; + session->gpsdata.satellites_visible = st; + gpsd_report(LOG_DATA, + "SVINFO: visible=%d used=%d mask={SATELLITE|USED}\n", + session->gpsdata.satellites_visible, + session->gpsdata.satellites_used); + return SATELLITE_IS | USED_IS; +} + +static gps_mask_t +superstar2_msg_version(struct gps_device_t *session, + unsigned char *buf, size_t data_len) +{ +#define SZ 16 + char main_sw[SZ], hw_part[SZ], boot_sw[SZ], ser_num[SZ]; + + /*@ +charint @*/ + /* byte 98 is device type, value = 3 means superstar2 */ + if ((data_len != 101) || ((getub(buf, 98) & 0x0f) != 3)) + return 0; + /*@ -charint @*/ + + (void)snprintf(main_sw, 15, "%s", (char *)buf + 4); + (void)snprintf(hw_part, 15, "%s", (char *)buf + 18); + (void)snprintf(boot_sw, 15, "%s", (char *)buf + 36); + (void)snprintf(ser_num, 14, "%s", (char *)buf + 73); + + gpsd_report(LOG_PROG, + "superstar2 #45 - " + "hw part %s boot sw %s main sw %s ser num %s\n", + hw_part, boot_sw, main_sw, ser_num); + (void)strlcpy(session->subtype, main_sw, sizeof(session->subtype)); + gpsd_report(LOG_DATA, "VERSION: subtype='%s' mask={DEVEICEID}\n", + session->subtype); + return DEVICEID_IS; +} + +/** + * GPS Leap Seconds + */ +static gps_mask_t +superstar2_msg_timing(struct gps_device_t *session, unsigned char *buf, + size_t data_len) +{ + gps_mask_t mask; + union long_double l_d; + double d; + struct tm tm; + + if (data_len != 65) + return 0; + + gpsd_report(LOG_PROG, "superstar2 #113 - timing status\n"); + /*@ +charint @*/ + if ((getub(buf, 55) & 0x30) != 0) + mask = 0; + /*@ -charint @*/ + else { + /* extract time data */ + (void)memset(&tm, '\0', sizeof(tm)); + tm.tm_mday = (int)getsb(buf, 37); + tm.tm_mon = (int)getsb(buf, 38) - 1; + tm.tm_year = (int)getlesw(buf, 39) - 1900; + + tm.tm_hour = (int)getsb(buf, 41); + tm.tm_min = (int)getsb(buf, 42); + d = getled(buf, 43); + tm.tm_sec = (int)d; + session->newdata.time = timegm(&tm); + session->context->leap_seconds = (int)getsb(buf, 20); + mask = TIME_IS; + } + gpsd_report(LOG_DATA, "TIMING: time=%.2f mask={TIME}\n", + session->newdata.time); + return mask; +} + +/** + * Raw Measurements + */ +static gps_mask_t +superstar2_msg_measurement(struct gps_device_t *session, unsigned char *buf, + size_t data_len UNUSED) +{ + gps_mask_t mask = 0; +#ifdef RAW_ENABLE + int i, n; + unsigned long ul; + double t; + union long_double l_d; + + gpsd_report(LOG_PROG, "superstar2 #23 - measurement block\n"); + + n = (int)getub(buf, 6); /* number of measurements */ + if ((n < 1) || (n > MAXCHANNELS)) { + gpsd_report(LOG_INF, "too many measurements\n"); + return 0; + } + t = getled(buf, 7); /* measurement time */ + for (i = 0; i < n; i++) { + session->gpsdata.raw.mtime[i] = t; + session->gpsdata.PRN[i] = (int)getub(buf, 11 * i + 15) & 0x1f; + session->gpsdata.ss[i] = (double)getub(buf, 11 * i * 15 + 1) / 4.0; + session->gpsdata.raw.codephase[i] = + (double)getleul(buf, 11 * i * 15 + 2); + ul = (unsigned long)getleul(buf, 11 * i * 15 + 6); + + session->gpsdata.raw.satstat[i] = (unsigned int)(ul & 0x03L); + session->gpsdata.raw.carrierphase[i] = (double)((ul >> 2) & 0x03ffL); + session->gpsdata.raw.pseudorange[i] = (double)(ul >> 12); + } + + mask |= RAW_IS; +#endif /* RAW_ENABLE */ + return mask; +} + +/* request for ionospheric and utc time data #75 */ +/*@ +charint @*/ +static unsigned char iono_utc_msg[] = { 0x01, 0x4b, 0xb4, 0x00, 0x00, 0x01 }; + +/*@ -charint @*/ + + +/** + * Ionospheric/UTC parameters + */ +static gps_mask_t +superstar2_msg_iono_utc(struct gps_device_t *session, unsigned char *buf, + size_t data_len UNUSED) +{ + unsigned int i, u; + + i = (unsigned int)getub(buf, 12); + u = (unsigned int)getub(buf, 21); + gpsd_report(LOG_PROG, + "superstar2 #75 - ionospheric & utc data: iono %s utc %s\n", + i ? "ok" : "bad", u ? "ok" : "bad"); + session->driver.superstar2.last_iono = time(NULL); + + return 0; +} + + +/** + * Ephemeris + */ +static gps_mask_t +superstar2_msg_ephemeris(struct gps_device_t *session, unsigned char *buf, + size_t data_len UNUSED) +{ + unsigned int prn; + prn = (unsigned int)(getub(buf, 4) & 0x1f); + gpsd_report(LOG_PROG, "superstar2 #22 - ephemeris data - prn %u\n", prn); + + /* ephemeris data updates fairly slowly, but when it does, poll UTC */ + if ((time(NULL) - session->driver.superstar2.last_iono) > 60) + (void)superstar2_write(session, (char *)iono_utc_msg, + sizeof(iono_utc_msg)); + + return ONLINE_IS; +} + + +static ssize_t +superstar2_write(struct gps_device_t *session, char *msg, size_t msglen) +{ + unsigned short c = 0; + ssize_t i; + + for (i = 0; i < (ssize_t) (msglen - 2); i++) + c += (unsigned short)msg[i]; + c += 0x100; + msg[(int)msg[3] + 4] = (char)((c >> 8) & 0xff); + msg[(int)msg[3] + 5] = (char)(c & 0xff); + gpsd_report(LOG_IO, "writing superstar2 control type %d len %zu:%s\n", + (int)msg[1] & 0x7f, msglen, + gpsd_hexdump_wrapper(msg, msglen, LOG_IO)); + return (i = gpsd_write(session, msg, msglen)); +} + +/** + * Parse the data from the device + */ +gps_mask_t +superstar2_dispatch(struct gps_device_t * session, unsigned char *buf, + size_t len) +{ + int type; + + if (len == 0) + return 0; + + type = (int)buf[SUPERSTAR2_TYPE_OFFSET]; + (void)snprintf(session->gpsdata.tag, + sizeof(session->gpsdata.tag), "SS2-%d", type); + + session->cycle_end_reliable = true; + + switch (type) { + case SUPERSTAR2_ACK: /* Message Acknowledgement */ + return superstar2_msg_ack(session, buf, len); + case SUPERSTAR2_SVINFO: /* Satellite Visibility Data */ + return superstar2_msg_svinfo(session, buf, len); + case SUPERSTAR2_NAVSOL_LLA: /* Navigation Data */ + return superstar2_msg_navsol_lla(session, buf, + len) | (CLEAR_IS | REPORT_IS); + case SUPERSTAR2_VERSION: /* Hardware/Software Version */ + return superstar2_msg_version(session, buf, len); + case SUPERSTAR2_TIMING: /* Timing Parameters */ + return superstar2_msg_timing(session, buf, len); + case SUPERSTAR2_MEASUREMENT: /* Timing Parameters */ + return superstar2_msg_measurement(session, buf, len); + case SUPERSTAR2_IONO_UTC: + return superstar2_msg_iono_utc(session, buf, len); + case SUPERSTAR2_EPHEMERIS: + return superstar2_msg_ephemeris(session, buf, len); + + default: + gpsd_report(LOG_WARN, + "unknown superstar2 packet id 0x%02x length %zd: %s\n", + type, len, gpsd_hexdump_wrapper(buf, len, LOG_WARN)); + return 0; + } +} + +/********************************************************** + * + * Externally called routines below here + * + **********************************************************/ +/*@ +charint @*/ +/* canned config messages */ +/* Initiate Link ID# 63 */ +static unsigned char link_msg[] = { 0x01, 0x3f, 0xc0, 0x08, + 0x55, 0x47, 0x50, 0x53, 0x2d, 0x30, 0x30, 0x30, + 0x00, 0x00 +}; + +/* Request Hardware/Software Identification ID# 45 */ +static unsigned char version_msg[] = { 0x01, 0x2d, 0xd2, 0x00, 0x00, 0x01 }; + +/*@ -charint @*/ + +static void superstar2_event_hook(struct gps_device_t *session, event_t event) +{ + if (event == event_wakeup) { + (void)superstar2_write(session, (char *)link_msg, sizeof(link_msg)); + (void)usleep(320000); + (void)superstar2_write(session, (char *)version_msg, + sizeof(version_msg)); + return; + } + + /* query firmware version */ + if (event == event_identified) + (void)superstar2_write(session, (char *)version_msg, + sizeof(version_msg)); + + /* FIX-ME: check to see if this really needs to be resent on reactivation */ + if (event == event_identified || event == event_reactivate) { + /*@ +charint @*/ + unsigned char svinfo_msg[] = { 0x01, 0xa1, 0x5e, 0x00, 0x00, 0x01 }; + unsigned char timing_msg[] = { 0x01, 0xf1, 0x0e, 0x00, 0x00, 0x01 }; + unsigned char navsol_lla_msg[] = + { 0x01, 0x94, 0x6b, 0x00, 0x00, 0x01 }; + unsigned char ephemeris_msg[] = + { 0x01, 0x96, 0x69, 0x00, 0x00, 0x01 }; + unsigned char measurement_msg[] = + { 0x01, 0x97, 0x68, 0x01, 0x00, 0x01, 0x01 }; + /*@ -charint @*/ + + (void)superstar2_write(session, (char *)timing_msg, + sizeof(timing_msg)); + (void)superstar2_write(session, (char *)measurement_msg, + sizeof(measurement_msg)); + (void)superstar2_write(session, (char *)svinfo_msg, + sizeof(svinfo_msg)); + (void)superstar2_write(session, (char *)navsol_lla_msg, + sizeof(navsol_lla_msg)); + (void)superstar2_write(session, (char *)version_msg, + sizeof(version_msg)); + (void)superstar2_write(session, (char *)ephemeris_msg, + sizeof(ephemeris_msg)); + (void)superstar2_write(session, (char *)iono_utc_msg, + sizeof(iono_utc_msg)); + session->driver.superstar2.last_iono = time(NULL); + } +} + +/* + * This is the entry point to the driver. When the packet sniffer recognizes + * a packet for this driver, it calls this method which passes the packet to + * the binary processor or the nmea processor, depending on the session type. + */ +static gps_mask_t superstar2_parse_input(struct gps_device_t *session) +{ + gps_mask_t st; + + if (session->packet.type == SUPERSTAR2_PACKET) { + st = superstar2_dispatch(session, session->packet.outbuffer, + session->packet.length); + session->gpsdata.dev.driver_mode = MODE_BINARY; + return st; +#ifdef NMEA_ENABLE + } else if (session->packet.type == NMEA_PACKET) { + st = nmea_parse((char *)session->packet.outbuffer, session); + (void)gpsd_switch_driver(session, "Generic NMEA"); + session->gpsdata.dev.driver_mode = MODE_NMEA; + return st; +#endif /* NMEA_ENABLE */ + } else + return 0; +} + +#ifdef ALLOW_CONTROLSEND +static ssize_t +superstar2_control_send(struct gps_device_t *session, char *msg, + size_t msglen) +{ + /*@ +charint -mayaliasunique @*/ + session->msgbuf[0] = 0x1; /* SOH */ + session->msgbuf[1] = msg[0]; + session->msgbuf[2] = msg[0] ^ 0xff; + session->msgbuf[3] = (char)(msglen + 1); + (void)memcpy(session->msgbuf + 4, msg + 1, msglen - 1); + session->msgbuflen = (size_t) (msglen + 5); + /*@ -charint +mayaliasunique @*/ + return superstar2_write(session, session->msgbuf, session->msgbuflen); +} +#endif /* ALLOW_CONTROLSEND */ + +#ifdef ALLOW_RECONFIGURE +static bool superstar2_set_speed(struct gps_device_t *session, + speed_t speed, char parity, int stopbits) +{ + /* parity and stopbit switching aren't available on this chip */ + if (parity != session->gpsdata.dev.parity + || stopbits != (int)session->gpsdata.dev.stopbits) { + return false; + } else { + /*@ +charint @*/ + unsigned char speed_msg[] = + { 0x01, 0x48, 0xB7, 0x01, 0x00, 0x00, 0x00 }; + + /* high bit 0 in the mode word means set NMEA mode */ + speed_msg[4] = (unsigned char)(speed / 300); + /*@ -charint @*/ + return (superstar2_write(session, (char *)speed_msg, 7) == 7); + } +} +#endif /* ALLOW_RECONFIGURE */ + +static void superstar2_set_mode(struct gps_device_t *session, int mode) +{ + if (mode == MODE_NMEA) { + /*@ +charint @*/ + unsigned char mode_msg[] = + { 0x01, 0x48, 0xB7, 0x01, 0x00, 0x00, 0x00 }; + + /* high bit 0 in the mode word means set NMEA mode */ + mode_msg[4] = (unsigned char)(session->gpsdata.dev.baudrate / 300); + (void)superstar2_write(session, (char *)mode_msg, 7); + /*@ -charint @*/ + } else { + session->back_to_nmea = false; + } +} + +/* *INDENT-OFF* */ +const struct gps_type_t superstar2_binary = { + /* Full name of type */ + .type_name = "SuperStarII binary", + /* Associated lexer packet type */ + .packet_type = SUPERSTAR2_PACKET, + /* Response string that identifies device (not active) */ + .trigger = NULL, + /* Number of satellite channels supported by the device */ + .channels = 12, + /* Startup-time device detector */ + .probe_detect = NULL, + /* Packet getter (using default routine) */ + .get_packet = generic_get, + /* Parse message packets */ + .parse_packet = superstar2_parse_input, + /* RTCM handler (using default routine) */ + .rtcm_writer = pass_rtcm, + /* Fire on various lifetime events */ + .event_hook = superstar2_event_hook, +#ifdef ALLOW_RECONFIGURE + /* Speed (baudrate) switch */ + .speed_switcher = superstar2_set_speed, + /* Switch to NMEA mode */ + .mode_switcher = superstar2_set_mode, + /* Message delivery rate switcher (not active) */ + .rate_switcher = NULL, + /* Minimum cycle time (not used) */ + .min_cycle = 1, +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + /* Control string sender - should provide checksum and trailer */ + .control_send = superstar2_control_send, +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* defined(SUPERSTAR2_ENABLE) && defined(BINARY_ENABLE) */ diff --git a/driver_superstar2.h b/driver_superstar2.h new file mode 100644 index 0000000..30416bb --- /dev/null +++ b/driver_superstar2.h @@ -0,0 +1,62 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#ifndef _GPSD_SUPERSTAR2_H_ +#define _GPSD_SUPERSTAR2_H_ + +#define SUPERSTAR2_BASE_SIZE 4 +#define SUPERSTAR2_TYPE_OFFSET 1 + +/* input-only */ +#define SUPERSTAR2_RESET 2 +#define SUPERSTAR2_LINKUP 63 +#define SUPERSTAR2_CHANNEL_INHIBIT 64 +#define SUPERSTAR2_TIME_PARAMS 69 +#define SUPERSTAR2_ALMANAC_INCREMENT 77 +#define SUPERSTAR2_ALMANAC_UPLOAD 79 +#define SUPERSTAR2_SET_OPMODE 80 +#define SUPERSTAR2_SET_MASK 81 +#define SUPERSTAR2_SET_DGPS 83 +#define SUPERSTAR2_SET_IONOMODEL 84 +#define SUPERSTAR2_SET_MSLMODEL 86 +#define SUPERSTAR2_SET_HEIGHT_MODE 87 +#define SUPERSTAR2_SET_DATUM 88 +#define SUPERSTAR2_SATELLITE_INHIBIT 90 +#define SUPERSTAR2_BASE_CONFIG 91 +#define SUPERSTAR2_SATELLITE_TRACK 95 +#define SUPERSTAR2_NVM_ERASE 99 +#define SUPERSTAR2_SET_TIME 103 +#define SUPERSTAR2_MESSAGE_CONFIG 105 +#define SUPERSTAR2_SERIAL_CONFIG 110 + +/* output-only */ +#define SUPERSTAR2_CHANINF2 7 +#define SUPERSTAR2_LINKERR 125 +#define SUPERSTAR2_ACK 126 + +/* bidirectional */ +#define SUPERSTAR2_DUMMY 0 +#define SUPERSTAR2_CHANINF 6 +#define SUPERSTAR2_NAVSOL_LLA 20 +#define SUPERSTAR2_NAVSOL_ECEF 21 +#define SUPERSTAR2_EPHEMERIS 22 +#define SUPERSTAR2_MEASUREMENT 23 +#define SUPERSTAR2_RECV_CONFIG 30 +#define SUPERSTAR2_SVINFO 33 +#define SUPERSTAR2_DGPSCONFIG 43 +#define SUPERSTAR2_VERSION 45 +#define SUPERSTAR2_BASE_STATUS 47 +#define SUPERSTAR2_DGPS_STATUS 48 +#define SUPERSTAR2_RECV_STATUS 49 +#define SUPERSTAR2_SAT_HEALTH 50 +#define SUPERSTAR2_SELFTEST 51 +#define SUPERSTAR2_RTCM_DATA 65 +#define SUPERSTAR2_SBAS_DATA 67 +#define SUPERSTAR2_SBAS_STATUS 68 +#define SUPERSTAR2_IONO_UTC 75 +#define SUPERSTAR2_ALMANAC_DATA 76 +#define SUPERSTAR2_ALMANAC_STATUS 78 +#define SUPERSTAR2_TIMING 113 + +#endif /* _GPSD_SUPERSTAR2_H_ */ diff --git a/driver_tsip.c b/driver_tsip.c new file mode 100644 index 0000000..648b5f0 --- /dev/null +++ b/driver_tsip.c @@ -0,0 +1,1183 @@ +/* + * Handle the Trimble TSIP packet format + * by Rob Janssen, PE1CHL. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include "gpsd_config.h" + +#if defined (HAVE_SYS_SELECT_H) +#include +#endif +#if defined(HAVE_SYS_TIME_H) +#include +#endif + +#include "gpsd.h" +#include "bits.h" + +#define USE_SUPERPACKET 1 /* use Super Packet mode? */ + +#define SEMI_2_DEG (180.0 / 2147483647) /* 2^-31 semicircle to deg */ + +#ifdef TSIP_ENABLE +#define TSIP_CHANNELS 12 + +static int tsip_write(struct gps_device_t *session, + unsigned int id, /*@null@*/ unsigned char *buf, + size_t len) +{ + char *ep, *cp; + + gpsd_report(LOG_IO, "Sent TSIP packet id 0x%02x: %s\n", id, + gpsd_hexdump_wrapper(buf, len, LOG_IO)); + + /*@ +charint @*/ + session->msgbuf[0] = '\x10'; + session->msgbuf[1] = (char)id; + ep = session->msgbuf + 2; + /*@ -nullderef @*/ + for (cp = (char *)buf; len-- > 0; cp++) { + if (*cp == '\x10') + *ep++ = '\x10'; + *ep++ = *cp; + } + /*@ +nullderef @*/ + *ep++ = '\x10'; + *ep++ = '\x03'; + session->msgbuflen = (size_t) (ep - session->msgbuf); + /*@ -charint @*/ + if (gpsd_write(session, session->msgbuf, session->msgbuflen) != + (ssize_t) session->msgbuflen) + return -1; + + return 0; +} + +/* tsip_detect() + * + * see if it looks like a TSIP device (speaking 9600O81) is listening and + * return 1 if found, 0 if not + */ +static bool tsip_detect(struct gps_device_t *session) +{ + char buf[BUFSIZ]; + unsigned int n; + bool ret = false; + int myfd; + fd_set fdset; + struct timeval to; + speed_t old_baudrate; + char old_parity; + unsigned int old_stopbits; + + gpsd_report(LOG_PROG, "Probing TSIP\n"); + + old_baudrate = session->gpsdata.dev.baudrate; + old_parity = session->gpsdata.dev.parity; + old_stopbits = session->gpsdata.dev.stopbits; + gpsd_set_speed(session, 9600, 'O', 1); + + /* request firmware revision and look for a valid response */ + /*@+ignoresigns@*/ + putbyte(buf, 0, 0x10); + putbyte(buf, 1, 0x1f); + putbyte(buf, 2, 0x10); + putbyte(buf, 3, 0x03); + /*@+ignoresigns@*/ + myfd = session->gpsdata.gps_fd; + if (write(myfd, buf, 4) == 4) { + for (n = 0; n < 3; n++) { + FD_ZERO(&fdset); + FD_SET(myfd, &fdset); + to.tv_sec = 1; + to.tv_usec = 0; + if (select(myfd + 1, &fdset, NULL, NULL, &to) != 1) + break; + if (generic_get(session) >= 0) { + if (session->packet.type == TSIP_PACKET) { + gpsd_report(LOG_RAW, "tsip_detect found\n"); + ret = true; + break; + } + } + } + } + + if (!ret) + /* return serial port to original settings */ + gpsd_set_speed(session, old_baudrate, old_parity, old_stopbits); + + return ret; +} + +static gps_mask_t tsip_analyze(struct gps_device_t *session) +{ + int i, j, len, count; + gps_mask_t mask = 0; + unsigned int id; + uint8_t u1, u2, u3, u4, u5; + int16_t s1, s2, s3, s4; + int32_t sl1, sl2, sl3; + uint32_t ul1, ul2; + float f1, f2, f3, f4, f5; + double d1, d2, d3, d4, d5; + union int_float i_f; + union long_double l_d; + time_t now; + unsigned char buf[BUFSIZ]; + char buf2[BUFSIZ]; + + if (session->packet.type != TSIP_PACKET) { + gpsd_report(LOG_INF, "tsip_analyze packet type %d\n", + session->packet.type); + return 0; + } + + /*@ +charint @*/ + if (session->packet.outbuflen < 4 || session->packet.outbuffer[0] != 0x10) + return 0; + + /* remove DLE stuffing and put data part of message in buf */ + + memset(buf, 0, sizeof(buf)); + buf2[len = 0] = '\0'; + for (i = 2; i < (int)session->packet.outbuflen; i++) { + if (session->packet.outbuffer[i] == 0x10) + if (session->packet.outbuffer[++i] == 0x03) + break; + + (void)snprintf(buf2 + strlen(buf2), + sizeof(buf2) - strlen(buf2), + "%02x", buf[len++] = session->packet.outbuffer[i]); + } + /*@ -charint @*/ + + (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), + "ID%02x", id = (unsigned)session->packet.outbuffer[1]); + + gpsd_report(LOG_IO, "TSIP packet id 0x%02x length %d: %s\n", id, len, + buf2); + (void)time(&now); + + session->cycle_end_reliable = true; + switch (id) { + case 0x13: /* Packet Received */ + u1 = getub(buf, 0); + u2 = getub(buf, 1); + gpsd_report(LOG_WARN, + "Received packet of type %02x cannot be parsed\n", u1); +#if USE_SUPERPACKET + if ((int)u1 == 0x8e && (int)u2 == 0x23) { /* no Compact Super Packet */ + gpsd_report(LOG_WARN, "No Compact Super Packet, use LFwEI\n"); + + /* Request LFwEI Super Packet */ + putbyte(buf, 0, 0x20); + putbyte(buf, 1, 0x01); /* enabled */ + (void)tsip_write(session, 0x8e, buf, 2); + } +#endif /* USE_SUPERPACKET */ + break; + case 0x41: /* GPS Time */ + if (len != 10) + break; + session->driver.tsip.last_41 = now; /* keep timestamp for request */ + f1 = getbef(buf, 0); /* gpstime */ + s1 = getbesw(buf, 4); /* week */ + f2 = getbef(buf, 6); /* leap seconds */ + if (f1 >= 0.0 && f2 > 10.0) { + session->context->gps_week = s1; + session->context->leap_seconds = (int)round(f2); + session->context->valid |= LEAP_SECOND_VALID; + session->context->gps_tow = f1; + + session->newdata.time = + gpstime_to_unix(session->context->gps_week, + session->context->gps_tow) - + session->context->leap_seconds; + mask |= TIME_IS; + } + gpsd_report(LOG_INF, "GPS Time %f %d %f\n", f1, s1, f2); + break; + case 0x42: /* Single-Precision Position Fix, XYZ ECEF */ + if (len != 16) + break; + f1 = getbef(buf, 0); /* X */ + f2 = getbef(buf, 4); /* Y */ + f3 = getbef(buf, 8); /* Z */ + f4 = getbef(buf, 12); /* time-of-fix */ + gpsd_report(LOG_INF, "GPS Position XYZ %f %f %f %f\n", f1, f2, f3, + f4); + break; + case 0x43: /* Velocity Fix, XYZ ECEF */ + if (len != 20) + break; + f1 = getbef(buf, 0); /* X velocity */ + f2 = getbef(buf, 4); /* Y velocity */ + f3 = getbef(buf, 8); /* Z velocity */ + f4 = getbef(buf, 12); /* bias rate */ + f5 = getbef(buf, 16); /* time-of-fix */ + gpsd_report(LOG_INF, "GPS Velocity XYZ %f %f %f %f %f\n", f1, f2, f3, + f4, f5); + break; + case 0x45: /* Software Version Information */ + if (len != 10) + break; + /*@ -formattype @*/ + (void)snprintf(session->subtype, sizeof(session->subtype), + "%d.%d %02d%02d%02d %d.%d %02d%02d%02d", + getub(buf, 0), getub(buf, 1), getub(buf, 4), getub(buf, + 2), + getub(buf, 3), getub(buf, 5), getub(buf, 6), getub(buf, + 9), + getub(buf, 7), getub(buf, 8)); + /*@ +formattype @*/ + gpsd_report(LOG_INF, "Software version: %s\n", session->subtype); + mask |= DEVICEID_IS; + break; + case 0x46: /* Health of Receiver */ + if (len != 2) + break; + session->driver.tsip.last_46 = now; + u1 = getub(buf, 0); /* Status code */ + u2 = getub(buf, 1); /* Antenna/Battery */ + if (u1 != (uint8_t) 0) { + session->gpsdata.status = STATUS_NO_FIX; + mask |= STATUS_IS; + } else { + if (session->gpsdata.status < STATUS_FIX) { + session->gpsdata.status = STATUS_FIX; + mask |= STATUS_IS; + } + } + gpsd_report(LOG_PROG, "Receiver health %02x %02x\n", u1, u2); + break; + case 0x47: /* Signal Levels for all Satellites */ + gpsd_zero_satellites(&session->gpsdata); + count = (int)getub(buf, 0); /* satellite count */ + if (len != (5 * count + 1)) + break; + buf2[0] = '\0'; + for (i = 0; i < count; i++) { + u1 = getub(buf, 5 * i + 1); + if ((f1 = getbef(buf, 5 * i + 2)) < 0) + f1 = 0.0; + for (j = 0; j < TSIP_CHANNELS; j++) + if (session->gpsdata.PRN[j] == (int)u1) { + session->gpsdata.ss[j] = f1; + break; + } + (void)snprintf(buf2 + strlen(buf2), sizeof(buf2) - strlen(buf2), + " %d=%.1f", (int)u1, f1); + } + gpsd_report(LOG_PROG, "Signal Levels (%d):%s\n", count, buf2); + mask |= SATELLITE_IS; + break; + case 0x48: /* GPS System Message */ + buf[len] = '\0'; + gpsd_report(LOG_PROG, "GPS System Message: %s\n", buf); + break; + case 0x49: /* Almanac Health Page */ + break; + case 0x4a: /* Single-Precision Position LLA */ + if (len != 20) + break; + session->newdata.latitude = getbef(buf, 0) * RAD_2_DEG; + session->newdata.longitude = getbef(buf, 4) * RAD_2_DEG; + session->newdata.altitude = getbef(buf, 8); + f1 = getbef(buf, 12); /* clock bias */ + f2 = getbef(buf, 16); /* time-of-fix */ + session->context->gps_tow = f2; + if (session->context->gps_week) { + session->newdata.time = + gpstime_to_unix((int)session->context->gps_week, + session->context->gps_tow) + - session->context->leap_seconds; + mask |= TIME_IS; + } + mask |= LATLON_IS | ALTITUDE_IS | CLEAR_IS | REPORT_IS; + gpsd_report(LOG_DATA, "SPPLLA 0x4a " + "time=%.2f lat=%.2f lon=%.2f alt=%.2f mask=%s\n", + session->newdata.time, + session->newdata.latitude, + session->newdata.longitude, + session->newdata.altitude, gpsd_maskdump(mask)); + break; + case 0x4b: /* Machine/Code ID and Additional Status */ + if (len != 3) + break; + u1 = getub(buf, 0); /* Machine ID */ + u2 = getub(buf, 1); /* Status 1 */ + u3 = getub(buf, 2); /* Status 2 */ + gpsd_report(LOG_INF, "Machine ID %02x %02x %02x\n", u1, u2, u3); +#if USE_SUPERPACKET + if ((u3 & 0x01) != (uint8_t) 0 && !session->driver.tsip.superpkt) { + gpsd_report(LOG_PROG, "Switching to Super Packet mode\n"); + + /* set new I/O Options for Super Packet output */ + putbyte(buf, 0, 0x2c); /* Position: SP, MSL */ + putbyte(buf, 1, 0x00); /* Velocity: none (via SP) */ + putbyte(buf, 2, 0x00); /* Time: GPS */ + putbyte(buf, 3, 0x08); /* Aux: dBHz */ + (void)tsip_write(session, 0x35, buf, 4); + session->driver.tsip.superpkt = true; + } +#endif /* USE_SUPERPACKET */ + break; + case 0x4c: /* Operating Parameters Report */ + break; + case 0x54: /* One Satellite Bias */ + break; + case 0x55: /* IO Options */ + if (len != 4) + break; + u1 = getub(buf, 0); /* Position */ + u2 = getub(buf, 1); /* Velocity */ + u3 = getub(buf, 2); /* Timing */ + u4 = getub(buf, 3); /* Aux */ + gpsd_report(LOG_INF, "IO Options %02x %02x %02x %02x\n", u1, u2, u3, + u4); +#if USE_SUPERPACKET + if ((u1 & 0x20) != (uint8_t) 0) { /* Output Super Packets? */ + /* No LFwEI Super Packet */ + putbyte(buf, 0, 0x20); + putbyte(buf, 1, 0x00); /* disabled */ + (void)tsip_write(session, 0x8e, buf, 2); + + /* Request Compact Super Packet */ + putbyte(buf, 0, 0x23); + putbyte(buf, 1, 0x01); /* enabled */ + (void)tsip_write(session, 0x8e, buf, 2); + session->driver.tsip.req_compact = now; + } +#endif /* USE_SUPERPACKET */ + break; + case 0x56: /* Velocity Fix, East-North-Up (ENU) */ + if (len != 20) + break; + f1 = getbef(buf, 0); /* East velocity */ + f2 = getbef(buf, 4); /* North velocity */ + f3 = getbef(buf, 8); /* Up velocity */ + f4 = getbef(buf, 12); /* clock bias rate */ + f5 = getbef(buf, 16); /* time-of-fix */ + session->newdata.climb = f3; + /*@ -evalorder @*/ + session->newdata.speed = sqrt(pow(f2, 2) + pow(f1, 2)); + /*@ +evalorder @*/ + if ((session->newdata.track = atan2(f1, f2) * RAD_2_DEG) < 0) + session->newdata.track += 360.0; + gpsd_report(LOG_INF, "GPS Velocity ENU %f %f %f %f %f\n", f1, f2, f3, + f4, f5); + mask |= SPEED_IS | TRACK_IS | CLIMB_IS; + gpsd_report(LOG_DATA, "VFENU 0x56 " + "time=%.2f speed=%.2f track=%.2f climb=%.2f mask=%s\n", + session->newdata.time, + session->newdata.speed, + session->newdata.track, + session->newdata.climb, gpsd_maskdump(mask)); + break; + case 0x57: /* Information About Last Computed Fix */ + if (len != 8) + break; + u1 = getub(buf, 0); /* Source of information */ + u2 = getub(buf, 1); /* Mfg. diagnostic */ + f1 = getbef(buf, 2); /* gps_time */ + s1 = getbesw(buf, 6); /* tsip.gps_week */ + /*@ +charint @*/ + if (getub(buf, 0) == 0x01) /* good current fix? */ + session->context->gps_week = s1; + /*@ -charint @*/ + gpsd_report(LOG_INF, "Fix info %02x %02x %d %f\n", u1, u2, s1, f1); + break; + case 0x58: /* Satellite System Data/Acknowledge from Receiver */ + break; + case 0x59: /* Status of Satellite Disable or Ignore Health */ + break; + case 0x5a: /* Raw Measurement Data */ + if (len != 29) + break; + f1 = getbef(buf, 5); /* Signal Level */ + f2 = getbef(buf, 9); /* Code phase */ + f3 = getbef(buf, 13); /* Doppler */ + d1 = getbed(buf, 17); /* Time of Measurement */ + gpsd_report(LOG_PROG, "Raw Measurement Data %d %f %f %f %f\n", + getub(buf, 0), f1, f2, f3, d1); + break; + case 0x5b: /* Satellite Ephemeris Status */ + break; + case 0x5c: /* Satellite Tracking Status */ + if (len != 24) + break; + u1 = getub(buf, 0); /* PRN */ + u2 = getub(buf, 1); /* chan */ + u3 = getub(buf, 2); /* Acquisition flag */ + u4 = getub(buf, 3); /* Ephemeris flag */ + f1 = getbef(buf, 4); /* Signal level */ + f2 = getbef(buf, 8); /* time of Last measurement */ + d1 = getbef(buf, 12) * RAD_2_DEG; /* Elevation */ + d2 = getbef(buf, 16) * RAD_2_DEG; /* Azimuth */ + i = (int)(u2 >> 3); /* channel number */ + gpsd_report(LOG_INF, + "Satellite Tracking Status: Ch %2d PRN %3d Res %d Acq %d Eph %2d SNR %4.1f LMT %.04f El %4.1f Az %5.1f\n", + i, u1, u2 & 7, u3, u4, f1, f2, d1, d2); + if (i < TSIP_CHANNELS) { + if (d1 >= 0.0) { + session->gpsdata.PRN[i] = (int)u1; + session->gpsdata.ss[i] = f1; + session->gpsdata.elevation[i] = (int)round(d1); + session->gpsdata.azimuth[i] = (int)round(d2); + } else { + session->gpsdata.PRN[i] = session->gpsdata.elevation[i] + = session->gpsdata.azimuth[i] = 0; + session->gpsdata.ss[i] = 0.0; + } + if (++i == session->gpsdata.satellites_visible) { + session->gpsdata.skyview_time = NAN; + mask |= SATELLITE_IS; /* last of the series */ + } + if (i > session->gpsdata.satellites_visible) + session->gpsdata.satellites_visible = i; + } + break; + case 0x5e: /* Additional Fix Status Report */ + break; + case 0x6d: /* All-In-View Satellite Selection */ + u1 = getub(buf, 0); /* nsvs/dimension */ + count = (int)((u1 >> 4) & 0x0f); + if (len != (17 + count)) + break; + session->driver.tsip.last_6d = now; /* keep timestamp for request */ +#ifdef __UNUSED__ + /* + * This looks right, but it sets a spurious mode value when + * the satellite constellation looks good to the chip but no + * actual fix has yet been acquired. We should set the mode + * field (which controls gpsd's fix reporting) only from sentences + * that convey actual fix information, like 0x20, othewise we + * get results like triggering ther error modeler spuriously. + */ + switch (u1 & 7) { /* dimension */ + case 3: + //session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_2D; + break; + case 4: + //session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_3D; + break; + default: + //session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + break; + } + mask |= MODE_IS; +#endif /* __UNUSED__ */ + session->gpsdata.satellites_used = count; + session->gpsdata.dop.pdop = getbef(buf, 1); + session->gpsdata.dop.hdop = getbef(buf, 5); + session->gpsdata.dop.vdop = getbef(buf, 9); + session->gpsdata.dop.tdop = getbef(buf, 13); + /*@ -evalorder @*/ + session->gpsdata.dop.gdop = + sqrt(pow(session->gpsdata.dop.pdop, 2) + + pow(session->gpsdata.dop.tdop, 2)); + /*@ +evalorder @*/ + + memset(session->gpsdata.used, 0, sizeof(session->gpsdata.used)); + buf2[0] = '\0'; + /*@ +charint @*/ + for (i = 0; i < count; i++) + (void)snprintf(buf2 + strlen(buf2), sizeof(buf2) - strlen(buf2), + " %d", session->gpsdata.used[i] = + (int)getub(buf, 17 + i)); + /*@ -charint @*/ + gpsd_report(LOG_DATA, "AIVSS: 0x6d " + "status=%d used=%d " + "pdop=%.1f hdop=%.1f vdop=%.1f tdop=%.1f gdup=%.1f " + "mask=%s\n", + session->gpsdata.status, + session->gpsdata.satellites_used, + session->gpsdata.dop.pdop, + session->gpsdata.dop.hdop, + session->gpsdata.dop.vdop, + session->gpsdata.dop.tdop, + session->gpsdata.dop.gdop, gpsd_maskdump(mask)); + mask |= DOP_IS | STATUS_IS | USED_IS; + break; + case 0x6e: /* Synchronized Measurements */ + break; + case 0x6f: /* Synchronized Measurements Report */ + /*@ +charint @*/ + if (len < 20 || getub(buf, 0) != 1 || getub(buf, 1) != 2) + break; + /*@ -charint @*/ + s1 = getbesw(buf, 2); /* number of bytes */ + u1 = getub(buf, 20); /* number of SVs */ + break; + case 0x70: /* Filter Report */ + break; + case 0x7a: /* NMEA settings */ + break; + case 0x82: /* Differential Position Fix Mode */ + if (len != 1) + break; + u1 = getub(buf, 0); /* fix mode */ + /*@ +charint @*/ + if (session->gpsdata.status == STATUS_FIX && (u1 & 0x01) != 0) { + session->gpsdata.status = STATUS_DGPS_FIX; + mask |= STATUS_IS; + } + /*@ -charint @*/ + gpsd_report(LOG_DATA, "DPFM 0x82 status=%d mask=%s\n", + session->gpsdata.status, gpsd_maskdump(mask)); + break; + case 0x83: /* Double-Precision XYZ Position Fix and Bias Information */ + if (len != 36) + break; + d1 = getbed(buf, 0); /* X */ + d2 = getbed(buf, 8); /* Y */ + d3 = getbed(buf, 16); /* Z */ + d4 = getbed(buf, 24); /* clock bias */ + f1 = getbef(buf, 32); /* time-of-fix */ + gpsd_report(LOG_INF, "GPS Position XYZ %f %f %f %f %f\n", d1, d2, d3, + d4, f1); + break; + case 0x84: /* Double-Precision LLA Position Fix and Bias Information */ + if (len != 36) + break; + session->newdata.latitude = getbed(buf, 0) * RAD_2_DEG; + session->newdata.longitude = getbed(buf, 8) * RAD_2_DEG; + session->newdata.altitude = getbed(buf, 16); + d1 = getbed(buf, 24); /* clock bias */ + f1 = getbef(buf, 32); /* time-of-fix */ + session->context->gps_tow = f1; + if (session->context->gps_week) { + session->newdata.time = + gpstime_to_unix((int)session->context->gps_week, + session->context->gps_tow) + - session->context->leap_seconds; + mask |= TIME_IS; + } + gpsd_report(LOG_INF, "GPS DP LLA %f %f %f %f\n", + session->newdata.time, + session->newdata.latitude, + session->newdata.longitude, session->newdata.altitude); + mask |= LATLON_IS | ALTITUDE_IS | CLEAR_IS | REPORT_IS; + gpsd_report(LOG_DATA, "DPPLLA 0x84 " + "time=%.2f lat=%.2f lon=%.2f alt=%.2f mask=%s\n", + session->newdata.time, + session->newdata.latitude, + session->newdata.longitude, + session->newdata.altitude, gpsd_maskdump(mask)); + break; + case 0x8f: /* Super Packet. Well... */ + /*@ +charint @*/ + u1 = (uint8_t) getub(buf, 0); + (void)snprintf(session->gpsdata.tag + strlen(session->gpsdata.tag), + sizeof(session->gpsdata.tag) - + strlen(session->gpsdata.tag), "%02x", (uint) u1); + /*@ -charint @*/ + switch (u1) { /* sub-packet ID */ + case 0x15: /* Current Datum Values */ + if (len != 43) + break; + s1 = getbesw(buf, 1); /* Datum Index */ + d1 = getbed(buf, 3); /* DX */ + d2 = getbed(buf, 11); /* DY */ + d3 = getbed(buf, 19); /* DZ */ + d4 = getbed(buf, 27); /* A-axis */ + d5 = getbed(buf, 35); /* Eccentricity Squared */ + gpsd_report(LOG_INF, "Current Datum %d %f %f %f %f %f\n", s1, d1, + d2, d3, d4, d5); + break; + + case 0x20: /* Last Fix with Extra Information (binary fixed point) */ + /* CSK sez "why does my Lassen iQ output oversize packets?" */ + if ((len != 56) && (len != 64)) + break; + s1 = getbesw(buf, 2); /* east velocity */ + s2 = getbesw(buf, 4); /* north velocity */ + s3 = getbesw(buf, 6); /* up velocity */ + ul1 = getbeul(buf, 8); /* time */ + sl1 = getbesl(buf, 12); /* latitude */ + ul2 = getbeul(buf, 16); /* longitude */ + sl2 = getbesl(buf, 20); /* altitude */ + u1 = getub(buf, 24); /* velocity scaling */ + u2 = getub(buf, 27); /* fix flags */ + u3 = getub(buf, 28); /* num svs */ + u4 = getub(buf, 29); /* utc offset */ + s4 = getbesw(buf, 30); /* tsip.gps_week */ + /* PRN/IODE data follows */ + gpsd_report(LOG_RAW, + "LFwEI %d %d %d %u %d %u %u %x %x %u %u %d\n", s1, s2, + s3, ul1, sl1, ul2, sl2, u1, u2, u3, u4, s4); + + if ((u1 & 0x01) != (uint8_t) 0) /* check velocity scaling */ + d5 = 0.02; + else + d5 = 0.005; + d1 = s1 * d5; /* east velocity m/s */ + d2 = s2 * d5; /* north velocity m/s */ + session->newdata.climb = s3 * d5; /* up velocity m/s */ + /*@ -evalorder @*/ + session->newdata.speed = sqrt(pow(d2, 2) + pow(d1, 2)); + /*@ +evalorder @*/ + if ((session->newdata.track = atan2(d1, d2) * RAD_2_DEG) < 0) + session->newdata.track += 360.0; + session->newdata.latitude = sl1 * SEMI_2_DEG; + /*@i1@*/ session->newdata.longitude = ul2 * SEMI_2_DEG; + if (session->newdata.longitude > 180.0) + session->newdata.longitude -= 360.0; + session->gpsdata.separation = + wgs84_separation(session->newdata.latitude, + session->newdata.longitude); + session->newdata.altitude = + sl2 * 1e-3 - session->gpsdata.separation;; + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + if ((u2 & 0x01) == (uint8_t) 0) { /* Fix Available */ + session->gpsdata.status = STATUS_FIX; + if ((u2 & 0x02) != (uint8_t) 0) /* DGPS Corrected */ + session->gpsdata.status = STATUS_DGPS_FIX; + if ((u2 & 0x04) != (uint8_t) 0) /* Fix Dimension */ + session->newdata.mode = MODE_2D; + else + session->newdata.mode = MODE_3D; + } + session->gpsdata.satellites_used = (int)u3; + if ((int)u4 > 10) { + session->context->leap_seconds = (int)u4; + session->context->valid |= LEAP_SECOND_VALID; + } + session->context->gps_week = (unsigned short)s4; + session->context->gps_tow = (double)ul1 *1e-3; + /*@ ignore @*//*@ splint is confused @ */ + session->newdata.time = + gpstime_to_unix((int)s4, session->context->gps_tow) + - session->context->leap_seconds; + /*@ end @*/ + mask |= + TIME_IS | LATLON_IS | ALTITUDE_IS | SPEED_IS | TRACK_IS | + CLIMB_IS | STATUS_IS | MODE_IS | CLEAR_IS | REPORT_IS; + gpsd_report(LOG_DATA, + "SP-LFEI 0x20: time=%.2f lat=%.2f lon=%.2f alt=%.2f " + "speed=%.2f track=%.2f climb=%.2f " + "mode=%d status=%d mask=%s\n", session->newdata.time, + session->newdata.latitude, session->newdata.longitude, + session->newdata.altitude, session->newdata.speed, + session->newdata.track, session->newdata.climb, + session->newdata.mode, session->gpsdata.status, + gpsd_maskdump(mask)); + break; + case 0x23: /* Compact Super Packet */ + session->driver.tsip.req_compact = 0; + /* CSK sez "i don't trust this to not be oversized either." */ + if (len < 29) + break; + ul1 = getbeul(buf, 1); /* time */ + s1 = getbesw(buf, 5); /* tsip.gps_week */ + u1 = getub(buf, 7); /* utc offset */ + u2 = getub(buf, 8); /* fix flags */ + sl1 = getbesl(buf, 9); /* latitude */ + ul2 = getbeul(buf, 13); /* longitude */ + sl3 = getbesl(buf, 17); /* altitude */ + s2 = getbesw(buf, 21); /* east velocity */ + s3 = getbesw(buf, 23); /* north velocity */ + s4 = getbesw(buf, 25); /* up velocity */ + gpsd_report(LOG_INF, "CSP %u %d %u %u %d %u %d %d %d %d\n", ul1, + s1, u1, u2, sl1, ul2, sl3, s2, s3, s4); + session->context->gps_week = s1; + if ((int)u1 > 10) { + session->context->leap_seconds = (int)u1; + session->context->valid |= LEAP_SECOND_VALID; + } + session->context->gps_week = (unsigned short)s1; + session->context->gps_tow = (double)ul1 *1e3; + /*@ ignore @*//*@ splint is confused @ */ + session->newdata.time = + gpstime_to_unix(session->context->gps_week, + session->context->gps_tow) + - session->context->leap_seconds; + /*@ end @*/ + session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + if ((u2 & 0x01) == (uint8_t) 0) { /* Fix Available */ + session->gpsdata.status = STATUS_FIX; + if ((u2 & 0x02) != (uint8_t) 0) /* DGPS Corrected */ + session->gpsdata.status = STATUS_DGPS_FIX; + if ((u2 & 0x04) != (uint8_t) 0) /* Fix Dimension */ + session->newdata.mode = MODE_2D; + else + session->newdata.mode = MODE_3D; + } + session->newdata.latitude = sl1 * SEMI_2_DEG; + /*@i1@*/ session->newdata.longitude = ul2 * SEMI_2_DEG; + if (session->newdata.longitude > 180.0) + session->newdata.longitude -= 360.0; + session->gpsdata.separation = + wgs84_separation(session->newdata.latitude, + session->newdata.longitude); + session->newdata.altitude = + sl3 * 1e-3 - session->gpsdata.separation;; + if ((u2 & 0x20) != (uint8_t) 0) /* check velocity scaling */ + d5 = 0.02; + else + d5 = 0.005; + d1 = s2 * d5; /* east velocity m/s */ + d2 = s3 * d5; /* north velocity m/s */ + session->newdata.climb = s4 * d5; /* up velocity m/s */ + /*@ -evalorder @*/ + session->newdata.speed = + sqrt(pow(d2, 2) + pow(d1, 2)) * MPS_TO_KNOTS; + /*@ +evalorder @*/ + if ((session->newdata.track = atan2(d1, d2) * RAD_2_DEG) < 0) + session->newdata.track += 360.0; + mask |= + TIME_IS | LATLON_IS | ALTITUDE_IS | SPEED_IS | TRACK_IS | + CLIMB_IS | STATUS_IS | MODE_IS | CLEAR_IS | REPORT_IS; + gpsd_report(LOG_DATA, + "SP-CSP 0x23: time=%.2f lat=%.2f lon=%.2f alt=%.2f " + "speed=%.2f track=%.2f climb=%.2f " + "mode=%d status=%d mask=%s\n", session->newdata.time, + session->newdata.latitude, session->newdata.longitude, + session->newdata.altitude, session->newdata.speed, + session->newdata.track, session->newdata.climb, + session->newdata.mode, session->gpsdata.status, + gpsd_maskdump(mask)); + break; + + case 0xab: /* Thunderbolt Timing Superpacket */ + if (len != 17) { + gpsd_report(4, "pkt 0xab len=%d\n", len); + break; + } + session->driver.tsip.last_41 = now; /* keep timestamp for request */ + ul1 = getbeul(buf, 1); /* gpstime */ + s1 = (short)getbeuw(buf, 5); /* week */ + s2 = getbesw(buf, 7); /* leap seconds */ + + session->context->gps_week = s1; + if ((int)u1 > 10) { + session->context->leap_seconds = (int)s2; + session->context->valid |= LEAP_SECOND_VALID; + + session->context->gps_week = s1; + session->context->gps_tow = (double)ul1; + session->newdata.time = + gpstime_to_unix((int)s1, session->context->gps_tow) + - (double)s2; + mask |= TIME_IS | CLEAR_IS; + gpsd_report(LOG_DATA, "SP-TTS 0xab time=%.2f mask={TIME}\n", + session->newdata.time); + } + + gpsd_report(4, "GPS Time %u %d %d\n", ul1, s1, s2); + break; + + + case 0xac: /* Thunderbolt Position Superpacket */ + if (len != 68) { + gpsd_report(4, "pkt 0xac len=%d\n", len); + + break; + } + session->newdata.latitude = getbed(buf, 36) * RAD_2_DEG; + session->newdata.longitude = getbed(buf, 44) * RAD_2_DEG; + session->newdata.altitude = getbed(buf, 52); + f1 = getbef(buf, 16); /* clock bias */ + + u1 = getub(buf, 12); /* GPS Decoding Status */ + u2 = getub(buf, 1); /* Reciever Mode */ + if (u1 != (uint8_t) 0) { + session->gpsdata.status = STATUS_NO_FIX; + mask |= STATUS_IS; + } else { + if (session->gpsdata.status < STATUS_FIX) { + session->gpsdata.status = STATUS_FIX; + mask |= STATUS_IS; + } + } + + /* Decode Fix modes */ + switch (u2 & 7) { + case 0: /* Auto */ + switch (u1) { + /* + * According to the Thunderbolt Manual, the + * first byte of the supplemental timing packet + * simply indicates the configuration of the + * device, not the actual lock, so we need to + * look at the decode status. + */ + case 0: /* "Doing Fixes" */ + session->newdata.mode = MODE_3D; + break; + case 0x0B: /* "Only 3 usable sats" */ + session->newdata.mode = MODE_2D; + break; + case 0x1: /* "Don't have GPS time" */ + case 0x3: /* "PDOP is too high" */ + case 0x8: /* "No usable sats" */ + case 0x9: /* "Only 1 usable sat" */ + case 0x0A: /* "Only 2 usable sats */ + case 0x0C: /* "The chosen sat is unusable" */ + case 0x10: /* TRAIM rejected the fix */ + default: + session->newdata.mode = MODE_NO_FIX; + } + break; + case 6: /* Clock Hold 2D */ + case 3: /* 2D Position Fix */ + //session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_2D; + break; + case 7: /* Thunderbolt overdetermined clock */ + case 4: /* 3D position Fix */ + //session->gpsdata.status = STATUS_FIX; + session->newdata.mode = MODE_3D; + break; + default: + //session->gpsdata.status = STATUS_NO_FIX; + session->newdata.mode = MODE_NO_FIX; + break; + } + + mask |= LATLON_IS | ALTITUDE_IS | MODE_IS | REPORT_IS; + gpsd_report(LOG_DATA, "SP-TPS 0xac " + "time=%.2f lat=%.2f lon=%.2f alt=%.2f mask=%s\n", + session->newdata.time, + session->newdata.latitude, + session->newdata.longitude, + session->newdata.altitude, gpsd_maskdump(mask)); + break; + + + default: + gpsd_report(LOG_WARN, "Unhandled TSIP superpacket type 0x%02x\n", + u1); + } + break; + case 0xbb: /* Navigation Configuration */ + if (len != 40) + break; + u1 = getub(buf, 0); /* Subcode */ + u2 = getub(buf, 1); /* Operating Dimension */ + u3 = getub(buf, 2); /* DGPS Mode */ + u4 = getub(buf, 3); /* Dynamics Code */ + f1 = getbef(buf, 5); /* Elevation Mask */ + f2 = getbef(buf, 9); /* AMU Mask */ + f3 = getbef(buf, 13); /* DOP Mask */ + f4 = getbef(buf, 17); /* DOP Switch */ + u5 = getub(buf, 21); /* DGPS Age Limit */ + gpsd_report(LOG_INF, + "Navigation Configuration %u %u %u %u %f %f %f %f %u\n", + u1, u2, u3, u4, f1, f2, f3, f4, u5); + break; + default: + gpsd_report(LOG_WARN, "Unhandled TSIP packet type 0x%02x\n", id); + break; + } + + /* see if it is time to send some request packets for reports that */ + /* the receiver won't send at fixed intervals */ + + if ((now - session->driver.tsip.last_41) > 5) { + /* Request Current Time */ + (void)tsip_write(session, 0x21, buf, 0); + session->driver.tsip.last_41 = now; + } + + if ((now - session->driver.tsip.last_6d) > 5) { + /* Request GPS Receiver Position Fix Mode */ + (void)tsip_write(session, 0x24, buf, 0); + session->driver.tsip.last_6d = now; + } + + if ((now - session->driver.tsip.last_48) > 60) { + /* Request GPS System Message */ + (void)tsip_write(session, 0x28, buf, 0); + session->driver.tsip.last_48 = now; + } + + if ((now - session->driver.tsip.last_5c) >= 5) { + /* Request Current Satellite Tracking Status */ + putbyte(buf, 0, 0x00); /* All satellites */ + (void)tsip_write(session, 0x3c, buf, 1); + session->driver.tsip.last_5c = now; + } + + if ((now - session->driver.tsip.last_46) > 5) { + /* Request Health of Receiver */ + (void)tsip_write(session, 0x26, buf, 0); + session->driver.tsip.last_46 = now; + } +#if USE_SUPERPACKET + if ((session->driver.tsip.req_compact > 0) && + ((now - session->driver.tsip.req_compact) > 5)) { + /* Compact Superpacket requested but no response */ + session->driver.tsip.req_compact = 0; + gpsd_report(LOG_WARN, "No Compact Super Packet, use LFwEI\n"); + + /* Request LFwEI Super Packet */ + putbyte(buf, 0, 0x20); + putbyte(buf, 1, 0x01); /* enabled */ + (void)tsip_write(session, 0x8e, buf, 2); + } +#endif /* USE_SUPERPACKET */ + + return mask; +} + +static gps_mask_t tsip_parse_input(struct gps_device_t *session) +{ + gps_mask_t st; + + if (session->packet.type == TSIP_PACKET) { + st = tsip_analyze(session); + session->gpsdata.dev.driver_mode = MODE_BINARY; + return st; +#ifdef EVERMORE_ENABLE + } else if (session->packet.type == EVERMORE_PACKET) { + (void)gpsd_switch_driver(session, "EverMore binary"); + st = evermore_parse(session, session->packet.outbuffer, + session->packet.outbuflen); + session->gpsdata.dev.driver_mode = MODE_BINARY; + return st; +#endif /* EVERMORE_ENABLE */ +#ifdef SIRF_ENABLE + /* + * mrd reported that once every couple of weeks his SiRF was flipping + * into Trimble binary mode and not recovering. Damn Trimble for not + * checksumming their packets, it makes false positives hard to reject. + * This should enable the SiRF to recover. + */ + } else if (session->packet.type == SIRF_PACKET) { + (void)gpsd_switch_driver(session, "SiRF binary"); + st = sirf_parse(session, session->packet.outbuffer, + session->packet.outbuflen); + session->gpsdata.dev.driver_mode = MODE_BINARY; + return st; +#endif /* SIRF_ENABLE */ + } else + return 0; +} + +#ifdef ALLOW_CONTROLSEND +static ssize_t tsip_control_send(struct gps_device_t *session, + char *buf, size_t buflen) +/* not used by the daemon, it's for gpsctl and friends */ +{ + return (ssize_t) tsip_write(session, + (unsigned int)buf[0], + (unsigned char *)buf + 1, buflen - 1); +} +#endif /* ALLOW_CONTROLSEND */ + +static void tsip_event_hook(struct gps_device_t *session, event_t event) +{ + /* FIX-ME: Resending this might not be needed on reactivation */ + if (event == event_identified && event == event_reactivate) { + unsigned char buf[100]; + + /* I/O Options */ + putbyte(buf, 0, 0x1e); /* Position: DP, MSL, LLA */ + putbyte(buf, 1, 0x02); /* Velocity: ENU */ + putbyte(buf, 2, 0x00); /* Time: GPS */ + putbyte(buf, 3, 0x08); /* Aux: dBHz */ + (void)tsip_write(session, 0x35, buf, 4); + } + if (event == event_configure) { + unsigned char buf[100]; + union int_float i_f; + + switch (session->packet.counter) { + case 0: + /* + * TSIP is ODD parity 1 stopbit, save original values and + * change it Thunderbolts and Copernicus use + * 8N1... which isn't exactly a good idea due to the + * fragile wire format. We must divine a clever + * heuristic to decide if the parity change is required. + */ + session->driver.tsip.parity = session->gpsdata.dev.parity; + session->driver.tsip.stopbits = + (uint) session->gpsdata.dev.stopbits; + // gpsd_set_speed(session, session->gpsdata.dev.baudrate, 'O', 1); + break; + + case 1: + /*@ -shiftimplementation @*/ + /* Request Software Versions */ + (void)tsip_write(session, 0x1f, NULL, 0); + /* Request Current Time */ + (void)tsip_write(session, 0x21, NULL, 0); + /* Set Operating Parameters */ + /* - dynamic code: land */ + putbyte(buf, 0, 0x01); + /* - elevation mask */ + i_f.f = 5.0 * DEG_2_RAD; + putbelong(buf, 1, i_f.i); + /* - signal level mask */ + i_f.f = 6.0; + putbelong(buf, 5, i_f.i); + /* - PDOP mask */ + i_f.f = 8.0; + putbelong(buf, 9, i_f.i); + /* - PDOP switch */ + i_f.f = 6.0; + putbelong(buf, 13, i_f.i); + /*@ +shiftimplementation @*/ + (void)tsip_write(session, 0x2c, buf, 17); + /* Set Position Fix Mode (auto 2D/3D) */ + putbyte(buf, 0, 0x00); + (void)tsip_write(session, 0x22, buf, 1); + /* Request GPS Systems Message */ + (void)tsip_write(session, 0x28, NULL, 0); + /* Request Current Datum Values */ + (void)tsip_write(session, 0x37, NULL, 0); + putbyte(buf, 0, 0x15); + (void)tsip_write(session, 0x8e, buf, 1); + /* Request Navigation Configuration */ + putbyte(buf, 0, 0x03); + (void)tsip_write(session, 0xbb, buf, 1); + break; + } + } + if (event == event_deactivate) { + /* restore saved parity and stopbits when leaving TSIP mode */ + gpsd_set_speed(session, + session->gpsdata.dev.baudrate, + session->driver.tsip.parity, + session->driver.tsip.stopbits); + } +} + +#ifdef ALLOW_RECONFIGURE +static bool tsip_speed_switch(struct gps_device_t *session, + speed_t speed, char parity, int stopbits) +{ + unsigned char buf[100]; + + switch (parity) { + case 'E': + case 2: + parity = (char)2; + break; + case 'O': + case 1: + parity = (char)1; + break; + case 'N': + case 0: + default: + parity = (char)0; + break; + } + + putbyte(buf, 0, 0xff); /* current port */ + putbyte(buf, 1, (round(log((double)speed / 300) / M_LN2)) + 2); /* input dev.baudrate */ + putbyte(buf, 2, getub(buf, 1)); /* output baudrate */ + putbyte(buf, 3, 3); /* character width (8 bits) */ + putbyte(buf, 4, parity); /* parity (normally odd) */ + putbyte(buf, 5, stopbits - 1); /* stop bits (normally 1 stopbit) */ + putbyte(buf, 6, 0); /* flow control (none) */ + putbyte(buf, 7, 0x02); /* input protocol (TSIP) */ + putbyte(buf, 8, 0x02); /* output protocol (TSIP) */ + putbyte(buf, 9, 0); /* reserved */ + (void)tsip_write(session, 0xbc, buf, 10); + + return true; /* it would be nice to error-check this */ +} + +static void tsip_mode(struct gps_device_t *session, int mode) +{ + unsigned char buf[16]; + + if (mode == MODE_NMEA) { + /* First turn on the NMEA messages we want */ + + putbyte(buf, 0, 0x00); /* subcode 0 */ + putbyte(buf, 1, 0x01); /* 1-second fix interval */ + putbyte(buf, 2, 0x00); /* Reserved */ + putbyte(buf, 3, 0x00); /* Reserved */ + putbyte(buf, 4, 0x01); /* 0=RMC, 1-7=Reserved */ + putbyte(buf, 5, 0x19); /* 0=GGA, 1=GGL, 2=VTG, 3=GSV, */ + /* 4=GSA, 5=ZDA, 6-7=Reserved */ + + (void)tsip_write(session, 0x7A, buf, 6); + + /* Now switch to NMEA mode */ + + memset(buf, 0, sizeof(buf)); + + putbyte(buf, 0, 0xff); /* current port */ + putbyte(buf, 1, 0x06); /* 4800 bps input */ + putbyte(buf, 2, 0x06); /* 4800 bps output */ + putbyte(buf, 3, 0x03); /* 8 data bits */ + putbyte(buf, 4, 0x00); /* No parity */ + putbyte(buf, 5, 0x00); /* 1 stop bit */ + putbyte(buf, 6, 0x00); /* No flow control */ + putbyte(buf, 7, 0x02); /* Input protocol TSIP */ + putbyte(buf, 8, 0x04); /* Output protocol NMEA */ + putbyte(buf, 9, 0x00); /* Reserved */ + + (void)tsip_write(session, 0xBC, buf, 10); + + } else if (mode == MODE_BINARY) { + /* The speed switcher also puts us back in TSIP, so call it */ + /* with the default 9600 8O1. */ + // FIX-ME: Should preserve the current speed. + // (void)tsip_speed_switch(session, 9600, 'O', 1); + ; + + } else { + gpsd_report(LOG_ERROR, "unknown mode %i requested\n", mode); + } +} +#endif /* ALLOW_RECONFIGURE */ + +#ifdef NTPSHM_ENABLE +static double tsip_ntp_offset(struct gps_device_t *session) +{ + /* FIX-ME: is a constant offset right here? */ + return 0.075; +} +#endif /* NTPSHM_ENABLE */ + +/* this is everything we export */ +/* *INDENT-OFF* */ +const struct gps_type_t tsip_binary = +{ + .type_name = "Trimble TSIP", /* full name of type */ + .packet_type = TSIP_PACKET, /* associated lexer packet type */ + .trigger = NULL, /* no trigger */ + .channels = TSIP_CHANNELS, /* consumer-grade GPS */ + .probe_detect = tsip_detect, /* probe for 9600O81 device */ + .get_packet = generic_get, /* use the generic packet getter */ + .parse_packet = tsip_parse_input, /* parse message packets */ + .rtcm_writer = NULL, /* doesn't accept DGPS corrections */ + .event_hook = tsip_event_hook, /* ifire on various lifetime events */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = tsip_speed_switch,/* change baud rate */ + .mode_switcher = tsip_mode, /* there is a mode switcher */ + .rate_switcher = NULL, /* no rate switcher */ + .min_cycle = 1, /* not relevant, no rate switcher */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = tsip_control_send,/* how to send commands */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = tsip_ntp_offset, +#endif /* NTPSHM_ENABLE */ +}; +/* *INDENT-ON* */ + +#endif /* TSIP_ENABLE */ diff --git a/driver_ubx.c b/driver_ubx.c new file mode 100644 index 0000000..f932417 --- /dev/null +++ b/driver_ubx.c @@ -0,0 +1,789 @@ +/* + * UBX driver + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + */ + +#include +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd.h" +#if defined(UBX_ENABLE) && defined(BINARY_ENABLE) +#include "driver_ubx.h" + +#include "bits.h" + +/* + * A ubx packet looks like this: + * leader: 0xb5 0x62 + * message class: 1 byte + * message type: 1 byte + * length of payload: 2 bytes + * payload: variable length + * checksum: 2 bytes + * + * see also the FV25 and UBX documents on reference.html + */ + +static gps_mask_t ubx_parse(struct gps_device_t *session, unsigned char *buf, + size_t len); +static gps_mask_t ubx_msg_nav_sol(struct gps_device_t *session, + unsigned char *buf, size_t data_len); +static gps_mask_t ubx_msg_nav_dop(struct gps_device_t *session, + unsigned char *buf, size_t data_len); +static gps_mask_t ubx_msg_nav_timegps(struct gps_device_t *session, + unsigned char *buf, size_t data_len); +static gps_mask_t ubx_msg_nav_svinfo(struct gps_device_t *session, + unsigned char *buf, size_t data_len); +static void ubx_msg_sbas(struct gps_device_t *session, unsigned char *buf); +static void ubx_msg_inf(unsigned char *buf, size_t data_len); + +/** + * Navigation solution message + */ +static gps_mask_t +ubx_msg_nav_sol(struct gps_device_t *session, unsigned char *buf, + size_t data_len) +{ + unsigned short gw; + unsigned int tow, flags; + double epx, epy, epz, evx, evy, evz; + unsigned char navmode; + gps_mask_t mask; + double t; + + if (data_len != 52) + return 0; + + flags = (unsigned int)getub(buf, 11); + mask = 0; + if ((flags & (UBX_SOL_VALID_WEEK | UBX_SOL_VALID_TIME)) != 0) { + tow = (unsigned int)getleul(buf, 0); + gw = (unsigned short)getlesw(buf, 8); + session->context->gps_week = gw; + session->context->gps_tow = tow / 1000.0; + + t = gpstime_to_unix((int)session->context->gps_week, + session->context->gps_tow) + - session->context->leap_seconds; + session->newdata.time = t; + mask |= TIME_IS; + } + + epx = (double)(getlesl(buf, 12) / 100.0); + epy = (double)(getlesl(buf, 16) / 100.0); + epz = (double)(getlesl(buf, 20) / 100.0); + evx = (double)(getlesl(buf, 28) / 100.0); + evy = (double)(getlesl(buf, 32) / 100.0); + evz = (double)(getlesl(buf, 36) / 100.0); + ecef_to_wgs84fix(&session->newdata, &session->gpsdata.separation, + epx, epy, epz, evx, evy, evz); + mask |= LATLON_IS | ALTITUDE_IS | SPEED_IS | TRACK_IS | CLIMB_IS; + session->newdata.epx = session->newdata.epy = + (double)(getlesl(buf, 24) / 100.0) / sqrt(2); + session->newdata.eps = (double)(getlesl(buf, 40) / 100.0); + /* Better to have a single point of truth about DOPs */ + //session->gpsdata.dop.pdop = (double)(getleuw(buf, 44)/100.0); + session->gpsdata.satellites_used = (int)getub(buf, 47); + + navmode = (unsigned char)getub(buf, 10); + switch (navmode) { + case UBX_MODE_TMONLY: + case UBX_MODE_3D: + session->newdata.mode = MODE_3D; + break; + case UBX_MODE_2D: + case UBX_MODE_DR: /* consider this too as 2D */ + case UBX_MODE_GPSDR: /* FIX-ME: DR-aided GPS may be valid 3D */ + session->newdata.mode = MODE_2D; + break; + default: + session->newdata.mode = MODE_NO_FIX; + } + + if ((flags & UBX_SOL_FLAG_DGPS) != 0) + session->gpsdata.status = STATUS_DGPS_FIX; + else if (session->newdata.mode != MODE_NO_FIX) + session->gpsdata.status = STATUS_FIX; + + mask |= MODE_IS | STATUS_IS; + gpsd_report(LOG_DATA, + "NAVSOL: time=%.2f lat=%.2f lon=%.2f alt=%.2f track=%.2f speed=%.2f climb=%.2f mode=%d status=%d used=%d mask=%s\n", + session->newdata.time, + session->newdata.latitude, + session->newdata.longitude, + session->newdata.altitude, + session->newdata.track, + session->newdata.speed, + session->newdata.climb, + session->newdata.mode, + session->gpsdata.status, + session->gpsdata.satellites_used, gpsd_maskdump(mask)); + return mask; +} + +/** + * Dilution of precision message + */ +static gps_mask_t +ubx_msg_nav_dop(struct gps_device_t *session, unsigned char *buf, + size_t data_len) +{ + if (data_len != 18) + return 0; + + /* + * We make a deliberate choice not to clear DOPs from the + * last skyview here, but rather to treat this as a supplement + * to our calculations from the visiniolity matrix, trusting + * the firmware algorithms over ours. + */ + session->gpsdata.dop.gdop = (double)(getleuw(buf, 4) / 100.0); + session->gpsdata.dop.pdop = (double)(getleuw(buf, 6) / 100.0); + session->gpsdata.dop.tdop = (double)(getleuw(buf, 8) / 100.0); + session->gpsdata.dop.vdop = (double)(getleuw(buf, 10) / 100.0); + session->gpsdata.dop.hdop = (double)(getleuw(buf, 12) / 100.0); + gpsd_report(LOG_DATA, "NAVDOP: gdop=%.2f pdop=%.2f " + "hdop=%.2f vdop=%.2f tdop=%.2f mask={DOP}\n", + session->gpsdata.dop.gdop, + session->gpsdata.dop.hdop, + session->gpsdata.dop.vdop, + session->gpsdata.dop.pdop, session->gpsdata.dop.tdop); + return DOP_IS; +} + +/** + * GPS Leap Seconds + */ +static gps_mask_t +ubx_msg_nav_timegps(struct gps_device_t *session, unsigned char *buf, + size_t data_len) +{ + unsigned int gw, tow, flags; + double t; + + if (data_len != 16) + return 0; + + tow = (unsigned int)getleul(buf, 0); + gw = (unsigned int)getlesw(buf, 8); + if (gw > session->context->gps_week) + session->context->gps_week = (unsigned short)gw; + + flags = (unsigned int)getub(buf, 11); + if ((flags & 0x7) != 0) + session->context->leap_seconds = (int)getub(buf, 10); + + session->context->gps_tow = tow / 1000.0; + t = gpstime_to_unix((int)session->context->gps_week, + session->context->gps_tow) + - session->context->leap_seconds; + session->newdata.time = t; + + gpsd_report(LOG_DATA, "TIMEGPS: time=%.2f mask={TIME}\n", + session->newdata.time); + return TIME_IS; +} + +/** + * GPS Satellite Info + */ +static gps_mask_t +ubx_msg_nav_svinfo(struct gps_device_t *session, unsigned char *buf, + size_t data_len) +{ + unsigned int i, j, nchan, nsv, st; + + if (data_len < 152) { + gpsd_report(LOG_PROG, "runt svinfo (datalen=%zd)\n", data_len); + return 0; + } + /*@ +charint @*/ + nchan = (unsigned int)getub(buf, 4); + if (nchan > MAXCHANNELS) { + gpsd_report(LOG_WARN, + "Invalid NAV SVINFO message, >%d reported visible", + MAXCHANNELS); + return 0; + } + /*@ -charint @*/ + gpsd_zero_satellites(&session->gpsdata); + nsv = 0; + for (i = j = st = 0; i < nchan; i++) { + unsigned int off = 8 + 12 * i; + if ((int)getub(buf, off + 4) == 0) + continue; /* LEA-5H seems to have a bug reporting sats it does not see or hear */ + session->gpsdata.PRN[j] = (int)getub(buf, off + 1); + session->gpsdata.ss[j] = (float)getub(buf, off + 4); + session->gpsdata.elevation[j] = (int)getsb(buf, off + 5); + session->gpsdata.azimuth[j] = (int)getlesw(buf, off + 6); + if (session->gpsdata.PRN[j]) + st++; + /*@ -predboolothers */ + if (getub(buf, off + 2) & 0x01) + session->gpsdata.used[nsv++] = session->gpsdata.PRN[j]; + if (session->gpsdata.PRN[j] == (int)session->driver.ubx.sbas_in_use) + session->gpsdata.used[nsv++] = session->gpsdata.PRN[j]; + /*@ +predboolothers */ + j++; + } + session->gpsdata.skyview_time = NAN; + session->gpsdata.satellites_visible = (int)st; + session->gpsdata.satellites_used = (int)nsv; + gpsd_report(LOG_DATA, + "SVINFO: visible=%d used=%d mask={SATELLITE|USED}\n", + session->gpsdata.satellites_visible, + session->gpsdata.satellites_used); + return SATELLITE_IS | USED_IS; +} + +/* + * SBAS Info + */ +static void ubx_msg_sbas(struct gps_device_t *session, unsigned char *buf) +{ +#ifdef UBX_SBAS_DEBUG + unsigned int i, nsv; + + gpsd_report(LOG_WARN, "SBAS: %d %d %d %d %d\n", + (int)getub(buf, 4), (int)getub(buf, 5), (int)getub(buf, 6), + (int)getub(buf, 7), (int)getub(buf, 8)); + + nsv = (int)getub(buf, 8); + for (i = 0; i < nsv; i++) { + int off = 12 + 12 * i; + gpsd_report(LOG_WARN, "SBAS info on SV: %d\n", (int)getub(buf, off)); + } +#endif +/* really 'in_use' depends on the sats info, EGNOS is still in test */ +/* In WAAS areas one might also check for the type of corrections indicated */ + session->driver.ubx.sbas_in_use = (unsigned char)getub(buf, 4); +} + +/* + * Raw Subframes + */ +static void ubx_msg_sfrb(struct gps_device_t *session, unsigned char *buf) +{ + unsigned int i, words[10], chan, svid; + + chan = (unsigned int)getub(buf, 0); + svid = (unsigned int)getub(buf, 1); + gpsd_report(LOG_PROG, "UBX_RXM_SFRB: %u %u\n", chan, svid); + + /* UBX does all the parity checking, but still bad data gets through */ + for (i = 0; i < 10; i++) { + words[i] = (unsigned int)getleul(buf, 4 * i + 2) & 0xffffff; + } + + gpsd_interpret_subframe(session, words); +} + +static void ubx_msg_inf(unsigned char *buf, size_t data_len) +{ + unsigned short msgid; + static char txtbuf[MAX_PACKET_LENGTH]; + + msgid = (unsigned short)((buf[2] << 8) | buf[3]); + if (data_len > MAX_PACKET_LENGTH - 1) + data_len = MAX_PACKET_LENGTH - 1; + + (void)strlcpy(txtbuf, (char *)buf + 6, MAX_PACKET_LENGTH); + txtbuf[data_len] = '\0'; + switch (msgid) { + case UBX_INF_DEBUG: + gpsd_report(LOG_PROG, "UBX_INF_DEBUG: %s\n", txtbuf); + break; + case UBX_INF_TEST: + gpsd_report(LOG_PROG, "UBX_INF_TEST: %s\n", txtbuf); + break; + case UBX_INF_NOTICE: + gpsd_report(LOG_INF, "UBX_INF_NOTICE: %s\n", txtbuf); + break; + case UBX_INF_WARNING: + gpsd_report(LOG_WARN, "UBX_INF_WARNING: %s\n", txtbuf); + break; + case UBX_INF_ERROR: + gpsd_report(LOG_WARN, "UBX_INF_ERROR: %s\n", txtbuf); + break; + default: + break; + } + return; +} + +/*@ +charint @*/ +gps_mask_t ubx_parse(struct gps_device_t * session, unsigned char *buf, + size_t len) +{ + size_t data_len; + unsigned short msgid; + gps_mask_t mask = 0; + int i; + + if (len < 6) /* the packet at least contains a head of six bytes */ + return 0; + + session->cycle_end_reliable = true; + + /* extract message id and length */ + msgid = (buf[2] << 8) | buf[3]; + data_len = (size_t) getlesw(buf, 4); + switch (msgid) { + case UBX_NAV_POSECEF: + gpsd_report(LOG_IO, "UBX_NAV_POSECEF\n"); + break; + case UBX_NAV_POSLLH: + gpsd_report(LOG_IO, "UBX_NAV_POSLLH\n"); + break; + case UBX_NAV_STATUS: + gpsd_report(LOG_IO, "UBX_NAV_STATUS\n"); + break; + case UBX_NAV_DOP: + gpsd_report(LOG_PROG, "UBX_NAV_DOP\n"); + mask = ubx_msg_nav_dop(session, &buf[6], data_len); + break; + case UBX_NAV_SOL: + gpsd_report(LOG_PROG, "UBX_NAV_SOL\n"); + mask = + ubx_msg_nav_sol(session, &buf[6], + data_len) | (CLEAR_IS | REPORT_IS); + break; + case UBX_NAV_POSUTM: + gpsd_report(LOG_IO, "UBX_NAV_POSUTM\n"); + break; + case UBX_NAV_VELECEF: + gpsd_report(LOG_IO, "UBX_NAV_VELECEF\n"); + break; + case UBX_NAV_VELNED: + gpsd_report(LOG_IO, "UBX_NAV_VELNED\n"); + break; + case UBX_NAV_TIMEGPS: + gpsd_report(LOG_PROG, "UBX_NAV_TIMEGPS\n"); + mask = ubx_msg_nav_timegps(session, &buf[6], data_len); + break; + case UBX_NAV_TIMEUTC: + gpsd_report(LOG_IO, "UBX_NAV_TIMEUTC\n"); + break; + case UBX_NAV_CLOCK: + gpsd_report(LOG_IO, "UBX_NAV_CLOCK\n"); + break; + case UBX_NAV_SVINFO: + gpsd_report(LOG_PROG, "UBX_NAV_SVINFO\n"); + mask = ubx_msg_nav_svinfo(session, &buf[6], data_len); + break; + case UBX_NAV_DGPS: + gpsd_report(LOG_IO, "UBX_NAV_DGPS\n"); + break; + case UBX_NAV_SBAS: + gpsd_report(LOG_IO, "UBX_NAV_SBAS\n"); + ubx_msg_sbas(session, &buf[6]); + break; + case UBX_NAV_EKFSTATUS: + gpsd_report(LOG_IO, "UBX_NAV_EKFSTATUS\n"); + break; + + case UBX_RXM_RAW: + gpsd_report(LOG_IO, "UBX_RXM_RAW\n"); + break; + case UBX_RXM_SFRB: + ubx_msg_sfrb(session, &buf[6]); + break; + case UBX_RXM_SVSI: + gpsd_report(LOG_PROG, "UBX_RXM_SVSI\n"); + break; + case UBX_RXM_ALM: + gpsd_report(LOG_IO, "UBX_RXM_ALM\n"); + break; + case UBX_RXM_EPH: + gpsd_report(LOG_IO, "UBX_RXM_EPH\n"); + break; + case UBX_RXM_POSREQ: + gpsd_report(LOG_IO, "UBX_RXM_POSREQ\n"); + break; + + case UBX_MON_SCHED: + gpsd_report(LOG_IO, "UBX_MON_SCHED\n"); + break; + case UBX_MON_IO: + gpsd_report(LOG_IO, "UBX_MON_IO\n"); + break; + case UBX_MON_IPC: + gpsd_report(LOG_IO, "UBX_MON_IPC\n"); + break; + case UBX_MON_VER: + gpsd_report(LOG_IO, "UBX_MON_VER\n"); + break; + case UBX_MON_EXCEPT: + gpsd_report(LOG_IO, "UBX_MON_EXCEPT\n"); + break; + case UBX_MON_MSGPP: + gpsd_report(LOG_IO, "UBX_MON_MSGPP\n"); + break; + case UBX_MON_RXBUF: + gpsd_report(LOG_IO, "UBX_MON_RXBUF\n"); + break; + case UBX_MON_TXBUF: + gpsd_report(LOG_IO, "UBX_MON_TXBUF\n"); + break; + case UBX_MON_HW: + gpsd_report(LOG_IO, "UBX_MON_HW\n"); + break; + case UBX_MON_USB: + gpsd_report(LOG_IO, "UBX_MON_USB\n"); + break; + + case UBX_INF_DEBUG: + /* FALLTHROUGH */ + case UBX_INF_TEST: + /* FALLTHROUGH */ + case UBX_INF_NOTICE: + /* FALLTHROUGH */ + case UBX_INF_WARNING: + /* FALLTHROUGH */ + case UBX_INF_ERROR: + ubx_msg_inf(buf, data_len); + break; + + case UBX_TIM_TP: + gpsd_report(LOG_IO, "UBX_TIM_TP\n"); + break; + case UBX_TIM_TM: + gpsd_report(LOG_IO, "UBX_TIM_TM\n"); + break; + case UBX_TIM_TM2: + gpsd_report(LOG_IO, "UBX_TIM_TM2\n"); + break; + case UBX_TIM_SVIN: + gpsd_report(LOG_IO, "UBX_TIM_SVIN\n"); + break; + + case UBX_CFG_PRT: + gpsd_report(LOG_IO, "UBX_CFG_PRT\n"); + for (i = 6; i < 26; i++) + session->driver.ubx.original_port_settings[i - 6] = buf[i]; /* copy the original port settings */ + buf[14 + 6] &= ~0x02; /* turn off NMEA output on this port */ + (void)ubx_write(session, 0x06, 0x00, &buf[6], 20); /* send back with all other settings intact */ + session->driver.ubx.have_port_configuration = true; + break; + + case UBX_ACK_NAK: + gpsd_report(LOG_IO, "UBX_ACK_NAK, class: %02x, id: %02x\n", buf[6], + buf[7]); + break; + case UBX_ACK_ACK: + gpsd_report(LOG_IO, "UBX_ACK_ACK, class: %02x, id: %02x\n", buf[6], + buf[7]); + break; + + default: + gpsd_report(LOG_WARN, + "UBX: unknown packet id 0x%04hx (length %zd) %s\n", + msgid, len, gpsd_hexdump_wrapper(buf, len, LOG_WARN)); + } + + if (mask) + (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), + "0x%04hx", msgid); + + return mask | ONLINE_IS; +} + +/*@ -charint @*/ + +static gps_mask_t parse_input(struct gps_device_t *session) +{ + gps_mask_t st; + + if (session->packet.type == UBX_PACKET) { + st = ubx_parse(session, session->packet.outbuffer, + session->packet.outbuflen); + session->gpsdata.dev.driver_mode = MODE_BINARY; + return st; +#ifdef NMEA_ENABLE + } else if (session->packet.type == NMEA_PACKET) { + st = nmea_parse((char *)session->packet.outbuffer, session); + session->gpsdata.dev.driver_mode = MODE_NMEA; + return st; +#endif /* NMEA_ENABLE */ + } else + return 0; +} + +bool ubx_write(struct gps_device_t * session, + unsigned int msg_class, unsigned int msg_id, + unsigned char *msg, unsigned short data_len) +{ + unsigned char CK_A, CK_B; + ssize_t i, count; + bool ok; + + /*@ -type @*/ + session->msgbuf[0] = 0xb5; + session->msgbuf[1] = 0x62; + + CK_A = CK_B = 0; + session->msgbuf[2] = msg_class; + session->msgbuf[3] = msg_id; + session->msgbuf[4] = data_len & 0xff; + session->msgbuf[5] = (data_len >> 8) & 0xff; + + assert(msg != NULL || data_len == 0); + if (msg != NULL) + (void)memcpy(&session->msgbuf[6], msg, data_len); + + /* calculate CRC */ + for (i = 2; i < 6; i++) { + CK_A += session->msgbuf[i]; + CK_B += CK_A; + } + /*@ -nullderef @*/ + for (i = 0; i < data_len; i++) { + CK_A += msg[i]; + CK_B += CK_A; + } + + session->msgbuf[6 + data_len] = CK_A; + session->msgbuf[7 + data_len] = CK_B; + session->msgbuflen = data_len + 8; + /*@ +type @*/ + + gpsd_report(LOG_IO, + "=> GPS: UBX class: %02x, id: %02x, len: %d, data:%s, crc: %02x%02x\n", + msg_class, msg_id, data_len, + gpsd_hexdump_wrapper(msg, (size_t) data_len, LOG_IO), + CK_A, CK_B); + + count = write(session->gpsdata.gps_fd, + session->msgbuf, session->msgbuflen); + (void)tcdrain(session->gpsdata.gps_fd); + ok = (count == (ssize_t) session->msgbuflen); + /*@ +nullderef @*/ + return (ok); +} + +#ifdef ALLOW_CONTROLSEND +static ssize_t ubx_control_send(struct gps_device_t *session, char *msg, + size_t data_len) +/* not used by gpsd, it's for gpsctl and friends */ +{ + return ubx_write(session, (unsigned int)msg[0], (unsigned int)msg[1], + (unsigned char *)msg + 2, + (unsigned short)(data_len - 2)) ? ((ssize_t) (data_len + + 7)) : -1; +} +#endif /* ALLOW_CONTROLSEND */ + +static void ubx_catch_model(struct gps_device_t *session, unsigned char *buf, + size_t len) +{ + /*@ +charint */ + unsigned char *ip = &buf[19]; + unsigned char *op = (unsigned char *)session->subtype; + size_t end = ((len - 19) < 63) ? (len - 19) : 63; + size_t i; + + for (i = 0; i < end; i++) { + if ((*ip == 0x00) || (*ip == '*')) { + *op = 0x00; + break; + } + *(op++) = *(ip++); + } + /*@ -charint */ +} + +static void ubx_event_hook(struct gps_device_t *session, event_t event) +{ + if (event == event_triggermatch) + ubx_catch_model(session, + session->packet.outbuffer, session->packet.outbuflen); + else if (event == event_identified || event == event_reactivate) { + unsigned char msg[32]; + + gpsd_report(LOG_IO, "UBX configure: %d\n", session->packet.counter); + + (void)ubx_write(session, 0x06u, 0x00, NULL, 0); /* get this port's settings */ + + /*@ -type @*/ + msg[0] = 0x03; /* SBAS mode enabled, accept testbed mode */ + msg[1] = 0x07; /* SBAS usage: range, differential corrections and integrity */ + msg[2] = 0x03; /* use the maximun search range: 3 channels */ + msg[3] = 0x00; /* PRN numbers to search for all set to 0 => auto scan */ + msg[4] = 0x00; + msg[5] = 0x00; + msg[6] = 0x00; + msg[7] = 0x00; + (void)ubx_write(session, 0x06u, 0x16, msg, 8); + + msg[0] = 0x01; /* class */ + msg[1] = 0x04; /* msg id = UBX_NAV_DOP */ + msg[2] = 0x01; /* rate */ + (void)ubx_write(session, 0x06u, 0x01, msg, 3); + msg[0] = 0x01; /* class */ + msg[1] = 0x06; /* msg id = NAV-SOL */ + msg[2] = 0x01; /* rate */ + (void)ubx_write(session, 0x06u, 0x01, msg, 3); + msg[0] = 0x01; /* class */ + msg[1] = 0x20; /* msg id = UBX_NAV_TIMEGPS */ + msg[2] = 0x01; /* rate */ + (void)ubx_write(session, 0x06u, 0x01, msg, 3); + msg[0] = 0x01; /* class */ + msg[1] = 0x30; /* msg id = NAV-SVINFO */ + msg[2] = 0x0a; /* rate */ + (void)ubx_write(session, 0x06u, 0x01, msg, 3); + msg[0] = 0x01; /* class */ + msg[1] = 0x32; /* msg id = NAV-SBAS */ + msg[2] = 0x0a; /* rate */ + (void)ubx_write(session, 0x06u, 0x01, msg, 3); + /*@ +type @*/ + } else if (event == event_deactivate) { + /*@ -type @*/ + unsigned char msg[4] = { + 0x00, 0x00, /* hotstart */ + 0x01, /* controlled software reset */ + 0x00 + }; /* reserved */ + /*@ +type @*/ + + gpsd_report(LOG_IO, "UBX revert\n"); + + /* Reverting all in one fast and reliable reset */ + (void)ubx_write(session, 0x06, 0x04, msg, 4); /* CFG-RST */ + } +} + +#ifdef ALLOW_RECONFIGURE +static void ubx_nmea_mode(struct gps_device_t *session, int mode) +{ + int i; + unsigned char buf[sizeof(session->driver.ubx.original_port_settings)]; + + if (!session->driver.ubx.have_port_configuration) + return; + + /*@ +charint -usedef @*/ + for (i = 0; i < (int)sizeof(session->driver.ubx.original_port_settings); + i++) + buf[i] = session->driver.ubx.original_port_settings[i]; /* copy the original port settings */ + if (buf[0] == 0x01) /* set baudrate on serial port only */ + putlelong(buf, 8, session->gpsdata.dev.baudrate); + + if (mode == MODE_NMEA) { + buf[14] &= ~0x01; /* turn off UBX output on this port */ + buf[14] |= 0x02; /* turn on NMEA output on this port */ + } else { /* MODE_BINARY */ + buf[14] &= ~0x02; /* turn off NMEA output on this port */ + buf[14] |= 0x01; /* turn on UBX output on this port */ + } + /*@ -charint +usedef @*/ + (void)ubx_write(session, 0x06u, 0x00, &buf[6], 20); /* send back with all other settings intact */ +} + +static bool ubx_speed(struct gps_device_t *session, + speed_t speed, char parity, int stopbits) +{ + int i; + unsigned char buf[sizeof(session->driver.ubx.original_port_settings)]; + unsigned long usart_mode; + + /*@ +charint -usedef -compdef */ + for (i = 0; i < (int)sizeof(session->driver.ubx.original_port_settings); + i++) + buf[i] = session->driver.ubx.original_port_settings[i]; /* copy the original port settings */ + if ((!session->driver.ubx.have_port_configuration) || (buf[0] != 0x01)) /* set baudrate on serial port only */ + return false; + + usart_mode = (unsigned long)getleul(buf, 4); + usart_mode &= ~0xE00; /* zero bits 11:9 */ + switch (parity) { + case (int)'E': + case 2: + usart_mode |= 0x00; + break; + case (int)'O': + case 1: + usart_mode |= 0x01; + break; + case (int)'N': + case 0: + default: + usart_mode |= 0x4; /* 0x5 would work too */ + break; + } + usart_mode &= ~0x03000; /* zero bits 13:12 */ + if (stopbits == 2) + usart_mode |= 0x2000; /* zero value means 1 stop bit */ + putlelong(buf, 4, usart_mode); + putlelong(buf, 8, speed); + (void)ubx_write(session, 0x06, 0x00, &buf[6], 20); /* send back with all other settings intact */ + /*@ -charint +usedef +compdef */ + return true; +} + +static bool ubx_rate(struct gps_device_t *session, double cycletime) +/* change the sample rate of the GPS */ +{ + unsigned short s; + /*@ -type @*/ + unsigned char msg[6] = { + 0x00, 0x00, /* U2: Measurement rate (ms) */ + 0x00, 0x01, /* U2: Navigation rate (cycles) */ + 0x00, 0x00, /* U2: Alignment to reference time: 0 = UTC, !0 = GPS */ + }; + /*@ +type @*/ + + /* clamp to cycle times that i know work on my receiver */ + if (cycletime > 1000.0) + cycletime = 1000.0; + if (cycletime < 200.0) + cycletime = 200.0; + + gpsd_report(LOG_IO, "UBX rate change, report every %f secs\n", cycletime); + s = (unsigned short)cycletime; + msg[0] = (unsigned char)(s >> 8); + msg[1] = (unsigned char)(s & 0xff); + + return ubx_write(session, 0x06, 0x08, msg, 6); /* CFG-RATE */ +} +#endif /* ALLOW_RECONFIGURE */ + +/* This is everything we export */ +/* *INDENT-OFF* */ +const struct gps_type_t ubx_binary = { + .type_name = "uBlox UBX binary", /* Full name of type */ + .packet_type = UBX_PACKET, /* associated lexer packet type */ + .trigger = "$GPTXT,01,01,02,MOD", + .channels = 50, /* Number of satellite channels supported by the device */ + .probe_detect = NULL, /* Startup-time device detector */ + .get_packet = generic_get, /* Packet getter (using default routine) */ + .parse_packet = parse_input, /* Parse message packets */ + .rtcm_writer = NULL, /* RTCM handler (using default routine) */ + .event_hook = ubx_event_hook, /* Fiew in variious lifetime events */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = ubx_speed, /* Speed (baudrate) switch */ + .mode_switcher = ubx_nmea_mode, /* Switch to NMEA mode */ + .rate_switcher = ubx_rate, /* Message delivery rate switcher */ + .min_cycle = 0.25, /* Maximum 4Hz sample rate */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = ubx_control_send, /* no control sender yet */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* defined(UBX_ENABLE) && defined(BINARY_ENABLE) */ diff --git a/driver_ubx.h b/driver_ubx.h new file mode 100644 index 0000000..fa8018b --- /dev/null +++ b/driver_ubx.h @@ -0,0 +1,120 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details + */ +#ifndef _GPSD_UBX_H_ +#define _GPSD_UBX_H_ + +#define UBX_MESSAGE_BASE_SIZE 6 +#define UBX_MESSAGE_DATA_OFFSET UBX_MESSAGE_BASE_SIZE + +typedef enum { + UBX_CLASS_NAV = 0x01, /**< Navigation */ + UBX_CLASS_RXM = 0x02, /**< Receiver Manager */ + UBX_CLASS_INF = 0x04, /**< Informative text messages */ + UBX_CLASS_ACK = 0x05, /**< (Not) Acknowledges for cfg messages */ + UBX_CLASS_CFG = 0x06, /**< Configuration requests */ + UBX_CLASS_UPD = 0x09, /**< Firmware updates */ + UBX_CLASS_MON = 0x0a, /**< System monitoring */ + UBX_CLASS_AID = 0x0b, /**< AGPS */ + UBX_CLASS_TIM = 0x0d, /**< Time */ +} ubx_classes_t; + +#define UBX_MSGID(cls_, id_) (((cls_)<<8)|(id_)) + +typedef enum { + UBX_NAV_POSECEF = UBX_MSGID(UBX_CLASS_NAV, 0x01), + UBX_NAV_POSLLH = UBX_MSGID(UBX_CLASS_NAV, 0x02), + UBX_NAV_STATUS = UBX_MSGID(UBX_CLASS_NAV, 0x03), + UBX_NAV_DOP = UBX_MSGID(UBX_CLASS_NAV, 0x04), + UBX_NAV_SOL = UBX_MSGID(UBX_CLASS_NAV, 0x06), + UBX_NAV_POSUTM = UBX_MSGID(UBX_CLASS_NAV, 0x08), + UBX_NAV_VELECEF = UBX_MSGID(UBX_CLASS_NAV, 0x11), + UBX_NAV_VELNED = UBX_MSGID(UBX_CLASS_NAV, 0x12), + UBX_NAV_TIMEGPS = UBX_MSGID(UBX_CLASS_NAV, 0x20), + UBX_NAV_TIMEUTC = UBX_MSGID(UBX_CLASS_NAV, 0x21), + UBX_NAV_CLOCK = UBX_MSGID(UBX_CLASS_NAV, 0x22), + UBX_NAV_SVINFO = UBX_MSGID(UBX_CLASS_NAV, 0x30), + UBX_NAV_DGPS = UBX_MSGID(UBX_CLASS_NAV, 0x31), + UBX_NAV_SBAS = UBX_MSGID(UBX_CLASS_NAV, 0x32), + UBX_NAV_EKFSTATUS = UBX_MSGID(UBX_CLASS_NAV, 0x40), + + UBX_RXM_RAW = UBX_MSGID(UBX_CLASS_RXM, 0x10), + UBX_RXM_SFRB = UBX_MSGID(UBX_CLASS_RXM, 0x11), + UBX_RXM_SVSI = UBX_MSGID(UBX_CLASS_RXM, 0x20), + UBX_RXM_ALM = UBX_MSGID(UBX_CLASS_RXM, 0x30), + UBX_RXM_EPH = UBX_MSGID(UBX_CLASS_RXM, 0x31), + UBX_RXM_POSREQ = UBX_MSGID(UBX_CLASS_RXM, 0x40), + + UBX_INF_ERROR = UBX_MSGID(UBX_CLASS_INF, 0X00), + UBX_INF_WARNING = UBX_MSGID(UBX_CLASS_INF, 0X01), + UBX_INF_NOTICE = UBX_MSGID(UBX_CLASS_INF, 0x02), + UBX_INF_TEST = UBX_MSGID(UBX_CLASS_INF, 0x03), + UBX_INF_DEBUG = UBX_MSGID(UBX_CLASS_INF, 0x04), + UBX_INF_USER = UBX_MSGID(UBX_CLASS_INF, 0x07), + + UBX_ACK_NAK = UBX_MSGID(UBX_CLASS_ACK, 0x00), + UBX_ACK_ACK = UBX_MSGID(UBX_CLASS_ACK, 0x01), + + UBX_CFG_PRT = UBX_MSGID(UBX_CLASS_CFG, 0x00), + + UBX_UPD_DOWNL = UBX_MSGID(UBX_CLASS_UPD, 0x01), + UBX_UPD_UPLOAD = UBX_MSGID(UBX_CLASS_UPD, 0x02), + UBX_UPD_EXEC = UBX_MSGID(UBX_CLASS_UPD, 0x03), + UBX_UPD_MEMCPY = UBX_MSGID(UBX_CLASS_UPD, 0x04), + + UBX_MON_SCHED = UBX_MSGID(UBX_CLASS_MON, 0x01), + UBX_MON_IO = UBX_MSGID(UBX_CLASS_MON, 0x02), + UBX_MON_IPC = UBX_MSGID(UBX_CLASS_MON, 0x03), + UBX_MON_VER = UBX_MSGID(UBX_CLASS_MON, 0x04), + UBX_MON_EXCEPT = UBX_MSGID(UBX_CLASS_MON, 0x05), + UBX_MON_MSGPP = UBX_MSGID(UBX_CLASS_MON, 0x06), + UBX_MON_RXBUF = UBX_MSGID(UBX_CLASS_MON, 0x07), + UBX_MON_TXBUF = UBX_MSGID(UBX_CLASS_MON, 0x08), + UBX_MON_HW = UBX_MSGID(UBX_CLASS_MON, 0x09), + UBX_MON_USB = UBX_MSGID(UBX_CLASS_MON, 0x0a), + + UBX_AID_REQ = UBX_MSGID(UBX_CLASS_AID, 0x00), + UBX_AID_INI = UBX_MSGID(UBX_CLASS_AID, 0x01), + UBX_AID_HUI = UBX_MSGID(UBX_CLASS_AID, 0x02), + UBX_AID_DATA = UBX_MSGID(UBX_CLASS_AID, 0x10), + UBX_AID_ALM = UBX_MSGID(UBX_CLASS_AID, 0x30), + UBX_AID_EPH = UBX_MSGID(UBX_CLASS_AID, 0x31), + + UBX_TIM_TP = UBX_MSGID(UBX_CLASS_TIM, 0x01), + UBX_TIM_TM = UBX_MSGID(UBX_CLASS_TIM, 0x02), + UBX_TIM_TM2 = UBX_MSGID(UBX_CLASS_TIM, 0x03), + UBX_TIM_SVIN = UBX_MSGID(UBX_CLASS_TIM, 0x04), +} ubx_message_t; + +typedef enum { + UBX_MODE_NOFIX = 0x00, /* no fix available */ + UBX_MODE_DR = 0x01, /* Dead reckoning */ + UBX_MODE_2D = 0x02, /* 2D fix */ + UBX_MODE_3D = 0x03, /* 3D fix */ + UBX_MODE_GPSDR = 0x04, /* GPS + dead reckoning */ + UBX_MODE_TMONLY = 0x05, /* Time-only fix */ +} ubx_mode_t; + +#define UBX_SOL_FLAG_GPS_FIX_OK 0x01 +#define UBX_SOL_FLAG_DGPS 0x02 +#define UBX_SOL_VALID_WEEK 0x04 +#define UBX_SOL_VALID_TIME 0x08 + +/* from UBX_NAV_SVINFO */ +#define UBX_SAT_USED 0x01 +#define UBX_SAT_DGPS 0x02 +#define UBX_SAT_EPHALM 0x04 +#define UBX_SAT_EPHEM 0x08 +#define UBX_SAT_UNHEALTHY 0x10 + +#define UBX_SIG_IDLE 0 +#define UBX_SIG_SRCH1 1 +#define UBX_SIG_SRCH2 2 +#define UBX_SIG_DETECT 3 +#define UBX_SIG_CDLK 4 +#define UBX_SIG_CDCRLK1 5 +#define UBX_SIG_CDCRLK2 6 +#define UBX_SIG_NAVMSG 7 + +#endif /* _GPSD_UBX_H_ */ diff --git a/driver_zodiac.c b/driver_zodiac.c new file mode 100644 index 0000000..fb40381 --- /dev/null +++ b/driver_zodiac.c @@ -0,0 +1,507 @@ +/* + * Handle the Rockwell binary packet format supported by the old Zodiac chipset + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include "gpsd.h" + +#include "bits.h" + +#ifdef ZODIAC_ENABLE +struct header +{ + unsigned short sync; + unsigned short id; + unsigned short ndata; + unsigned short flags; + unsigned short csum; +}; + +static unsigned short zodiac_checksum(unsigned short *w, int n) +{ + unsigned short csum = 0; + + while (n-- > 0) + csum += *(w++); + return -csum; +} + +/* zodiac_spew - Takes a message type, an array of data words, and a length + for the array, and prepends a 5 word header (including checksum). + The data words are expected to be checksummed */ +#if defined (WORDS_BIGENDIAN) +/* data is assumed to contain len/2 unsigned short words + * we change the endianness to little, when needed. + */ +static int end_write(int fd, void *d, int len) +{ + char buf[BUFSIZ]; + char *p = buf; + char *data = (char *)d; + size_t n = (size_t) len; + + while (n > 0) { + *p++ = *(data + 1); + *p++ = *data; + data += 2; + n -= 2; + } + return write(fd, buf, len); +} +#else +#define end_write write +#endif /* WORDS_BIGENDIAN */ + +static ssize_t zodiac_spew(struct gps_device_t *session, unsigned short type, + unsigned short *dat, int dlen) +{ + struct header h; + int i; + char buf[BUFSIZ]; + + h.sync = 0x81ff; + h.id = (unsigned short)type; + h.ndata = (unsigned short)(dlen - 1); + h.flags = 0; + h.csum = zodiac_checksum((unsigned short *)&h, 4); + + if (session->gpsdata.gps_fd != -1) { + size_t hlen, datlen; + hlen = sizeof(h); + datlen = sizeof(unsigned short) * dlen; + if (end_write(session->gpsdata.gps_fd, &h, hlen) != (ssize_t) hlen || + end_write(session->gpsdata.gps_fd, dat, + datlen) != (ssize_t) datlen) { + gpsd_report(LOG_RAW, "Reconfigure write failed\n"); + return -1; + } + } + + (void)snprintf(buf, sizeof(buf), + "%04x %04x %04x %04x %04x", + h.sync, h.id, h.ndata, h.flags, h.csum); + for (i = 0; i < dlen; i++) + (void)snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + " %04x", dat[i]); + + gpsd_report(LOG_RAW, "Sent Zodiac packet: %s\n", buf); + + return 0; +} + +static void send_rtcm(struct gps_device_t *session, + char *rtcmbuf, size_t rtcmbytes) +{ + unsigned short data[34]; + int n = 1 + (int)(rtcmbytes / 2 + rtcmbytes % 2); + + if (session->driver.zodiac.sn++ > 32767) + session->driver.zodiac.sn = 0; + + memset(data, 0, sizeof(data)); + data[0] = session->driver.zodiac.sn; /* sequence number */ + memcpy(&data[1], rtcmbuf, rtcmbytes); + data[n] = zodiac_checksum(data, n); + + (void)zodiac_spew(session, 1351, data, n + 1); +} + +static ssize_t zodiac_send_rtcm(struct gps_device_t *session, + char *rtcmbuf, size_t rtcmbytes) +{ + size_t len; + + while (rtcmbytes > 0) { + len = (size_t) (rtcmbytes > 64 ? 64 : rtcmbytes); + send_rtcm(session, rtcmbuf, len); + rtcmbytes -= len; + rtcmbuf += len; + } + return 1; +} + +#define getzword(n) getwordz(session->packet.outbuffer, n) +#define getzlong(n) getlongz(session->packet.outbuffer, n) + +static gps_mask_t handle1000(struct gps_device_t *session) +/* time-position-velocity report */ +{ + gps_mask_t mask; + double subseconds; + struct tm unpacked_date; + /* ticks = getzlong(6); */ + /* sequence = getzword(8); */ + /* measurement_sequence = getzword(9); */ + /*@ -boolops -predboolothers @*/ + session->gpsdata.status = (getzword(10) & 0x1c) ? 0 : 1; + if (session->gpsdata.status != 0) + session->newdata.mode = (getzword(10) & 1) ? MODE_2D : MODE_3D; + else + session->newdata.mode = MODE_NO_FIX; + /*@ +boolops -predboolothers @*/ + + /* solution_type = getzword(11); */ + session->gpsdata.satellites_used = (int)getzword(12); + /* polar_navigation = getzword(13); */ + session->context->gps_week = (unsigned short)getzword(14); + /* gps_seconds = getzlong(15); */ + /* gps_nanoseconds = getzlong(17); */ + unpacked_date.tm_mday = (int)getzword(19); + unpacked_date.tm_mon = (int)getzword(20) - 1; + unpacked_date.tm_year = (int)getzword(21) - 1900; + unpacked_date.tm_hour = (int)getzword(22); + unpacked_date.tm_min = (int)getzword(23); + unpacked_date.tm_sec = (int)getzword(24); + subseconds = (int)getzlong(25) / 1e9; + /*@ -compdef */ + session->newdata.time = (double)mkgmtime(&unpacked_date) + subseconds; + /*@ +compdef */ + /*@ -type @*/ + session->newdata.latitude = ((long)getzlong(27)) * RAD_2_DEG * 1e-8; + session->newdata.longitude = ((long)getzlong(29)) * RAD_2_DEG * 1e-8; + /* + * The Rockwell Jupiter TU30-D140 reports altitude as uncorrected height + * above WGS84 geoid. The Zodiac binary protocol manual does not + * specify whether word 31 is geodetic or WGS 84. + */ + session->newdata.altitude = ((long)getzlong(31)) * 1e-2; + /*@ +type @*/ + session->gpsdata.separation = ((short)getzword(33)) * 1e-2; + session->newdata.altitude -= session->gpsdata.separation; + session->newdata.speed = (int)getzlong(34) * 1e-2; + session->newdata.track = (int)getzword(36) * RAD_2_DEG * 1e-3; + session->mag_var = ((short)getzword(37)) * RAD_2_DEG * 1e-4; + session->newdata.climb = ((short)getzword(38)) * 1e-2; + /* map_datum = getzword(39); */ + /* + * The manual says these are 1-sigma. Device reports only eph, circular + * error; no harm in assigning it to both x and y components. + */ + session->newdata.epx = session->newdata.epy = + (int)getzlong(40) * 1e-2 * (1 / sqrt(2)) * GPSD_CONFIDENCE; + session->newdata.epv = (int)getzlong(42) * 1e-2 * GPSD_CONFIDENCE; + session->newdata.ept = (int)getzlong(44) * 1e-2 * GPSD_CONFIDENCE; + session->newdata.eps = (int)getzword(46) * 1e-2 * GPSD_CONFIDENCE; + /* clock_bias = (int)getzlong(47) * 1e-2; */ + /* clock_bias_sd = (int)getzlong(49) * 1e-2; */ + /* clock_drift = (int)getzlong(51) * 1e-2; */ + /* clock_drift_sd = (int)getzlong(53) * 1e-2; */ + + mask = + TIME_IS | LATLON_IS | ALTITUDE_IS | CLIMB_IS | SPEED_IS | TRACK_IS | + STATUS_IS | MODE_IS; + gpsd_report(LOG_DATA, + "1000: time=%.2f lat=%.2f lon=%.2f alt=%.2f track=%.2f speed=%.2f climb=%.2f mode=%d status=%d mask=%s\n", + session->newdata.time, session->newdata.latitude, + session->newdata.longitude, session->newdata.altitude, + session->newdata.track, session->newdata.speed, + session->newdata.climb, session->newdata.mode, + session->gpsdata.status, gpsd_maskdump(mask)); + return mask; +} + +static gps_mask_t handle1002(struct gps_device_t *session) +/* satellite signal quality report */ +{ + int i, j, status, prn; + + /* ticks = getzlong(6); */ + /* sequence = getzword(8); */ + /* measurement_sequence = getzword(9); */ + /*@+charint@*/ + int gps_week = getzword(10); + int gps_seconds = getzlong(11); + /* gps_nanoseconds = getzlong(13); */ + /*@-charint@*/ + session->context->gps_week = (unsigned short)gps_week; + session->gpsdata.satellites_used = 0; + memset(session->gpsdata.used, 0, sizeof(session->gpsdata.used)); + for (i = 0; i < ZODIAC_CHANNELS; i++) { + /*@ -type @*/ + session->driver.zodiac.Zv[i] = status = (int)getzword(15 + (3 * i)); + session->driver.zodiac.Zs[i] = prn = (int)getzword(16 + (3 * i)); + /*@ +type @*/ + + if (status & 1) + session->gpsdata.used[session->gpsdata.satellites_used++] = prn; + for (j = 0; j < ZODIAC_CHANNELS; j++) { + if (session->gpsdata.PRN[j] != prn) + continue; + session->gpsdata.ss[j] = (float)getzword(17 + (3 * i)); + break; + } + } + session->context->gps_week = (unsigned short)gps_week; + session->context->gps_tow = (double)gps_seconds; + session->gpsdata.skyview_time = + gpstime_to_unix(gps_week, session->context->gps_tow); + gpsd_report(LOG_DATA, "1002: visible=%d used=%d mask={SATELLITE|USED}\n", + session->gpsdata.satellites_visible, + session->gpsdata.satellites_used); + return SATELLITE_IS | USED_IS; +} + +static gps_mask_t handle1003(struct gps_device_t *session) +/* skyview report */ +{ + int i, n; + + /* The Polaris (and probably the DAGR) emit some strange variant of + * this message which causes gpsd to crash filtering on impossible + * number of satellites avoids this */ + n = (int)getzword(14); + if ((n < 0) || (n > 12)) + return 0; + + gpsd_zero_satellites(&session->gpsdata); + + /* ticks = getzlong(6); */ + /* sequence = getzword(8); */ + session->gpsdata.dop.gdop = (unsigned int)getzword(9) * 1e-2; + session->gpsdata.dop.pdop = (unsigned int)getzword(10) * 1e-2; + session->gpsdata.dop.hdop = (unsigned int)getzword(11) * 1e-2; + session->gpsdata.dop.vdop = (unsigned int)getzword(12) * 1e-2; + session->gpsdata.dop.tdop = (unsigned int)getzword(13) * 1e-2; + session->gpsdata.satellites_visible = n; + + for (i = 0; i < ZODIAC_CHANNELS; i++) { + if (i < session->gpsdata.satellites_visible) { + session->gpsdata.PRN[i] = (int)getzword(15 + (3 * i)); + session->gpsdata.azimuth[i] = + (int)(((short)getzword(16 + (3 * i))) * RAD_2_DEG * 1e-4); + if (session->gpsdata.azimuth[i] < 0) + session->gpsdata.azimuth[i] += 360; + session->gpsdata.elevation[i] = + (int)(((short)getzword(17 + (3 * i))) * RAD_2_DEG * 1e-4); + } else { + session->gpsdata.PRN[i] = 0; + session->gpsdata.azimuth[i] = 0; + session->gpsdata.elevation[i] = 0; + } + } + session->gpsdata.skyview_time = NAN; + gpsd_report(LOG_DATA, "NAVDOP: visible=%d gdop=%.2f pdop=%.2f " + "hdop=%.2f vdop=%.2f tdop=%.2f mask={SATELLITE|DOP}\n", + session->gpsdata.satellites_visible, + session->gpsdata.dop.gdop, + session->gpsdata.dop.hdop, + session->gpsdata.dop.vdop, + session->gpsdata.dop.pdop, session->gpsdata.dop.tdop); + return SATELLITE_IS | DOP_IS; +} + +static void handle1005(struct gps_device_t *session UNUSED) +/* fix quality report */ +{ + /* ticks = getzlong(6); */ + /* sequence = getzword(8); */ + int numcorrections = (int)getzword(12); + + if (session->newdata.mode == MODE_NO_FIX) + session->gpsdata.status = STATUS_NO_FIX; + else if (numcorrections == 0) + session->gpsdata.status = STATUS_FIX; + else + session->gpsdata.status = STATUS_DGPS_FIX; +} + +static gps_mask_t handle1011(struct gps_device_t *session) +/* version report */ +{ + /* + * This is UNTESTED -- but harmless if buggy. Added to support + * client querying of the ID with firmware version in 2006. + * The Zodiac is supposed to send one of these messages on startup. + */ + getstringz(session->subtype, session->packet.outbuffer, 19, 28); /* software version field */ + gpsd_report(LOG_DATA, "1011: subtype=%s mask={DEVICEID}\n", + session->subtype); + return DEVICEID_IS; +} + + +static void handle1108(struct gps_device_t *session) +/* leap-second correction report */ +{ + /* ticks = getzlong(6); */ + /* sequence = getzword(8); */ + /* utc_week_seconds = getzlong(14); */ + /* leap_nanoseconds = getzlong(17); */ + if ((int)(getzword(19) & 3) == 3) + session->context->leap_seconds = (int)getzword(16); +} + +static gps_mask_t zodiac_analyze(struct gps_device_t *session) +{ + char buf[BUFSIZ]; + int i; + unsigned int id = + (unsigned int)((session->packet.outbuffer[3] << 8) | + session->packet.outbuffer[2]); + + if (session->packet.type != ZODIAC_PACKET) { + const struct gps_type_t **dp; + gpsd_report(LOG_PROG, "zodiac_analyze packet type %d\n", + session->packet.type); + // Wrong packet type ? + // Maybe find a trigger just in case it's an Earthmate + gpsd_report(LOG_RAW + 4, "Is this a trigger: %s ?\n", + (char *)session->packet.outbuffer); + + for (dp = gpsd_drivers; *dp; dp++) { + char *trigger = (*dp)->trigger; + + if (trigger != NULL + && strncmp((char *)session->packet.outbuffer, trigger, + strlen(trigger)) == 0 + && isatty(session->gpsdata.gps_fd) != 0) { + gpsd_report(LOG_PROG, "found %s.\n", trigger); + + (void)gpsd_switch_driver(session, (*dp)->type_name); + return 0; + } + } + return 0; + } + + buf[0] = '\0'; + for (i = 0; i < (int)session->packet.outbuflen; i++) + (void)snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "%02x", (unsigned int)session->packet.outbuffer[i]); + gpsd_report(LOG_RAW, "Raw Zodiac packet type %d length %zd: %s\n", + id, session->packet.outbuflen, buf); + + if (session->packet.outbuflen < 10) + return 0; + + (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), "%u", + id); + + /* + * Normal cycle for these devices is 1001 1002. + * We count 1001 as end of cycle because 1002 doesn't + * carry fix information. + */ + session->cycle_end_reliable = true; + + switch (id) { + case 1000: + return handle1000(session) | (CLEAR_IS | REPORT_IS); + case 1002: + return handle1002(session); + case 1003: + return handle1003(session); + case 1005: + handle1005(session); + return 0; + case 1011: + return handle1011(session); + case 1108: + handle1108(session); + return 0; + default: + return 0; + } +} + +#ifdef ALLOW_CONTROLSEND +static ssize_t zodiac_control_send(struct gps_device_t *session, + char *msg, size_t len) +{ + unsigned short *shortwords = (unsigned short *)msg; + + /* and if len isn't even, it's your own fault */ + return zodiac_spew(session, shortwords[0], shortwords + 1, + (int)(len / 2 - 1)); +} +#endif /* ALLOW_CONTROLSEND */ + +#ifdef ALLOW_RECONFIGURE +static bool zodiac_speed_switch(struct gps_device_t *session, + speed_t speed, char parity, int stopbits) +{ + unsigned short data[15]; + + if (session->driver.zodiac.sn++ > 32767) + session->driver.zodiac.sn = 0; + + switch (parity) { + case 'E': + case 2: + parity = (char)2; + break; + case 'O': + case 1: + parity = (char)1; + break; + case 'N': + case 0: + default: + parity = (char)0; + break; + } + + memset(data, 0, sizeof(data)); + /* data is the part of the message starting at word 6 */ + data[0] = session->driver.zodiac.sn; /* sequence number */ + data[1] = 1; /* port 1 data valid */ + data[2] = (unsigned short)parity; /* port 1 character width (8 bits) */ + data[3] = (unsigned short)(stopbits - 1); /* port 1 stop bits (1 stopbit) */ + data[4] = 0; /* port 1 parity (none) */ + data[5] = (unsigned short)(round(log((double)speed / 300) / M_LN2) + 1); /* port 1 speed */ + data[14] = zodiac_checksum(data, 14); + + (void)zodiac_spew(session, 1330, data, 15); + return true; /* it would be nice to error-check this */ +} +#endif /* ALLOW_RECONFIGURE */ + +#ifdef NTPSHM_ENABLE +static double zodiac_ntp_offset(struct gps_device_t *session) +{ + /* Removing/changing the magic number below is likely to disturb + * the handling of the 1pps signal from the gps device. The regression + * tests and simple gps applications do not detect this. A live test + * with the 1pps signal active is required. */ + return 1.1; +} +#endif /* NTPSHM_ENABLE */ + +/* this is everything we export */ +/* *INDENT-OFF* */ +const struct gps_type_t zodiac_binary = +{ + .type_name = "Zodiac binary", /* full name of type */ + .packet_type = ZODIAC_PACKET, /* associated lexer packet type */ + .trigger = NULL, /* no trigger */ + .channels = 12, /* consumer-grade GPS */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* use the generic packet getter */ + .parse_packet = zodiac_analyze, /* parse message packets */ + .rtcm_writer = zodiac_send_rtcm, /* send DGPS correction */ + .event_hook = NULL, /* no configuration */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = zodiac_speed_switch,/* we can change baud rate */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = zodiac_control_send, /* for gpsctl and friends */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = zodiac_ntp_offset, /* compute NTO fudge factor */ +#endif /* NTPSHM_ENABLE */ +}; +/* *INDENT-ON* */ + +#endif /* ZODIAC_ENABLE */ diff --git a/drivers.c b/drivers.c new file mode 100644 index 0000000..1e32b90 --- /dev/null +++ b/drivers.c @@ -0,0 +1,1218 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include "gpsd_config.h" +#ifdef HAVE_SYS_IOCTL_H +#include +#endif /* HAVE_SYS_IOCTL_H */ +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "bits.h" /* for getbeuw(), to extract big-endian words */ + +extern const struct gps_type_t zodiac_binary; +extern const struct gps_type_t ubx_binary; +extern const struct gps_type_t sirf_binary; + +ssize_t generic_get(struct gps_device_t *session) +{ + return packet_get(session->gpsdata.gps_fd, &session->packet); +} + +#if defined(NMEA_ENABLE) || defined(SIRF_ENABLE) || defined(EVERMORE_ENABLE) || defined(ITRAX_ENABLE) || defined(NAVCOM_ENABLE) +ssize_t pass_rtcm(struct gps_device_t * session, char *buf, size_t rtcmbytes) +/* most GPSes take their RTCM corrections straight up */ +{ + return gpsd_write(session, buf, rtcmbytes); +} +#endif + +#ifdef NMEA_ENABLE +/************************************************************************** + * + * Generic driver -- straight NMEA 0183 + * + **************************************************************************/ + +gps_mask_t nmea_parse_input(struct gps_device_t * session) +{ + const struct gps_type_t **dp; + + if (session->packet.type == COMMENT_PACKET) { + return 0; + } else if (session->packet.type != NMEA_PACKET) { + for (dp = gpsd_drivers; *dp; dp++) { + if (session->packet.type == (*dp)->packet_type) { + gpsd_report(LOG_WARN, "%s packet seen when NMEA expected.\n", + (*dp)->type_name); + (void)gpsd_switch_driver(session, (*dp)->type_name); + return (*dp)->parse_packet(session); + } + } + return 0; + } else { /* session->packet.type == NMEA_PACKET) */ + + gps_mask_t st = 0; + /* + * Some packets do not end in \n, append one + * for good logging + */ + gpsd_report(LOG_IO, "<= GPS: %s\n", session->packet.outbuffer); + + if ((st = + nmea_parse((char *)session->packet.outbuffer, session)) == 0) { + gpsd_report(LOG_WARN, "unknown sentence: \"%s\"\n", + session->packet.outbuffer); + } + for (dp = gpsd_drivers; *dp; dp++) { + char *trigger = (*dp)->trigger; + + if (trigger != NULL + && strncmp((char *)session->packet.outbuffer, trigger, + strlen(trigger)) == 0) { + gpsd_report(LOG_PROG, "found trigger string %s.\n", trigger); + if (*dp != session->device_type) { + (void)gpsd_switch_driver(session, (*dp)->type_name); + if (session->device_type != NULL + && session->device_type->event_hook != NULL) + session->device_type->event_hook(session, + event_triggermatch); + st |= DEVICEID_IS; + } + } + } + return st; + } +} + +static void nmea_event_hook(struct gps_device_t *session, event_t event) +{ + /* + * This is where we try to tickle NMEA devices into erevrealing their + * inner natures. + */ + if (event == event_configure) { + /* change this guard if the probe count goes up */ + if (session->packet.counter <= 8) + gpsd_report(LOG_WARN, "=> Probing device subtype %d\n", + session->packet.counter); + /* + * The reason for splitting these probes up by packet sequence + * number, interleaving them with the first few packet receives, + * is because many generic-NMEA devices get confused if you send + * too much at them in one go. + * + * A fast response to an early probe will change drivers so the + * later ones won't be sent at all. Thus, for best overall + * performance, order these to probe for the most popular types + * soonest. + * + * Note: don't make the trigger strings identical to the probe, + * because some NMEA devices (notably SiRFs) will just echo + * unknown strings right back at you. A useful dodge is to append + * a comma to the trigger, because that won't be in the response + * unless there is actual following data. + */ + switch (session->packet.counter) { +#ifdef NMEA_ENABLE + case 0: + /* probe for Garmin serial GPS -- expect $PGRMC followed by data */ + (void)nmea_send(session, "$PGRMCE"); + break; +#endif /* NMEA_ENABLE */ +#ifdef SIRF_ENABLE + case 1: + /* + * We used to try to probe for SiRF by issuing "$PSRF105,1" + * and expecting "$Ack Input105.". But it turns out this + * only works for SiRF-IIs; SiRF-I and SiRF-III don't respond. + * Thus the only reliable probe is to try to flip the SiRF into + * binary mode, cluing in the library to revert it on close. + * + * SiRFs dominate the GPS-mouse market, so we used to put this test + * first. Unfortunately this causes problems for gpsctl, as it cannot + * select the NMEA driver without switching the device back to + * binary mode! Fix this if we ever find a nondisruptive probe string. + */ + (void)nmea_send(session, + "$PSRF100,0,%d,%d,%d,0", + session->gpsdata.dev.baudrate, + 9 - session->gpsdata.dev.stopbits, + session->gpsdata.dev.stopbits); + session->back_to_nmea = true; + break; +#endif /* SIRF_ENABLE */ +#ifdef NMEA_ENABLE + case 2: + /* probe for the FV-18 -- expect $PFEC,GPint followed by data */ + (void)nmea_send(session, "$PFEC,GPint"); + break; + case 3: + /* probe for the Trimble Copernicus */ + (void)nmea_send(session, "$PTNLSNM,0139,01"); + break; +#endif /* NMEA_ENABLE */ +#ifdef EVERMORE_ENABLE + case 4: + /* Enable checksum and GGA(1s), GLL(0s), GSA(1s), GSV(1s), RMC(1s), VTG(0s), PEMT101(1s) */ + /* EverMore will reply with: \x10\x02\x04\x38\x8E\xC6\x10\x03 */ + (void)gpsd_write(session, + "\x10\x02\x12\x8E\x7F\x01\x01\x00\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x13\x10\x03", + 22); + break; +#endif /* EVERMORE_ENABLE */ +#ifdef ITRAX_ENABLE + case 5: + /* probe for iTrax, looking for "$PFST,OK" */ + (void)nmea_send(session, "$PFST"); + break; +#endif /* ITRAX_ENABLE */ +#ifdef GPSCLOCK_ENABLE + case 6: + /* probe for Furuno Electric GH-79L4-N (GPSClock); expect $PFEC,GPssd */ + (void)nmea_send(session, "$PFEC,GPsrq"); + break; +#endif /* GPSCLOCK_ENABLE */ +#ifdef ASHTECH_ENABLE + case 7: + /* probe for Ashtech -- expect $PASHR,RID */ + (void)nmea_send(session, "$PASHQ,RID"); + break; +#endif /* ASHTECH_ENABLE */ +#ifdef UBX_ENABLE + case 8: + /* probe for UBX -- query software version */ + (void)ubx_write(session, 0x0au, 0x04, NULL, 0); + break; +#endif /* UBX_ENABLE */ +#ifdef MTK3301_ENABLE + case 9: + /* probe for MTK-3301 -- expect $PMTK705 */ + (void)nmea_send(session, "$PMTK605"); + break; +#endif /* MTK3301_ENABLE */ + default: + break; + } + } +} + +#ifdef ALLOW_RECONFIGURE +static void nmea_mode_switch(struct gps_device_t *session, int mode) +{ + if (mode == MODE_BINARY) { +#if defined(SIRF_ENABLE) && defined(BINARY_ENABLE) + if (0 != (SIRF_PACKET & session->observed)) { + /* it was SiRF binary once, do it again */ + sirf_binary.mode_switcher(session, mode); + } +#endif + } +} +#endif /* ALLOW_RECONFIGURE */ + +/* *INDENT-OFF* */ +const struct gps_type_t nmea = { + .type_name = "Generic NMEA", /* full name of type */ + .packet_type = NMEA_PACKET, /* associated lexer packet type */ + .trigger = NULL, /* it's the default */ + .channels = 12, /* consumer-grade GPS */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* use generic packet getter */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = pass_rtcm, /* write RTCM data straight */ + .event_hook = nmea_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = nmea_mode_switch, /* no mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ + +#if defined(GARMIN_ENABLE) && defined(NMEA_ENABLE) +/************************************************************************** + * + * Garmin NMEA + * + **************************************************************************/ + +#ifdef ALLOW_RECONFIGURE +static void garmin_mode_switch(struct gps_device_t *session, int mode) +/* only does anything in one direction, going to Garmin binary driver */ +{ + if (mode == MODE_BINARY) { + (void)nmea_send(session, "$PGRMC1,1,2,1,,,,2,W,N"); + (void)nmea_send(session, "$PGRMI,,,,,,,R"); + (void)usleep(333); /* standard Garmin settling time */ + session->gpsdata.dev.driver_mode = MODE_BINARY; + } +} +#endif /* ALLOW_RECONFIGURE */ + +static void garmin_nmea_event_hook(struct gps_device_t *session, + event_t event) +{ + if (event == event_driver_switch) { + /* forces a reconfigure as the following packets come in */ + session->packet.counter = 0; + } + if (event == event_configure) { + /* + * And here's that reconfigure. It's spplit up like this because + * receivers like the Garmin GPS-10 don't handle having having a lot of + * probes shoved at them very well. + */ + switch (session->packet.counter) { + case 0: + /* reset some config, AutoFix, WGS84, PPS + * Set the PPS pulse length to 40ms which leaves the Garmin 18-5hz + * with a 160ms low state. + * NOTE: new PPS only takes effect after next power cycle + */ + (void)nmea_send(session, "$PGRMC,A,,100,,,,,,A,,1,2,1,30"); + break; + case 1: + /* once a sec, no averaging, NMEA 2.3, WAAS */ + (void)nmea_send(session, "$PGRMC1,1,1,1,,,,2,W,N"); + break; + case 2: + /* get some more config info */ + (void)nmea_send(session, "$PGRMC1E"); + break; + case 3: + /* turn off all output except GGA */ + (void)nmea_send(session, "$PGRMO,,2"); + (void)nmea_send(session, "$PGRMO,GPGGA,1"); + break; + case 4: + /* enable GPGGA, GPGSA, GPGSV, GPRMC on Garmin serial GPS */ + (void)nmea_send(session, "$PGRMO,GPGSA,1"); + break; + case 5: + (void)nmea_send(session, "$PGRMO,GPGSV,1"); + break; + case 6: + (void)nmea_send(session, "$PGRMO,GPRMC,1"); + break; + case 7: + (void)nmea_send(session, "$PGRMO,PGRME,1"); + break; + } + } +} + +/* *INDENT-OFF* */ +const struct gps_type_t garmin = { + .type_name = "Garmin NMEA", /* full name of type */ + .packet_type = NMEA_PACKET, /* associated lexer packet type */ + .trigger = "$PGRMC,", /* Garmin private */ + .channels = 12, /* not used by this driver */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* use generic packet getter */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = NULL, /* some do, some don't, skip for now */ + .event_hook = garmin_nmea_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = garmin_mode_switch, /* mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /*ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* GARMIN_ENABLE && NMEA_ENABLE */ + +#ifdef ASHTECH_ENABLE +/************************************************************************** + * + * Ashtech (then Thales, now Magellan Professional) Receivers + * + **************************************************************************/ + +static void ashtech_event_hook(struct gps_device_t *session, event_t event) +{ + if (event == event_wakeup) + (void)nmea_send(session, "$PASHQ,RID"); + if (event == event_identified) { + /* turn WAAS on. can't hurt... */ + (void)nmea_send(session, "$PASHS,WAS,ON"); + /* reset to known output state */ + (void)nmea_send(session, "$PASHS,NME,ALL,A,OFF"); + /* then turn on some useful sentences */ +#ifdef ASHTECH_NOTYET + /* we could parse these, but they're oversize so they get dropped */ + (void)nmea_send(session, "$PASHS,NME,POS,A,ON"); + (void)nmea_send(session, "$PASHS,NME,SAT,A,ON"); +#else + (void)nmea_send(session, "$PASHS,NME,GGA,A,ON"); + (void)nmea_send(session, "$PASHS,NME,GSA,A,ON"); + (void)nmea_send(session, "$PASHS,NME,GSV,A,ON"); + (void)nmea_send(session, "$PASHS,NME,RMC,A,ON"); +#endif + (void)nmea_send(session, "$PASHS,NME,ZDA,A,ON"); + } +} + +/* *INDENT-OFF* */ +const struct gps_type_t ashtech = { + .type_name = "Ashtech", /* full name of type */ + .packet_type = NMEA_PACKET, /* associated lexer packet type */ + .trigger = "$PASHR,RID,", /* Ashtech receivers respond thus */ + .channels = 24, /* not used, GG24 has 24 channels */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = pass_rtcm, /* write RTCM data straight */ + .event_hook = ashtech_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* ASHTECH_ENABLE */ + +#ifdef FV18_ENABLE +/************************************************************************** + * + * FV18 -- uses 2 stop bits, needs to be told to send GSAs + * + **************************************************************************/ + +static void fv18_event_hook(struct gps_device_t *session, event_t event) +{ + /* + * Tell an FV18 to send GSAs so we'll know if 3D is accurate. + * Suppress GLL and VTG. Enable ZDA so dates will be accurate for replay. + * It's possible we might not need to redo this on event_reactivate, + * but doing so is safe and cheap. + */ + if (event == event_identified || event == event_reactivate) + (void)nmea_send(session, + "$PFEC,GPint,GSA01,DTM00,ZDA01,RMC01,GLL00,VTG00,GSV05"); +} + +/* *INDENT-OFF* */ +const struct gps_type_t fv18 = { + .type_name = "San Jose Navigation FV18", /* full name of type */ + .packet_type = NMEA_PACKET, /* associated lexer packet type */ + .trigger = "$PFEC,GPint,", /* FV18s should echo the probe */ + .channels = 12, /* not used by this driver */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = pass_rtcm, /* write RTCM data straight */ + .event_hook = fv18_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* FV18_ENABLE */ + +#ifdef GPSCLOCK_ENABLE +/************************************************************************** + * + * Furuno Electric GPSClock (GH-79L4) + * + **************************************************************************/ + +/* + * Based on http://www.tecsys.de/fileadmin/user_upload/pdf/gh79_1an_intant.pdf + */ + +static void gpsclock_event_hook(struct gps_device_t *session, event_t event) +{ + /* + * Michael St. Laurent reports that you have to + * ignore the trailing PPS edge when extracting time from this chip. + */ + if (event == event_identified || event == event_reactivate) { + gpsd_report(LOG_INF, "PPS trailing edge will be ignored\n"); + session->driver.nmea.ignore_trailing_edge = true; + } +} + +/* *INDENT-OFF* */ +const struct gps_type_t gpsclock = { + .type_name = "Furuno Electric GH-79L4", /* full name of type */ + .packet_type = NMEA_PACKET, /* associated lexer packet type */ + .trigger = "$PFEC,GPssd", /* GPSclock should return this */ + .channels = 12, /* not used by this driver */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = pass_rtcm, /* write RTCM data straight */ + .event_hook = gpsclock_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* sample rate is fixed */ + .min_cycle = 1, /* sample rate is fixed */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* GPSCLOCK_ENABLE */ + +#ifdef TRIPMATE_ENABLE +/************************************************************************** + * + * TripMate -- extended NMEA, gets faster fix when primed with lat/long/time + * + **************************************************************************/ + +/* + * Some technical FAQs on the TripMate: + * http://vancouver-webpages.com/pub/peter/tripmate.faq + * http://www.asahi-net.or.jp/~KN6Y-GTU/tripmate/trmfaqe.html + * The TripMate was discontinued sometime before November 1998 + * and was replaced by the Zodiac EarthMate. + */ + +static void tripmate_event_hook(struct gps_device_t *session, event_t event) +{ + /* TripMate requires this response to the ASTRAL it sends at boot time */ + if (event == event_identified) + (void)nmea_send(session, "$IIGPQ,ASTRAL"); + /* stop it sending PRWIZCH */ + if (event == event_identified || event == event_reactivate) + (void)nmea_send(session, "$PRWIILOG,ZCH,V,,"); +} + +/* *INDENT-OFF* */ +static const struct gps_type_t tripmate = { + .type_name = "Delorme TripMate", /* full name of type */ + .packet_type = NMEA_PACKET, /* lexer packet type */ + .trigger ="ASTRAL", /* tells us to switch */ + .channels = 12, /* consumer-grade GPS */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = pass_rtcm, /* send RTCM data straight */ + .event_hook = tripmate_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher= NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* TRIPMATE_ENABLE */ + +#ifdef EARTHMATE_ENABLE +/************************************************************************** + * + * Zodiac EarthMate textual mode + * + * Note: This is the pre-2003 version using Zodiac binary protocol. + * There is a good HOWTO at . + * It has been replaced with a design that uses a SiRF chipset. + * + **************************************************************************/ + +static void earthmate_event_hook(struct gps_device_t *session, event_t event) +{ + if (event == event_identified) { + (void)gpsd_write(session, "EARTHA\r\n", 8); + (void)usleep(10000); + (void)gpsd_switch_driver(session, "Zodiac Binary"); + } +} + +/*@ -redef @*/ +/* *INDENT-OFF* */ +static const struct gps_type_t earthmate = { + .type_name = "Delorme EarthMate (pre-2003, Zodiac chipset)", + .packet_type = NMEA_PACKET, /* associated lexer packet type */ + .trigger = "EARTHA", /* Earthmate trigger string */ + .channels = 12, /* not used by NMEA parser */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = NULL, /* don't send RTCM data */ + .event_hook = earthmate_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher= NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, /* no method for NTP fudge factor */ +#endif /* NTPSHM_ ENABLE */ +}; +/*@ -redef @*/ +/* *INDENT-ON* */ +#endif /* EARTHMATE_ENABLE */ + +#endif /* NMEA_ENABLE */ + +#ifdef TNT_ENABLE +/************************************************************************** + * True North Technologies - Revolution 2X Digital compass + * + * More info: http://www.tntc.com/ + * + * This is a digital compass which uses magnetometers to measure the + * strength of the earth's magnetic field. Based on these measurements + * it provides a compass heading using NMEA formatted output strings. + * This is useful to supplement the heading provided by another GPS + * unit. A GPS heading is unreliable at slow speed or no speed. + * + **************************************************************************/ + +static void tnt_add_checksum(char *sentence) +/* add NMEA-style CRC checksum to a command */ +{ + unsigned char sum = '\0'; + char c, *p = sentence; + + if (*p == '@') { + p++; + } else { + gpsd_report(LOG_ERROR, "Bad TNT sentence: '%s'\n", sentence); + } + while (((c = *p) != '\0')) { + sum ^= c; + p++; + } + (void)snprintf(p, 6, "*%02X\r\n", (unsigned int)sum); +} + + +static ssize_t tnt_control_send(struct gps_device_t *session, + char *msg, size_t len) +/* send a control string in TNT native formal */ +{ + ssize_t status; + + tnt_add_checksum(msg); + status = write(session->gpsdata.gps_fd, msg, strlen(msg)); + (void)tcdrain(session->gpsdata.gps_fd); + return status; +} + +static bool tnt_send(struct gps_device_t *session, const char *fmt, ...) +/* printf(3)-like TNT command generator */ +{ + char buf[BUFSIZ]; + va_list ap; + ssize_t sent; + + va_start(ap, fmt); + (void)vsnprintf(buf, sizeof(buf) - 5, fmt, ap); + va_end(ap); + sent = tnt_control_send(session, buf, strlen(buf)); + if (sent == (ssize_t) strlen(buf)) { + gpsd_report(LOG_IO, "=> GPS: %s\n", buf); + return true; + } else { + gpsd_report(LOG_WARN, "=> GPS: %s FAILED\n", buf); + return false; + } +} + +#ifdef ALLOW_RECONFIGURE +static bool tnt_speed(struct gps_device_t *session, + speed_t speed, char parity, int stopbits) +{ + /* + * Baud rate change followed by device reset. + * See page 40 of Technical Guide 1555-B. We need: + * 2400 -> 1, 4800 -> 2, 9600 -> 3, 19200 -> 4, 38400 -> 5 + */ + unsigned int val = speed / 2400u; /* 2400->1, 4800->2, 9600->4, 19200->8... */ + unsigned int i = 0; + + /* fast way to compute log2(val) */ + while ((val >> i) > 1) + ++i; + return tnt_send(session, "@B6=%d", i + 1) + && tnt_send(session, "@F28.6=1"); +} +#endif /* ALLOW_RECONFIGURE */ + +static void tnt_event_hook(struct gps_device_t *session, event_t event) +/* TNT lifetime event hook */ +{ + if (event == event_wakeup) { + (void)tnt_send(session, "@F0.3=1"); /* set run mode */ + (void)tnt_send(session, "@F2.2=1"); /* report in degrees */ + } +} + +/* *INDENT-OFF* */ +const struct gps_type_t trueNorth = { + .type_name = "True North", /* full name of type */ + .packet_type = NMEA_PACKET, /* associated lexer packet type */ + .trigger = "$PTNTHTM", /* their proprietary sentence */ + .channels = 0, /* not an actual GPS at all */ + .probe_detect = NULL, /* no probe in run mode */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = NULL, /* Don't send */ + .event_hook = tnt_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = tnt_speed, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no wrapup */ + .min_cycle = 0.5, /* fixed at 20 samples per second */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = tnt_control_send, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif + +#ifdef OCEANSERVER_ENABLE +/************************************************************************** + * OceanServer - Digital Compass, OS5000 Series + * + * More info: http://www.ocean-server.com/download/OS5000_Compass_Manual.pdf + * + * This is a digital compass which uses magnetometers to measure the + * strength of the earth's magnetic field. Based on these measurements + * it provides a compass heading using NMEA formatted output strings. + * This is useful to supplement the heading provided by another GPS + * unit. A GPS heading is unreliable at slow speed or no speed. + * + **************************************************************************/ + +static int oceanserver_send(int fd, const char *fmt, ...) +{ + int status; + char buf[BUFSIZ]; + va_list ap; + + va_start(ap, fmt); + (void)vsnprintf(buf, sizeof(buf) - 5, fmt, ap); + va_end(ap); + (void)strlcat(buf, "", BUFSIZ); + status = (int)write(fd, buf, strlen(buf)); + (void)tcdrain(fd); + if (status == (int)strlen(buf)) { + gpsd_report(LOG_IO, "=> GPS: %s\n", buf); + return status; + } else { + gpsd_report(LOG_WARN, "=> GPS: %s FAILED\n", buf); + return -1; + } +} + +static void oceanserver_event_hook(struct gps_device_t *session, + event_t event) +{ + if (event == event_configure && session->packet.counter == 0) { + /* report in NMEA format */ + (void)oceanserver_send(session->gpsdata.gps_fd, "2\n"); + /* ship all fields */ + (void)oceanserver_send(session->gpsdata.gps_fd, "X2047"); + } +} + +/* *INDENT-OFF* */ +static const struct gps_type_t oceanServer = { + .type_name = "OceanServer Digital Compass OS5000", /* full name of type */ + .packet_type = NMEA_PACKET, /* associated lexer packet type */ + .trigger = "$OHPR,", /* detect their main sentence */ + .channels = 0, /* not an actual GPS at all */ + .probe_detect = NULL, + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = NULL, /* Don't send */ + .event_hook = oceanserver_event_hook, +#ifdef ALLOW_RECONFIGURE + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no wrapup */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif + +#ifdef RTCM104V2_ENABLE +/************************************************************************** + * + * RTCM-104 (v2), used for broadcasting DGPS corrections and by DGPS radios + * + **************************************************************************/ + +static gps_mask_t rtcm104v2_analyze(struct gps_device_t *session) +{ + rtcm2_unpack(&session->gpsdata.rtcm2, (char *)session->packet.isgps.buf); + gpsd_report(LOG_RAW, "RTCM 2.x packet type 0x%02x length %d words: %s\n", + session->gpsdata.rtcm2.type, + session->gpsdata.rtcm2.length + 2, + gpsd_hexdump_wrapper(session->packet.isgps.buf, + (session->gpsdata.rtcm2.length + + 2) * sizeof(isgps30bits_t), LOG_RAW)); + return RTCM2_IS; +} + +/* *INDENT-OFF* */ +static const struct gps_type_t rtcm104v2 = { + .type_name = "RTCM104V2", /* full name of type */ + .packet_type = RTCM2_PACKET, /* associated lexer packet type */ + .trigger = NULL, /* no recognition string */ + .channels = 0, /* not used */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = rtcm104v2_analyze, /* */ + .rtcm_writer = NULL, /* don't send RTCM data, */ + .event_hook = NULL, /* no event_hook */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher= NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* RTCM104V2_ENABLE */ +#ifdef RTCM104V3_ENABLE +/************************************************************************** + * + * RTCM-104 (v3), used for broadcasting DGPS corrections and by DGPS radios + * + **************************************************************************/ + +static gps_mask_t rtcm104v3_analyze(struct gps_device_t *session) +{ + uint16_t length = getbeuw(session->packet.inbuffer, 1); + uint16_t type = getbeuw(session->packet.inbuffer, 3) >> 4; + + /* *INDENT-OFF* */ + gpsd_report(LOG_RAW, "RTCM 3.x packet type %d length %d words: %s\n", + type, length, gpsd_hexdump_wrapper(session->packet.inbuffer, + (size_t) (session->gpsdata.rtcm3.length), + LOG_RAW)); + /* *INDENT-ON* */ + return RTCM3_IS; +} + +/* *INDENT-OFF* */ +static const struct gps_type_t rtcm104v3 = { + .type_name = "RTCM104V3", /* full name of type */ + .packet_type = RTCM3_PACKET, /* associated lexer packet type */ + .trigger = NULL, /* no recognition string */ + .channels = 0, /* not used */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = rtcm104v3_analyze, /* */ + .rtcm_writer = NULL, /* don't send RTCM data, */ + .event_hook = NULL, /* no event hook */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher= NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* RTCM104V3_ENABLE */ + +#ifdef GARMINTXT_ENABLE +/************************************************************************** + * + * Garmin Simple Text protocol + * + **************************************************************************/ + +static gps_mask_t garmintxt_parse_input(struct gps_device_t *session) +{ + if (session->packet.type == COMMENT_PACKET) { + return 0; + } else if (session->packet.type == GARMINTXT_PACKET) { + //gpsd_report(LOG_PROG, "Garmin Simple Text packet\n"); + return garmintxt_parse(session); + } else { + const struct gps_type_t **dp; + + for (dp = gpsd_drivers; *dp; dp++) { + if (session->packet.type == (*dp)->packet_type) { + gpsd_report(LOG_WARN, "%s packet seen when NMEA expected.\n", + (*dp)->type_name); + (void)gpsd_switch_driver(session, (*dp)->type_name); + return (*dp)->parse_packet(session); + } + } + return 0; + } +} + +/* *INDENT-OFF* */ +static const struct gps_type_t garmintxt = { + .type_name = "Garmin Simple Text", /* full name of type */ + .packet_type = GARMINTXT_PACKET, /* associated lexer packet type */ + .trigger = NULL, /* no recognition string */ + .channels = 0, /* not used */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = garmintxt_parse_input, /* */ + .rtcm_writer = NULL, /* don't send RTCM data, */ + .event_hook = NULL, /* no event hook */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher= NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = NULL, /* no sample-rate switcher */ + .min_cycle = 1, /* not relevant, no rate switch */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* GARMINTXT_ENABLE */ + +#ifdef MTK3301_ENABLE +/************************************************************************** + * + * MTK-3301 + * + **************************************************************************/ +const char *mtk_reasons[4] = + { "Invalid", "Unsupported", "Valid but Failed", "Valid success" }; + +gps_mask_t processMTK3301(int c UNUSED, char *field[], + struct gps_device_t *session) +{ + int msg, reason; + gps_mask_t mask; + mask = 1; //ONLINE_IS; + + switch (msg = atoi(&(field[0])[4])) { + case 705: /* */ + (void)strlcat(session->subtype, field[1], sizeof(session->subtype)); + (void)strlcat(session->subtype, "-", sizeof(session->subtype)); + (void)strlcat(session->subtype, field[2], sizeof(session->subtype)); + return 0; /* return a unknown sentence, which will cause the driver switch */ + case 001: /* ACK / NACK */ + reason = atoi(field[2]); + if (atoi(field[1]) == -1) + gpsd_report(LOG_WARN, "MTK NACK: unknown sentence\n"); + else if (reason < 3) + gpsd_report(LOG_WARN, "MTK NACK: %s, reason: %s\n", field[1], + mtk_reasons[reason]); + else + gpsd_report(LOG_WARN, "MTK ACK: %s\n", field[1]); + break; + default: + return 0; /* ignore */ + } + return mask; +} + +static void mtk3301_event_hook(struct gps_device_t *session, event_t event) +{ +/* +0 NMEA_SEN_GLL, GPGLL interval - Geographic Position - Latitude longitude +1 NMEA_SEN_RMC, GPRMC interval - Recommended Minimum Specific GNSS Sentence +2 NMEA_SEN_VTG, GPVTG interval - Course Over Ground and Ground Speed +3 NMEA_SEN_GGA, GPGGA interval - GPS Fix Data +4 NMEA_SEN_GSA, GPGSA interval - GNSS DOPS and Active Satellites +5 NMEA_SEN_GSV, GPGSV interval - GNSS Satellites in View +6 NMEA_SEN_GRS, GPGRS interval - GNSS Range Residuals +7 NMEA_SEN_GST, GPGST interval - GNSS Pseudorange Errors Statistics +13 NMEA_SEN_MALM, PMTKALM interval - GPS almanac information +14 NMEA_SEN_MEPH, PMTKEPH interval - GPS ephemeris information +15 NMEA_SEN_MDGP, PMTKDGP interval - GPS differential correction information +16 NMEA_SEN_MDBG, PMTKDBG interval – MTK debug information +17 NMEA_SEN_ZDA, GPZDA interval - Time & Date +18 NMEA_SEN_MCHN, PMTKCHN interval – GPS channel status + +"$PMTK314,1,1,1,1,1,5,1,1,0,0,0,0,0,0,0,0,0,1,0" + +*/ + /* FIX-ME: Do we need to resend this on reactivation? */ + if (event == event_identified) { + (void)nmea_send(session, "$PMTK320,0"); /* power save off */ + (void)nmea_send(session, "$PMTK300,1000,0,0,0.0,0.0"); /* Fix interval */ + (void)nmea_send(session, + "$PMTK314,0,1,0,1,1,5,1,1,0,0,0,0,0,0,0,0,0,1,0"); + (void)nmea_send(session, "$PMTK301,2"); /* DGPS is WAAS */ + (void)nmea_send(session, "$PMTK313,1"); /* SBAS enable */ + } +} + +#ifdef ALLOW_RECONFIGURE +static bool mtk3301_rate_switcher(struct gps_device_t *session, double rate) +{ + char buf[78]; + /*@i1@*/ unsigned int milliseconds = 1000 * rate; + if (rate > 1) + milliseconds = 1000; + else if (rate < 0.2) + milliseconds = 200; + + (void)snprintf(buf, 78, "$PMTK300,%u,0,0,0,0", milliseconds); + (void)nmea_send(session, buf); /* Fix interval */ + return true; +} +#endif /* ALLOW_RECONFIGURE */ + +/* *INDENT-OFF* */ +const struct gps_type_t mtk3301 = { + .type_name = "MTK-3301", /* full name of type */ + .packet_type = NMEA_PACKET, /* associated lexer packet type */ + .trigger = "$PMTK705,", /* MTK-3301s send firmware release name and version */ + .channels = 12, /* not used by this driver */ + .probe_detect = NULL, /* no probe */ + .get_packet = generic_get, /* how to get a packet */ + .parse_packet = nmea_parse_input, /* how to interpret a packet */ + .rtcm_writer = pass_rtcm, /* write RTCM data straight */ + .event_hook = mtk3301_event_hook, /* lifetime event handler */ +#ifdef ALLOW_RECONFIGURE + .speed_switcher = NULL, /* no speed switcher */ + .mode_switcher = NULL, /* no mode switcher */ + .rate_switcher = mtk3301_rate_switcher, /* sample rate switcher */ + .min_cycle = 0.2, /* max 5Hz */ +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + .control_send = nmea_write, /* how to send control strings */ +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* MTK3301_ENABLE */ + + +#ifdef AIVDM_ENABLE +/************************************************************************** + * + * AIVDM + * + **************************************************************************/ + +static gps_mask_t aivdm_analyze(struct gps_device_t *session) +{ + if (session->packet.type == AIVDM_PACKET) { + if (aivdm_decode + ((char *)session->packet.outbuffer, session->packet.outbuflen, + session->aivdm, &session->gpsdata.ais)) { + return ONLINE_IS | AIS_IS; + } else + return ONLINE_IS; +#ifdef NMEA_ENABLE + } else if (session->packet.type == NMEA_PACKET) { + return nmea_parse((char *)session->packet.outbuffer, session); +#endif /* NMEA_ENABLE */ + } else + return 0; +} + +/* *INDENT-OFF* */ +static const struct gps_type_t aivdm = { + /* Full name of type */ + .type_name = "AIVDM", + /* Associated lexer packet type */ + .packet_type = AIVDM_PACKET, + /* Response string that identifies device (not active) */ + .trigger = NULL, + /* Number of satellite channels supported by the device */ + .channels = 0, + /* Startup-time device detector */ + .probe_detect = NULL, + /* Packet getter (using default routine) */ + .get_packet = generic_get, + /* Parse message packets */ + .parse_packet = aivdm_analyze, + /* RTCM handler (using default routine) */ + .rtcm_writer = NULL, + /* Handle various lifetime events */ + .event_hook = NULL, +#ifdef ALLOW_RECONFIGURE + /* Speed (baudrate) switch */ + .speed_switcher = NULL, + /* Switch to NMEA mode */ + .mode_switcher = NULL, + /* Message delivery rate switcher (not active) */ + .rate_switcher = NULL, + /* Minimum cycle time of the device */ + .min_cycle = 1, +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + /* Control string sender - should provide checksum and headers/trailer */ + .control_send = NULL, +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + .ntp_offset = NULL, +#endif /* NTPSHM_ ENABLE */ +}; +/* *INDENT-ON* */ +#endif /* AIVDM_ENABLE */ + +extern const struct gps_type_t garmin_usb_binary, garmin_ser_binary; +extern const struct gps_type_t tsip_binary, oncore_binary; +extern const struct gps_type_t evermore_binary, italk_binary; +extern const struct gps_type_t navcom_binary, superstar2_binary; + +/*@ -nullassign @*/ +/* the point of this rigamarole is to not have to export a table size */ +static const struct gps_type_t *gpsd_driver_array[] = { +#ifdef NMEA_ENABLE + &nmea, +#ifdef ASHTECH_ENABLE + &ashtech, +#endif /* ASHTECHV18_ENABLE */ +#ifdef TRIPMATE_ENABLE + &tripmate, +#endif /* TRIPMATE_ENABLE */ +#ifdef EARTHMATE_ENABLE + &earthmate, +#endif /* EARTHMATE_ENABLE */ +#ifdef GPSCLOCK_ENABLE + &gpsclock, +#endif /* GPSCLOCK_ENABLE */ +#ifdef GARMIN_ENABLE + &garmin, +#endif /* GARMIN_ENABLE */ +#ifdef MTK3301_ENABLE + &mtk3301, +#endif /* MTK3301_ENABLE */ +#ifdef OCEANSERVER_ENABLE + &oceanServer, +#endif /* OCEANSERVER_ENABLE */ +#ifdef FV18_ENABLE + &fv18, +#endif /* FV18_ENABLE */ +#ifdef TNT_ENABLE + &trueNorth, +#endif /* TNT_ENABLE */ +#ifdef AIVDM_ENABLE + &aivdm, +#endif /* AIVDM_ENABLE */ +#endif /* NMEA_ENABLE */ + + +#ifdef EVERMORE_ENABLE + &evermore_binary, +#endif /* EVERMORE_ENABLE */ +#ifdef GARMIN_ENABLE + &garmin_usb_binary, + &garmin_ser_binary, +#endif /* GARMIN_ENABLE */ +#ifdef ITRAX_ENABLE + &italk_binary, +#endif /* ITRAX_ENABLE */ +#ifdef ONCORE_ENABLE + &oncore_binary, +#endif /* ONCORE_ENABLE */ +#ifdef NAVCOM_ENABLE + &navcom_binary, +#endif /* NAVCOM_ENABLE */ +#ifdef SIRF_ENABLE + &sirf_binary, +#endif /* SIRF_ENABLE */ +#ifdef SUPERSTAR2_ENABLE + &superstar2_binary, +#endif /* SUPERSTAR2_ENABLE */ +#ifdef TSIP_ENABLE + &tsip_binary, +#endif /* TSIP_ENABLE */ +#ifdef UBX_ENABLE + &ubx_binary, +#endif /* UBX_ENABLE */ +#ifdef ZODIAC_ENABLE + &zodiac_binary, +#endif /* ZODIAC_ENABLE */ + +#ifdef RTCM104V2_ENABLE + &rtcm104v2, +#endif /* RTCM104V2_ENABLE */ +#ifdef RTCM104V3_ENABLE + &rtcm104v3, +#endif /* RTCM104V3_ENABLE */ +#ifdef GARMINTXT_ENABLE + &garmintxt, +#endif /* GARMINTXT_ENABLE */ + NULL, +}; + +/*@ +nullassign @*/ +const struct gps_type_t **gpsd_drivers = &gpsd_driver_array[0]; diff --git a/geoid.c b/geoid.c new file mode 100644 index 0000000..a64c5f0 --- /dev/null +++ b/geoid.c @@ -0,0 +1,151 @@ +/* + * geoid.c -- ECEF to WGS84 conversions, including ellipsoid-to-MSL height + * + * Geoid separation code by Oleg Gusev, from data by Peter Dana. + * ECEF conversion by Rob Janssen. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#include +#include +#include "gpsd.h" + +static double fix_minuz(double d); + +static double bilinear(double x1, double y1, double x2, double y2, double x, + double y, double z11, double z12, double z21, + double z22) +{ + double delta; + + if (y1 == y2 && x1 == x2) + return (z11); + if (y1 == y2 && x1 != x2) + return (z22 * (x - x1) + z11 * (x2 - x)) / (x2 - x1); + if (x1 == x2 && y1 != y2) + return (z22 * (y - y1) + z11 * (y2 - y)) / (y2 - y1); + + delta = (y2 - y1) * (x2 - x1); + + return (z22 * (y - y1) * (x - x1) + z12 * (y2 - y) * (x - x1) + + z21 * (y - y1) * (x2 - x) + z11 * (y2 - y) * (x2 - x)) / delta; +} + + +/* return geoid separtion (MSL - WGS84) in meters, given a lat/lot in degrees */ +double wgs84_separation(double lat, double lon) +{ +#define GEOID_ROW 19 +#define GEOID_COL 37 + /* *INDENT-OFF* */ + /*@ +charint @*/ + const char geoid_delta[GEOID_COL*GEOID_ROW]={ + /* 90S */ -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, + /* 80S */ -53,-54,-55,-52,-48,-42,-38,-38,-29,-26,-26,-24,-23,-21,-19,-16,-12, -8, -4, -1, 1, 4, 4, 6, 5, 4, 2, -6,-15,-24,-33,-40,-48,-50,-53,-52,-53, + /* 70S */ -61,-60,-61,-55,-49,-44,-38,-31,-25,-16, -6, 1, 4, 5, 4, 2, 6, 12, 16, 16, 17, 21, 20, 26, 26, 22, 16, 10, -1,-16,-29,-36,-46,-55,-54,-59,-61, + /* 60S */ -45,-43,-37,-32,-30,-26,-23,-22,-16,-10, -2, 10, 20, 20, 21, 24, 22, 17, 16, 19, 25, 30, 35, 35, 33, 30, 27, 10, -2,-14,-23,-30,-33,-29,-35,-43,-45, + /* 50S */ -15,-18,-18,-16,-17,-15,-10,-10, -8, -2, 6, 14, 13, 3, 3, 10, 20, 27, 25, 26, 34, 39, 45, 45, 38, 39, 28, 13, -1,-15,-22,-22,-18,-15,-14,-10,-15, + /* 40S */ 21, 6, 1, -7,-12,-12,-12,-10, -7, -1, 8, 23, 15, -2, -6, 6, 21, 24, 18, 26, 31, 33, 39, 41, 30, 24, 13, -2,-20,-32,-33,-27,-14, -2, 5, 20, 21, + /* 30S */ 46, 22, 5, -2, -8,-13,-10, -7, -4, 1, 9, 32, 16, 4, -8, 4, 12, 15, 22, 27, 34, 29, 14, 15, 15, 7, -9,-25,-37,-39,-23,-14, 15, 33, 34, 45, 46, + /* 20S */ 51, 27, 10, 0, -9,-11, -5, -2, -3, -1, 9, 35, 20, -5, -6, -5, 0, 13, 17, 23, 21, 8, -9,-10,-11,-20, -40,-47,-45,-25, 5, 23, 45, 58, 57, 63, 51, + /* 10S */ 36, 22, 11, 6, -1, -8,-10, -8,-11, -9, 1, 32, 4,-18,-13, -9, 4, 14, 12, 13, -2,-14,-25,-32,-38,-60, -75,-63,-26, 0, 35, 52, 68, 76, 64, 52, 36, + /* 00N */ 22, 16, 17, 13, 1,-12,-23,-20,-14, -3, 14, 10,-15,-27,-18, 3, 12, 20, 18, 12,-13, -9,-28,-49,-62,-89,-102,-63, -9, 33, 58, 73, 74, 63, 50, 32, 22, + /* 10N */ 13, 12, 11, 2,-11,-28,-38,-29,-10, 3, 1,-11,-41,-42,-16, 3, 17, 33, 22, 23, 2, -3, -7,-36,-59,-90, -95,-63,-24, 12, 53, 60, 58, 46, 36, 26, 13, + /* 20N */ 5, 10, 7, -7,-23,-39,-47,-34, -9,-10,-20,-45,-48,-32, -9, 17, 25, 31, 31, 26, 15, 6, 1,-29,-44,-61, -67,-59,-36,-11, 21, 39, 49, 39, 22, 10, 5, + /* 30N */ -7, -5, -8,-15,-28,-40,-42,-29,-22,-26,-32,-51,-40,-17, 17, 31, 34, 44, 36, 28, 29, 17, 12,-20,-15,-40, -33,-34,-34,-28, 7, 29, 43, 20, 4, -6, -7, + /* 40N */ -12,-10,-13,-20,-31,-34,-21,-16,-26,-34,-33,-35,-26, 2, 33, 59, 52, 51, 52, 48, 35, 40, 33, -9,-28,-39, -48,-59,-50,-28, 3, 23, 37, 18, -1,-11,-12, + /* 50N */ -8, 8, 8, 1,-11,-19,-16,-18,-22,-35,-40,-26,-12, 24, 45, 63, 62, 59, 47, 48, 42, 28, 12,-10,-19,-33, -43,-42,-43,-29, -2, 17, 23, 22, 6, 2, -8, + /* 60N */ 2, 9, 17, 10, 13, 1,-14,-30,-39,-46,-42,-21, 6, 29, 49, 65, 60, 57, 47, 41, 21, 18, 14, 7, -3,-22, -29,-32,-32,-26,-15, -2, 13, 17, 19, 6, 2, + /* 70N */ 2, 2, 1, -1, -3, -7,-14,-24,-27,-25,-19, 3, 24, 37, 47, 60, 61, 58, 51, 43, 29, 20, 12, 5, -2,-10, -14,-12,-10,-14,-12, -6, -2, 3, 6, 4, 2, + /* 80N */ 3, 1, -2, -3, -3, -3, -1, 3, 1, 5, 9, 11, 19, 27, 31, 34, 33, 34, 33, 34, 28, 23, 17, 13, 9, 4, 4, 1, -2, -2, 0, 2, 3, 2, 1, 1, 3, + /* 90N */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13 + }; + /*@ -charint @*/ + /* *INDENT-ON* */ + int ilat, ilon; + int ilat1, ilat2, ilon1, ilon2; + + ilat = (int)floor((90. + lat) / 10); + ilon = (int)floor((180. + lon) / 10); + + /* sanity checks to prevent segfault on bad data */ + if ((ilat > 90) || (ilat < -90)) { + return 0.0; + } + if ((ilon > 180) || (ilon < -180)) { + return 0.0; + } + + ilat1 = ilat; + ilon1 = ilon; + ilat2 = (ilat < GEOID_ROW - 1) ? ilat + 1 : ilat; + ilon2 = (ilon < GEOID_COL - 1) ? ilon + 1 : ilon; + + return bilinear(ilon1 * 10. - 180., ilat1 * 10. - 90., + ilon2 * 10. - 180., ilat2 * 10. - 90., + lon, lat, + (double)geoid_delta[ilon1 + ilat1 * GEOID_COL], + (double)geoid_delta[ilon2 + ilat1 * GEOID_COL], + (double)geoid_delta[ilon1 + ilat2 * GEOID_COL], + (double)geoid_delta[ilon2 + ilat2 * GEOID_COL] + ); +} + + +void ecef_to_wgs84fix(struct gps_fix_t *fix, double *separation, + double x, double y, double z, + double vx, double vy, double vz) +/* fill in WGS84 position/velocity fields from ECEF coordinates */ +{ + double lambda, phi, p, theta, n, h, vnorth, veast, heading; + const double a = WGS84A; /* equatorial radius */ + const double b = WGS84B; /* polar radius */ + const double e2 = (a * a - b * b) / (a * a); + const double e_2 = (a * a - b * b) / (b * b); + + /* geodetic location */ + lambda = atan2(y, x); + /*@ -evalorder @*/ + p = sqrt(pow(x, 2) + pow(y, 2)); + theta = atan2(z * a, p * b); + phi = + atan2(z + e_2 * b * pow(sin(theta), 3), + p - e2 * a * pow(cos(theta), 3)); + n = a / sqrt(1.0 - e2 * pow(sin(phi), 2)); + h = p / cos(phi) - n; + fix->latitude = phi * RAD_2_DEG; + fix->longitude = lambda * RAD_2_DEG; + *separation = wgs84_separation(fix->latitude, fix->longitude); + fix->altitude = h - *separation; + /* velocity computation */ + vnorth = + -vx * sin(phi) * cos(lambda) - vy * sin(phi) * sin(lambda) + + vz * cos(phi); + veast = -vx * sin(lambda) + vy * cos(lambda); + fix->climb = + vx * cos(phi) * cos(lambda) + vy * cos(phi) * sin(lambda) + + vz * sin(phi); + fix->speed = sqrt(pow(vnorth, 2) + pow(veast, 2)); + heading = atan2(fix_minuz(veast), fix_minuz(vnorth)); + /*@ +evalorder @*/ + if (heading < 0) + heading += 2 * GPS_PI; + fix->track = heading * RAD_2_DEG; +} + +/* + * Some systems propagate the sign along with zero. This messes up + * certain trig functions, like atan2(): + * atan2(+0, +0) = 0 + * atan2(+0, -0) = PI + * Obviously that will break things. Luckily the "==" operator thinks + * that -0 == +0; we will use this to return an unambiguous value. + * + * I hereby decree that zero is not allowed to have a negative sign! + */ +static double fix_minuz(double d) +{ + return ((d == 0.0) ? 0.0 : d); +} diff --git a/gps.h b/gps.h new file mode 100644 index 0000000..23ff0bf --- /dev/null +++ b/gps.h @@ -0,0 +1,1118 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#ifndef _GPSD_GPS_H_ +#define _GPSD_GPS_H_ + +/* gps.h -- interface of the libgps library */ + +#ifdef _WIN32 +#define strtok_r(s,d,p) strtok_s(s,d,p) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macro for declaring function arguments unused. */ +#if defined(__GNUC__) +# define UNUSED __attribute__((unused)) /* Flag variable as unused */ +#else /* not __GNUC__ */ +# define UNUSED +#endif + + +#include +#include +#include +#include /* stdint.h would be smaller but not all have it */ +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include /* pacifies OpenBSD's compiler */ +#endif + +/* + * 4.1 - Base version for initial JSON protocol (Dec 2009) + * 4.2 - AIS application IDs split into DAC and FID (May 2010) + */ +#define GPSD_API_MAJOR_VERSION 4 /* bump on incompatible changes */ +#define GPSD_API_MINOR_VERSION 2 /* bump on compatible changes */ + +#define MAXTAGLEN 8 /* maximum length of sentence tag name */ +#define MAXCHANNELS 20 /* maximum GPS channels (*not* satellites!) */ +#define GPS_PRNMAX 32 /* above this number are SBAS satellites */ +#define GPS_PATH_MAX 64 /* dev files usually have short names */ +#define MAXUSERDEVS 4 /* max devices per user */ + +/* + * The structure describing an uncertainty volume in kinematic space. + * This is what GPSes are meant to produce; all the other info is + * technical impedimenta. + * + * All double values use NAN to indicate data not available. + * + * Usually all the information in this structure was considered valid + * by the GPS at the time of update. This will be so if you are using + * a GPS chipset that speaks SiRF binary, Garmin binary, or Zodiac binary. + * This covers over 80% of GPS products in early 2005. + * + * If you are using a chipset that speaks NMEA, this structure is updated + * in bits by GPRMC (lat/lon, track, speed), GPGGA (alt, climb), GPGLL + * (lat/lon), and GPGSA (eph, epv). Most NMEA GPSes take a single fix + * at the beginning of a 1-second cycle and report the same timestamp in + * GPRMC, GPGGA, and GPGLL; for these, all info is guaranteed correctly + * synced to the time member, but you'll get different stages of the same + * update depending on where in the cycle you poll. A very few GPSes, + * like the Garmin 48, take a new fix before more than one of of + * GPRMC/GPGGA/GPGLL during a single cycle; thus, they may have different + * timestamps and some data in this structure can be up to 1 cycle (usually + * 1 second) older than the fix time. + * + * Error estimates are at 95% confidence. + */ +struct gps_fix_t { + double time; /* Time of update, seconds since Unix epoch */ + int mode; /* Mode of fix */ +#define MODE_NOT_SEEN 0 /* mode update not seen yet */ +#define MODE_NO_FIX 1 /* none */ +#define MODE_2D 2 /* good for latitude/longitude */ +#define MODE_3D 3 /* good for altitude/climb too */ + double ept; /* Expected time uncertainty */ + double latitude; /* Latitude in degrees (valid if mode >= 2) */ + double epy; /* Latitude position uncertainty, meters */ + double longitude; /* Longitude in degrees (valid if mode >= 2) */ + double epx; /* Longitude position uncertainty, meters */ + double altitude; /* Altitude in meters (valid if mode == 3) */ + double epv; /* Vertical position uncertainty, meters */ + double track; /* Course made good (relative to true north) */ + double epd; /* Track uncertainty, degrees */ + double speed; /* Speed over ground, meters/sec */ + double eps; /* Speed uncertainty, meters/sec */ + double climb; /* Vertical speed, meters/sec */ + double epc; /* Vertical speed uncertainty */ +}; + +/* + * From the RCTM104 2.x standard: + * + * "The 30 bit words (as opposed to 32 bit words) coupled with a 50 Hz + * transmission rate provides a convenient timing capability where the + * times of word boundaries are a rational multiple of 0.6 seconds." + * + * "Each frame is N+2 words long, where N is the number of message data + * words. For example, a filler message (type 6 or 34) with no message + * data will have N=0, and will consist only of two header words. The + * maximum number of data words allowed by the format is 31, so that + * the longest possible message will have a total of 33 words." + */ +#define RTCM2_WORDS_MAX 33 +#define MAXCORRECTIONS 18 /* max correction count in type 1 or 9 */ +#define MAXSTATIONS 10 /* maximum stations in almanac, type 5 */ +/* RTCM104 doesn't specify this, so give it the largest reasonable value */ +#define MAXHEALTH (RTCM2_WORDS_MAX-2) + +#ifndef S_SPLINT_S +/* + * A nominally 30-bit word (24 bits of data, 6 bits of parity) + * used both in the GPS downlink protocol described in IS-GPS-200 + * and in the format for DGPS corrections used in RTCM-104v2. + */ +typedef /*@unsignedintegraltype@*/ uint32_t isgps30bits_t; +#endif /* S_SPLINT_S */ + +/* + * Values for "system" fields. Note, the encoding logic is senstive to the + * actual values of these; it's not sufficient that they're distinct. + */ +#define NAVSYSTEM_GPS 0 +#define NAVSYSTEM_GLONASS 1 +#define NAVSYSTEM_GALILEO 2 +#define NAVSYSTEM_UNKNOWN 3 + +struct rtcm2_t { + /* header contents */ + unsigned type; /* RTCM message type */ + unsigned length; /* length (words) */ + double zcount; /* time within hour: GPS time, no leap secs */ + unsigned refstaid; /* reference station ID */ + unsigned seqnum; /* message sequence number (modulo 8) */ + unsigned stathlth; /* station health */ + + /* message data in decoded form */ + union { + struct { + unsigned int nentries; + struct rangesat_t { /* data from messages 1 & 9 */ + unsigned ident; /* satellite ID */ + unsigned udre; /* user diff. range error */ + unsigned issuedata; /* issue of data */ + double rangerr; /* range error */ + double rangerate; /* range error rate */ + } sat[MAXCORRECTIONS]; + } ranges; + struct { /* data for type 3 messages */ + bool valid; /* is message well-formed? */ + double x, y, z; + } ecef; + struct { /* data from type 4 messages */ + bool valid; /* is message well-formed? */ + int system; + int sense; +#define SENSE_INVALID 0 +#define SENSE_GLOBAL 1 +#define SENSE_LOCAL 2 + char datum[6]; + double dx, dy, dz; + } reference; + struct { /* data from type 5 messages */ + unsigned int nentries; + struct consat_t { + unsigned ident; /* satellite ID */ + bool iodl; /* issue of data */ + unsigned int health; /* is satellite healthy? */ +#define HEALTH_NORMAL (0) /* Radiobeacon operation normal */ +#define HEALTH_UNMONITORED (1) /* No integrity monitor operating */ +#define HEALTH_NOINFO (2) /* No information available */ +#define HEALTH_DONOTUSE (3) /* Do not use this radiobeacon */ + int snr; /* signal-to-noise ratio, dB */ +#define SNR_BAD -1 /* not reported */ + bool health_en; /* health enabled */ + bool new_data; /* new data? */ + bool los_warning; /* line-of-sight warning */ + unsigned int tou; /* time to unhealth, seconds */ + } sat[MAXHEALTH]; + } conhealth; + struct { /* data from type 7 messages */ + unsigned int nentries; + struct station_t { + double latitude, longitude; /* location */ + unsigned int range; /* range in km */ + double frequency; /* broadcast freq */ + unsigned int health; /* station health */ + unsigned int station_id; /* of the transmitter */ + unsigned int bitrate; /* of station transmissions */ + } station[MAXSTATIONS]; + } almanac; + /* data from type 16 messages */ + char message[(RTCM2_WORDS_MAX-2) * sizeof(isgps30bits_t)]; + /* data from messages of unknown type */ + isgps30bits_t words[RTCM2_WORDS_MAX-2]; + }; +}; + +/* RTCM3 report structures begin here */ + +#define RTCM3_MAX_SATELLITES 64 +#define RTCM3_MAX_DESCRIPTOR 31 +#define RTCM3_MAX_ANNOUNCEMENTS 32 + +struct rtcm3_rtk_hdr { /* header data from 1001, 1002, 1003, 1004 */ + /* Used for both GPS and GLONASS, but their timebases differ */ + unsigned int station_id; /* Reference Station ID */ + time_t tow; /* GPS Epoch Time (TOW) in ms, + or GLONASS Epoch Time in ms */ + bool sync; /* Synchronous GNSS Message Flag */ + unsigned short satcount; /* # Satellite Signals Processed */ + bool smoothing; /* Divergence-free Smoothing Indicator */ + unsigned short interval; /* Smoothing Interval */ +}; + +struct rtcm3_basic_rtk { + unsigned char indicator; /* Indicator */ + unsigned char channel; /* Satellite Frequency Channel Number + (GLONASS only) */ + double pseudorange; /* Pseudorange */ + double rangediff; /* PhaseRange – Pseudorange in meters */ + unsigned char locktime; /* Lock time Indicator */ +}; + +struct rtcm3_extended_rtk { + unsigned char indicator; /* Indicator */ + unsigned char channel; /* Satellite Frequency Channel Number + (GLONASS only) */ + double pseudorange; /* Pseudorange */ + double rangediff; /* PhaseRange – L1 Pseudorange */ + unsigned char locktime; /* Lock time Indicator */ + unsigned char ambiguity; /* Integer Pseudorange + Modulus Ambiguity */ + double CNR; /* Carrier-to-Noise Ratio */ +}; + +struct rtcm3_network_rtk_header { + unsigned int network_id; /* Network ID */ + unsigned int subnetwork_id; /* Subnetwork ID */ + time_t time; /* GPS Epoch Time (TOW) in ms */ + bool multimesg; /* GPS Multiple Message Indicator */ + unsigned master_id; /* Master Reference Station ID */ + unsigned aux_id; /* Auxilary Reference Station ID */ + unsigned char satcount; /* count of GPS satellites */ +}; + +struct rtcm3_correction_diff { + unsigned char ident; /* satellite ID */ + enum {reserved, correct, widelane, uncertain} ambiguity; + unsigned char nonsync; + double geometric_diff; /* Geometric Carrier Phase + Correction Difference (1016, 1017) */ + unsigned char iode; /* GPS IODE (1016, 1017) */ + double ionospheric_diff; /* Ionospheric Carrier Phase + Correction Difference (1015, 1017) */ +}; + +struct rtcm3_t { + /* header contents */ + unsigned type; /* RTCM 3.x message type */ + unsigned length; /* payload length, inclusive of checksum */ + + union { + /* 1001-1013 were present in the 3.0 version */ + struct { + struct rtcm3_rtk_hdr header; + struct { + unsigned ident; /* Satellite ID */ + struct rtcm3_basic_rtk L1; + } rtk_data[RTCM3_MAX_SATELLITES]; + } rtcm3_1001; + struct { + struct rtcm3_rtk_hdr header; + struct { + unsigned ident; /* Satellite ID */ + struct rtcm3_extended_rtk L1; + } rtk_data[RTCM3_MAX_SATELLITES]; + } rtcm3_1002; + struct { + struct rtcm3_rtk_hdr header; + struct { + unsigned ident; /* Satellite ID */ + struct rtcm3_basic_rtk L1; + struct rtcm3_basic_rtk L2; + } rtk_data[RTCM3_MAX_SATELLITES]; + } rtcm3_1003; + struct { + struct rtcm3_rtk_hdr header; + struct { + unsigned ident; /* Satellite ID */ + struct rtcm3_extended_rtk L1; + struct rtcm3_extended_rtk L2; + } rtk_data[RTCM3_MAX_SATELLITES]; + } rtcm3_1004; + struct { + unsigned int station_id; /* Reference Station ID */ + int system; /* Which system is it? */ + bool reference_station; /* Reference-station indicator */ + bool single_receiver; /* Single Receiver Oscillator */ + double ecef_x, ecef_y, ecef_z; /* ECEF antenna location */ + } rtcm3_1005; + struct { + unsigned int station_id; /* Reference Station ID */ + int system; /* Which system is it? */ + bool reference_station; /* Reference-station indicator */ + bool single_receiver; /* Single Receiver Oscillator */ + double ecef_x, ecef_y, ecef_z; /* ECEF antenna location */ + double height; /* Antenna height */ + } rtcm3_1006; + struct { + unsigned int station_id; /* Reference Station ID */ + char descriptor[RTCM3_MAX_DESCRIPTOR+1]; /* Description string */ + unsigned char setup_id; + } rtcm3_1007; + struct { + unsigned int station_id; /* Reference Station ID */ + char descriptor[RTCM3_MAX_DESCRIPTOR+1]; /* Description string */ + unsigned char setup_id; + char serial[RTCM3_MAX_DESCRIPTOR+1]; /* Serial # string */ + } rtcm3_1008; + struct { + struct rtcm3_rtk_hdr header; + struct { + unsigned ident; /* Satellite ID */ + struct rtcm3_basic_rtk L1; + } rtk_data[RTCM3_MAX_SATELLITES]; + } rtcm3_1009; + struct { + struct rtcm3_rtk_hdr header; + struct { + unsigned ident; /* Satellite ID */ + struct rtcm3_extended_rtk L1; + } rtk_data[RTCM3_MAX_SATELLITES]; + } rtcm3_1010; + struct { + struct rtcm3_rtk_hdr header; + struct { + unsigned ident; /* Satellite ID */ + struct rtcm3_extended_rtk L1; + struct rtcm3_extended_rtk L2; + } rtk_data[RTCM3_MAX_SATELLITES]; + } rtcm3_1011; + struct { + struct rtcm3_rtk_hdr header; + struct { + unsigned ident; /* Satellite ID */ + struct rtcm3_extended_rtk L1; + struct rtcm3_extended_rtk L2; + } rtk_data[RTCM3_MAX_SATELLITES]; + } rtcm3_1012; + struct { + unsigned int station_id; /* Reference Station ID */ + unsigned short mjd; /* Modified Julian Day (MJD) Number */ + unsigned int sod; /* Seconds of Day (UTC) */ + unsigned char leapsecs; /* Leap Seconds, GPS-UTC */ + unsigned char ncount; /* Count of announcements to follow */ + struct { + unsigned short id; + bool sync; + unsigned short interval; + } announcements[RTCM3_MAX_ANNOUNCEMENTS]; + } rtcm3_1013; + /* 1014-1017 were added in the 3.1 version */ + struct { + unsigned int network_id; /* Network ID */ + unsigned int subnetwork_id; /* Subnetwork ID */ + unsigned char stationcount; /* # auxiliary stations transmitted */ + unsigned int master_id; /* Master Reference Station ID */ + unsigned int aux_id; /* Auxilary Reference Station ID */ + double d_lat, d_lon, d_alt; /* Aux-master location delta */ + } rtcm3_1014; + struct { + struct rtcm3_network_rtk_header header; + struct rtcm3_correction_diff corrections[RTCM3_MAX_SATELLITES]; + } rtcm3_1015; + struct { + struct rtcm3_network_rtk_header header; + struct rtcm3_correction_diff corrections[RTCM3_MAX_SATELLITES]; + } rtcm3_1016; + struct { + struct rtcm3_network_rtk_header header; + struct rtcm3_correction_diff corrections[RTCM3_MAX_SATELLITES]; + } rtcm3_1017; + /* 1018-1029 were in the 3.0 version */ + struct { + unsigned int ident; /* Satellite ID */ + unsigned int week; /* GPS Week Number */ + unsigned char sv_accuracy; /* GPS SV ACCURACY */ + enum {reserved_code, p, ca, l2c} code; + double idot; + unsigned char iode; + /* ephemeris fields, not scaled */ + unsigned int t_sub_oc; + signed int a_sub_f2; + signed int a_sub_f1; + signed int a_sub_f0; + unsigned int iodc; + signed int C_sub_rs; + signed int delta_sub_n; + signed int M_sub_0; + signed int C_sub_uc; + unsigned int e; + signed int C_sub_us; + unsigned int sqrt_sub_A; + unsigned int t_sub_oe; + signed int C_sub_ic; + signed int OMEGA_sub_0; + signed int C_sub_is; + signed int i_sub_0; + signed int C_sub_rc; + signed int argument_of_perigee; + signed int omegadot; + signed int t_sub_GD; + unsigned char sv_health; + bool p_data; + bool fit_interval; + } rtcm3_1019; + struct { + unsigned int ident; /* Satellite ID */ + unsigned short channel; /* Satellite Frequency Channel Number */ + /* ephemeris fields, not scaled */ + bool C_sub_n; + bool health_avAilability_indicator; + unsigned char P1; + unsigned short t_sub_k; + bool msb_of_B_sub_n; + bool P2; + bool t_sub_b; + signed int x_sub_n_t_of_t_sub_b_prime; + signed int x_sub_n_t_of_t_sub_b; + signed int x_sub_n_t_of_t_sub_b_prime_prime; + signed int y_sub_n_t_of_t_sub_b_prime; + signed int y_sub_n_t_of_t_sub_b; + signed int y_sub_n_t_of_t_sub_b_prime_prime; + signed int z_sub_n_t_of_t_sub_b_prime; + signed int z_sub_n_t_of_t_sub_b; + signed int z_sub_n_t_of_t_sub_b_prime_prime; + bool P3; + signed int gamma_sub_n_of_t_sub_b; + unsigned char MP; + bool Ml_n; + signed int tau_n_of_t_sub_b; + signed int M_delta_tau_sub_n; + unsigned int E_sub_n; + bool MP4; + unsigned char MF_sub_T; + unsigned char MN_sub_T; + unsigned char MM; + bool additioinal_data_availability; + unsigned int N_sup_A; + unsigned int tau_sub_c; + unsigned int M_N_sub_4; + signed int M_tau_sub_GPS; + bool M_l_sub_n; + } rtcm3_1020; + struct { + unsigned int station_id; /* Reference Station ID */ + unsigned short mjd; /* Modified Julian Day (MJD) Number */ + unsigned int sod; /* Seconds of Day (UTC) */ + unsigned char len; /* # Chars to follow */ + unsigned char unicode_units; + unsigned char text[128]; + } rtcm3_1029; + } rtcmtypes; +}; + +typedef /*@unsignedintegraltype@*/ unsigned int gps_mask_t; + +/* + * Is an MMSI number that of an auxiliary associated with a mother ship? + * We need to be able to test this for decoding AIS Type 24 messages. + * According to , + * auxiliary-craft MMSIs have the form 98MIDXXXX, where MID is a country + * code and XXXX the vessel ID. + */ +#define AIS_AUXILIARY_MMSI(n) ((n) / 10000000 == 98) + +struct ais_t +{ + unsigned int type; /* message type */ + unsigned int repeat; /* Repeat indicator */ + unsigned int mmsi; /* MMSI */ + union { + /* Types 1-3 Common navigation info */ + struct { + unsigned int status; /* navigation status */ + signed turn; /* rate of turn */ +#define AIS_TURN_HARD_LEFT -127 +#define AIS_TURN_HARD_RIGHT 127 +#define AIS_TURN_NOT_AVAILABLE 128 + unsigned int speed; /* speed over ground in deciknots */ +#define AIS_SPEED_NOT_AVAILABLE 1023 +#define AIS_SPEED_FAST_MOVER 1022 /* >= 102.2 knots */ + bool accuracy; /* position accuracy */ +#define AIS_LATLON_SCALE 600000.0 + int lon; /* longitude */ +#define AIS_LON_NOT_AVAILABLE 0x6791AC0 + int lat; /* latitude */ +#define AIS_LAT_NOT_AVAILABLE 0x3412140 + unsigned int course; /* course over ground */ +#define AIS_COURSE_NOT_AVAILABLE 3600 + unsigned int heading; /* true heading */ +#define AIS_HEADING_NOT_AVAILABLE 511 + unsigned int second; /* seconds of UTC timestamp */ +#define AIS_SEC_NOT_AVAILABLE 60 +#define AIS_SEC_MANUAL 61 +#define AIS_SEC_ESTIMATED 62 +#define AIS_SEC_INOPERATIVE 63 + unsigned int maneuver; /* maneuver indicator */ + //unsigned int spare; spare bits */ + bool raim; /* RAIM flag */ + unsigned int radio; /* radio status bits */ + } type1; + /* Type 4 - Base Station Report & Type 11 - UTC and Date Response */ + struct { + unsigned int year; /* UTC year */ +#define AIS_YEAR_NOT_AVAILABLE 0 + unsigned int month; /* UTC month */ +#define AIS_MONTH_NOT_AVAILABLE 0 + unsigned int day; /* UTC day */ +#define AIS_DAY_NOT_AVAILABLE 0 + unsigned int hour; /* UTC hour */ +#define AIS_HOUR_NOT_AVAILABLE 24 + unsigned int minute; /* UTC minute */ +#define AIS_MINUTE_NOT_AVAILABLE 60 + unsigned int second; /* UTC second */ +#define AIS_SECOND_NOT_AVAILABLE 60 + bool accuracy; /* fix quality */ + int lon; /* longitude */ + int lat; /* latitude */ + unsigned int epfd; /* type of position fix device */ + //unsigned int spare; spare bits */ + bool raim; /* RAIM flag */ + unsigned int radio; /* radio status bits */ + } type4; + /* Type 5 - Ship static and voyage related data */ + struct { + unsigned int ais_version; /* AIS version level */ + unsigned int imo; /* IMO identification */ + char callsign[8]; /* callsign */ +#define AIS_SHIPNAME_MAXLEN 20 + char shipname[AIS_SHIPNAME_MAXLEN+1]; /* vessel name */ + unsigned int shiptype; /* ship type code */ + unsigned int to_bow; /* dimension to bow */ + unsigned int to_stern; /* dimension to stern */ + unsigned int to_port; /* dimension to port */ + unsigned int to_starboard; /* dimension to starboard */ + unsigned int epfd; /* type of position fix deviuce */ + unsigned int month; /* UTC month */ + unsigned int day; /* UTC day */ + unsigned int hour; /* UTC hour */ + unsigned int minute; /* UTC minute */ + unsigned int draught; /* draft in meters */ + char destination[21]; /* ship destination */ + unsigned int dte; /* data terminal enable */ + //unsigned int spare; spare bits */ + } type5; + /* Type 6 - Addressed Binary Message */ + struct { + unsigned int seqno; /* sequence number */ + unsigned int dest_mmsi; /* destination MMSI */ + bool retransmit; /* retransmit flag */ + //unsigned int spare; spare bit(s) */ + unsigned int dac; /* Application ID */ + unsigned int fid; /* Functional ID */ +#define AIS_TYPE6_BINARY_MAX 920 /* 920 bits */ + size_t bitcount; /* bit count of the data */ + char bitdata[(AIS_TYPE6_BINARY_MAX + 7) / 8]; + } type6; + /* Type 7 - Binary Acknowledge */ + struct { + unsigned int mmsi1; + unsigned int mmsi2; + unsigned int mmsi3; + unsigned int mmsi4; + /* spares ignored, they're only padding here */ + } type7; + /* Type 8 - Broadcast Binary Message */ + struct { + //unsigned int spare; spare bit(s) */ + unsigned int dac; /* Designated Area Code */ + unsigned int fid; /* Functional ID */ +#define AIS_TYPE8_BINARY_MAX 952 /* 952 bits */ + size_t bitcount; /* bit count of the data */ + char bitdata[(AIS_TYPE8_BINARY_MAX + 7) / 8]; + } type8; + /* Type 9 - Standard SAR Aircraft Position Report */ + struct { + unsigned int alt; /* altitude in meters */ +#define AIS_ALT_NOT_AVAILABLE 4095 +#define AIS_ALT_HIGH 4094 /* 4094 meters or higher */ + unsigned int speed; /* speed over ground in deciknots */ +#define AIS_SAR_SPEED_NOT_AVAILABLE 1023 +#define AIS_SAR_FAST_MOVER 1022 + bool accuracy; /* position accuracy */ + int lon; /* longitude */ + int lat; /* latitude */ + unsigned int course; /* course over ground */ + unsigned int second; /* seconds of UTC timestamp */ + unsigned int regional; /* regional reserved */ + unsigned int dte; /* data terminal enable */ + //unsigned int spare; spare bits */ + bool assigned; /* assigned-mode flag */ + bool raim; /* RAIM flag */ + unsigned int radio; /* radio status bits */ + } type9; + /* Type 10 - UTC/Date Inquiry */ + struct { + //unsigned int spare; + unsigned int dest_mmsi; /* destination MMSI */ + //unsigned int spare2; + } type10; + /* Type 12 - Safety-Related Message */ + struct { + unsigned int seqno; /* sequence number */ + unsigned int dest_mmsi; /* destination MMSI */ + bool retransmit; /* retransmit flag */ + //unsigned int spare; spare bit(s) */ +#define AIS_TYPE12_TEXT_MAX 157 /* 936 bits of six-bit, plus NUL */ + char text[AIS_TYPE12_TEXT_MAX]; + } type12; + /* Type 14 - Safety-Related Broadcast Message */ + struct { + //unsigned int spare; spare bit(s) */ +#define AIS_TYPE14_TEXT_MAX 161 /* 952 bits of six-bit, plus NUL */ + char text[AIS_TYPE14_TEXT_MAX]; + } type14; + /* Type 15 - Interrogation */ + struct { + //unsigned int spare; spare bit(s) */ + unsigned int mmsi1; + unsigned int type1_1; + unsigned int offset1_1; + //unsigned int spare2; spare bit(s) */ + unsigned int type1_2; + unsigned int offset1_2; + //unsigned int spare3; spare bit(s) */ + unsigned int mmsi2; + unsigned int type2_1; + unsigned int offset2_1; + //unsigned int spare4; spare bit(s) */ + } type15; + /* Type 16 - Assigned Mode Command */ + struct { + //unsigned int spare; spare bit(s) */ + unsigned int mmsi1; + unsigned int offset1; + unsigned int increment1; + unsigned int mmsi2; + unsigned int offset2; + unsigned int increment2; + } type16; + /* Type 17 - GNSS Broadcast Binary Message */ + struct { + //unsigned int spare; spare bit(s) */ +#define AIS_GNSS_LATLON_SCALE 600.0 + int lon; /* longitude */ + int lat; /* latitude */ + //unsigned int spare2; spare bit(s) */ +#define AIS_TYPE17_BINARY_MAX 736 /* 920 bits */ + size_t bitcount; /* bit count of the data */ + char bitdata[(AIS_TYPE17_BINARY_MAX + 7) / 8]; + } type17; + /* Type 18 - Standard Class B CS Position Report */ + struct { + unsigned int reserved; /* altitude in meters */ + unsigned int speed; /* speed over ground in deciknots */ + bool accuracy; /* position accuracy */ + int lon; /* longitude */ +#define AIS_GNS_LON_NOT_AVAILABLE 0x1a838 + int lat; /* latitude */ +#define AIS_GNS_LAT_NOT_AVAILABLE 0xd548 + unsigned int course; /* course over ground */ + unsigned int heading; /* true heading */ + unsigned int second; /* seconds of UTC timestamp */ + unsigned int regional; /* regional reserved */ + bool cs; /* carrier sense unit flag */ + bool display; /* unit has attached display? */ + bool dsc; /* unit attached to radio with DSC? */ + bool band; /* unit can switch frequency bands? */ + bool msg22; /* can accept Message 22 management? */ + bool assigned; /* assigned-mode flag */ + bool raim; /* RAIM flag */ + unsigned int radio; /* radio status bits */ + } type18; + /* Type 19 - Extended Class B CS Position Report */ + struct { + unsigned int reserved; /* altitude in meters */ + unsigned int speed; /* speed over ground in deciknots */ + bool accuracy; /* position accuracy */ + int lon; /* longitude */ + int lat; /* latitude */ + unsigned int course; /* course over ground */ + unsigned int heading; /* true heading */ + unsigned int second; /* seconds of UTC timestamp */ + unsigned int regional; /* regional reserved */ + char shipname[AIS_SHIPNAME_MAXLEN+1]; /* ship name */ + unsigned int shiptype; /* ship type code */ + unsigned int to_bow; /* dimension to bow */ + unsigned int to_stern; /* dimension to stern */ + unsigned int to_port; /* dimension to port */ + unsigned int to_starboard; /* dimension to starboard */ + unsigned int epfd; /* type of position fix deviuce */ + bool raim; /* RAIM flag */ + unsigned int dte; /* date terminal enable */ + bool assigned; /* assigned-mode flag */ + //unsigned int spare; spare bits */ + } type19; + /* Type 20 - Data Link Management Message */ + struct { + //unsigned int spare; spare bit(s) */ + unsigned int offset1; /* TDMA slot offset */ + unsigned int number1; /* number of xlots to allocate */ + unsigned int timeout1; /* allocation timeout */ + unsigned int increment1; /* repeat increment */ + unsigned int offset2; /* TDMA slot offset */ + unsigned int number2; /* number of xlots to allocate */ + unsigned int timeout2; /* allocation timeout */ + unsigned int increment2; /* repeat increment */ + unsigned int offset3; /* TDMA slot offset */ + unsigned int number3; /* number of xlots to allocate */ + unsigned int timeout3; /* allocation timeout */ + unsigned int increment3; /* repeat increment */ + unsigned int offset4; /* TDMA slot offset */ + unsigned int number4; /* number of xlots to allocate */ + unsigned int timeout4; /* allocation timeout */ + unsigned int increment4; /* repeat increment */ + } type20; + /* Type 21 - Aids to Navigation Report */ + struct { + unsigned int aid_type; /* aid type */ + char name[35]; /* name of aid to navigation */ + bool accuracy; /* position accuracy */ + int lon; /* longitude */ + int lat; /* latitude */ + unsigned int to_bow; /* dimension to bow */ + unsigned int to_stern; /* dimension to stern */ + unsigned int to_port; /* dimension to port */ + unsigned int to_starboard; /* dimension to starboard */ + unsigned int epfd; /* type of EPFD */ + unsigned int second; /* second of UTC timestamp */ + bool off_position; /* off-position indicator */ + unsigned int regional; /* regional reserved field */ + bool raim; /* RAIM flag */ + bool virtual_aid; /* is virtual station? */ + bool assigned; /* assigned-mode flag */ + //unsigned int spare; unused */ + } type21; + /* Type 22 - Channel Management */ + struct { + //unsigned int spare; spare bit(s) */ + unsigned int channel_a; /* Channel A number */ + unsigned int channel_b; /* Channel B number */ + unsigned int txrx; /* transmit/receive mode */ + bool power; /* high-power flag */ +#define AIS_CHANNEL_LATLON_SCALE 600.0 + union { + struct { + int ne_lon; /* NE corner longitude */ + int ne_lat; /* NE corner latitude */ + int sw_lon; /* SW corner longitude */ + int sw_lat; /* SW corner latitude */ + } area; + struct { + unsigned int dest1; /* addressed station MMSI 1 */ + unsigned int dest2; /* addressed station MMSI 2 */ + } mmsi; + }; + bool addressed; /* addressed vs. broadast flag */ + bool band_a; /* fix 1.5kHz band for channel A */ + bool band_b; /* fix 1.5kHz band for channel B */ + unsigned int zonesize; /* size of transitional zone */ + } type22; + /* Type 23 - Group Assignment Command */ + struct { + int ne_lon; /* NE corner longitude */ + int ne_lat; /* NE corner latitude */ + int sw_lon; /* SW corner longitude */ + int sw_lat; /* SW corner latitude */ + //unsigned int spare; spare bit(s) */ + unsigned int stationtype; /* station type code */ + unsigned int shiptype; /* ship type code */ + //unsigned int spare2; spare bit(s) */ + unsigned int txrx; /* transmit-enable code */ + unsigned int interval; /* report interval */ + unsigned int quiet; /* quiet time */ + //unsigned int spare3; spare bit(s) */ + } type23; + /* Type 24 - Class B CS Static Data Report */ + struct { + char shipname[AIS_SHIPNAME_MAXLEN+1]; /* vessel name */ + unsigned int shiptype; /* ship type code */ + char vendorid[8]; /* vendor ID */ + char callsign[8]; /* callsign */ + union { + unsigned int mothership_mmsi; /* MMSI of main vessel */ + struct { + unsigned int to_bow; /* dimension to bow */ + unsigned int to_stern; /* dimension to stern */ + unsigned int to_port; /* dimension to port */ + unsigned int to_starboard; /* dimension to starboard */ + } dim; + }; + } type24; + /* Type 25 - Addressed Binary Message */ + struct { + bool addressed; /* addressed-vs.broadcast flag */ + bool structured; /* structured-binary flag */ + unsigned int dest_mmsi; /* destination MMSI */ + unsigned int app_id; /* Application ID */ +#define AIS_TYPE25_BINARY_MAX 128 /* Up to 128 bits */ + size_t bitcount; /* bit count of the data */ + char bitdata[(AIS_TYPE25_BINARY_MAX + 7) / 8]; + } type25; + /* Type 26 - Addressed Binary Message */ + struct { + bool addressed; /* addressed-vs.broadcast flag */ + bool structured; /* structured-binary flag */ + unsigned int dest_mmsi; /* destination MMSI */ + unsigned int app_id; /* Application ID */ +#define AIS_TYPE26_BINARY_MAX 1004 /* Up to 128 bits */ + size_t bitcount; /* bit count of the data */ + char bitdata[(AIS_TYPE26_BINARY_MAX + 7) / 8]; + unsigned int radio; /* radio status bits */ + } type26; + }; +}; + +struct attitude_t { + double heading; + double pitch; + double roll; + double yaw; + double dip; + double mag_len; /* unitvector sqrt(x^2 + y^2 +z^2) */ + double mag_x; + double mag_y; + double mag_z; + double acc_len; /* unitvector sqrt(x^2 + y^2 +z^2) */ + double acc_x; + double acc_y; + double acc_z; + double gyro_x; + double gyro_y; + double temp; + double depth; + /* compass status -- TrueNorth (and any similar) devices only */ + char mag_st; + char pitch_st; + char roll_st; + char yaw_st; +}; + +struct dop_t { + /* Dilution of precision factors */ + double xdop, ydop, pdop, hdop, vdop, tdop, gdop; +}; + +struct rawdata_t { + /* raw measurement data */ + double codephase[MAXCHANNELS]; /* meters */ + double carrierphase[MAXCHANNELS]; /* meters */ + double pseudorange[MAXCHANNELS]; /* meters */ + double deltarange[MAXCHANNELS]; /* meters/sec */ + double doppler[MAXCHANNELS]; /* Hz */ + double mtime[MAXCHANNELS]; /* sec */ + unsigned satstat[MAXCHANNELS]; /* tracking status */ +#define SAT_ACQUIRED 0x01 /* satellite acquired */ +#define SAT_CODE_TRACK 0x02 /* code-tracking loop acquired */ +#define SAT_CARR_TRACK 0x04 /* carrier-tracking loop acquired */ +#define SAT_DATA_SYNC 0x08 /* data-bit synchronization done */ +#define SAT_FRAME_SYNC 0x10 /* frame synchronization done */ +#define SAT_EPHEMERIS 0x20 /* ephemeris collected */ +#define SAT_FIX_USED 0x40 /* used for position fix */ +}; + +struct version_t { + char release[64]; /* external version */ + char rev[64]; /* internal revision ID */ + int proto_major, proto_minor; /* API major and minor versions */ +}; + +struct devconfig_t { + char path[GPS_PATH_MAX]; + int flags; +#define SEEN_GPS 0x01 +#define SEEN_RTCM2 0x02 +#define SEEN_RTCM3 0x04 +#define SEEN_AIS 0x08 + char driver[64]; + char subtype[64]; + double activated; + unsigned int baudrate, stopbits; /* RS232 link parameters */ + char parity; /* 'N', 'O', or 'E' */ + double cycle, mincycle; /* refresh cycle time in seconds */ + int driver_mode; /* is driver in native mode or not? */ +}; + +struct policy_t { + bool watcher; /* is watcher mode on? */ + bool json; /* requesting JSON? */ + bool nmea; /* requesting dumping as NMEA? */ + int raw; /* requesting raw data? */ + bool scaled; /* requesting report scaling? */ + bool timing; /* requesting timing info */ + char devpath[GPS_PATH_MAX]; /* specific device to watch */ +}; + +/* + * Someday we may support Windows, under which socket_t is a separate type. + * In the meantime, having a typedef for this semantic kind is no bad thing, + * as it makes clearer what some declarations are doing without breaking + * binary compatibility. + */ +typedef int socket_t; + +/* mode flags for setting streaming policy */ +#define WATCH_ENABLE 0x0001u /* enable streaming */ +#define WATCH_JSON 0x0002u /* enable JSON output */ +#define WATCH_NMEA 0x0004u /* enable output in NMEA */ +#define WATCH_RARE 0x0008u /* enable output of packets in hex */ +#define WATCH_RAW 0x0010u /* enable output of raw packets */ +#define WATCH_SCALED 0x0020u /* scale output to floats, when applicable */ +#define WATCH_NEWSTYLE 0x0040u /* force JSON streaming */ +#define WATCH_OLDSTYLE 0x0080u /* force old-style streaming */ +#define WATCH_DEVICE 0x0100u /* watch specific device */ +#define WATCH_DISABLE 0x0200u /* disable watching */ +#define POLL_NONBLOCK 0x1000u /* set non-blocking poll (experimental!) */ + +/* + * Main structure that includes all previous substructures + */ + +struct gps_data_t { + gps_mask_t set; /* has field been set since this was last cleared? */ +#define ONLINE_SET 0x00000001u +#define TIME_SET 0x00000002u +#define TIMERR_SET 0x00000004u +#define LATLON_SET 0x00000008u +#define ALTITUDE_SET 0x00000010u +#define SPEED_SET 0x00000020u +#define TRACK_SET 0x00000040u +#define CLIMB_SET 0x00000080u +#define STATUS_SET 0x00000100u +#define MODE_SET 0x00000200u +#define DOP_SET 0x00000400u +#define VERSION_SET 0x00000800u +#define HERR_SET 0x00001000u +#define VERR_SET 0x00002000u +#define ATTITUDE_SET 0x00004000u +#define POLICY_SET 0x00008000u +#define SATELLITE_SET 0x00010000u +#define RAW_SET 0x00020000u +#define USED_SET 0x00040000u +#define SPEEDERR_SET 0x00080000u +#define TRACKERR_SET 0x00100000u +#define CLIMBERR_SET 0x00200000u +#define DEVICE_SET 0x00400000u +#define DEVICELIST_SET 0x00800000u +#define DEVICEID_SET 0x01000000u +#define ERROR_SET 0x02000000u +#define RTCM2_SET 0x04000000u +#define RTCM3_SET 0x08000000u +#define AIS_SET 0x10000000u +#define PACKET_SET 0x20000000u +#define AUXDATA_SET 0x80000000u /* reserved */ + double online; /* NZ if GPS is on line, 0 if not. + * + * Note: gpsd clears this time when sentences + * fail to show up within the GPS's normal + * send cycle time. If the host-to-GPS + * link is lossy enough to drop entire + * sentences, this field will be + * prone to false zero values. + */ + +#ifndef USE_QT + socket_t gps_fd; /* socket or file descriptor to GPS */ +#else + void* gps_fd; +#endif + struct gps_fix_t fix; /* accumulated PVT data */ + + double separation; /* Geoidal separation, MSL - WGS84 (Meters) */ + + /* GPS status -- always valid */ + int status; /* Do we have a fix? */ +#define STATUS_NO_FIX 0 /* no */ +#define STATUS_FIX 1 /* yes, without DGPS */ +#define STATUS_DGPS_FIX 2 /* yes, with DGPS */ + + /* precision of fix -- valid if satellites_used > 0 */ + int satellites_used; /* Number of satellites used in solution */ + int used[MAXCHANNELS]; /* PRNs of satellites used in solution */ + struct dop_t dop; + + /* redundant with the estimate elements in the fix structure */ + double epe; /* spherical position error, 95% confidence (meters) */ + + /* satellite status -- valid when satellites_visible > 0 */ + double skyview_time; /* skyview timestamp */ + int satellites_visible; /* # of satellites in view */ + int PRN[MAXCHANNELS]; /* PRNs of satellite */ + int elevation[MAXCHANNELS]; /* elevation of satellite */ + int azimuth[MAXCHANNELS]; /* azimuth */ + double ss[MAXCHANNELS]; /* signal-to-noise ratio (dB) */ + + struct devconfig_t dev; /* device that shipped last update */ + + struct policy_t policy; /* our listening policy */ + + char tag[MAXTAGLEN+1]; /* tag of last sentence processed */ + + void (*raw_hook)(struct gps_data_t *, char *, size_t len); /* Raw-mode hook for GPS data. */ + + /* pack things never reported together to reduce structure size */ +#define UNION_SET (RTCM2_SET|RTCM3_SET|AIS_SET|VERSION_SET|DEVICELIST_SET|ERROR_SET) + union { + /* unusual forms of sensor data that might come up the pipe */ + struct rtcm2_t rtcm2; + struct rtcm3_t rtcm3; + struct ais_t ais; + struct attitude_t attitude; + struct rawdata_t raw; + /* "artificial" structures for various protocol responses */ + struct version_t version; + struct { + double time; + int ndevices; + struct devconfig_t list[MAXUSERDEVS]; + } devices; + char error[80]; + }; + + /* Private data - client code must not set this */ + void *privdata; +}; + +extern int gps_open_r(/*@null@*/const char *, /*@null@*/const char *, + /*@out@*/struct gps_data_t *); +extern /*@null@*/struct gps_data_t *gps_open(const char *, const char *); +extern int gps_close(struct gps_data_t *); +extern int gps_send(struct gps_data_t *, const char *, ... ); +extern int gps_read(/*@out@*/struct gps_data_t *); +extern int gps_poll(/*@out@*/struct gps_data_t *); +extern bool gps_waiting(struct gps_data_t *); +extern int gps_stream(struct gps_data_t *, unsigned int, /*@null@*/void *); +extern void gps_set_raw_hook(struct gps_data_t *, + void (*)(struct gps_data_t *, char *, size_t)); +extern char /*@observer@*/ *gps_errstr(const int); + +/* this only needs to be visible for the unit tests */ +extern int gps_unpack(char *, struct gps_data_t *); + +/* dependencies on struct gpsdata_t end hrere */ + +extern void gps_clear_fix(/*@ out @*/struct gps_fix_t *); +extern void gps_merge_fix(/*@ out @*/struct gps_fix_t *, + gps_mask_t, + /*@ in @*/struct gps_fix_t *); +extern void gps_enable_debug(int, FILE *); +extern /*@observer@*/const char *gps_maskdump(gps_mask_t); + +extern time_t mkgmtime(register struct tm *); +extern double timestamp(void); +extern double iso8601_to_unix(char *); +extern /*@observer@*/char *unix_to_iso8601(double t, /*@ out @*/char[], size_t len); +extern double gpstime_to_unix(int, double); +extern void unix_to_gpstime(double, /*@out@*/int *, /*@out@*/double *); +extern double earth_distance(double, double, double, double); +extern double wgs84_separation(double, double); + +/* some multipliers for interpreting GPS output */ +#define METERS_TO_FEET 3.2808399 /* Meters to U.S./British feet */ +#define METERS_TO_MILES 0.00062137119 /* Meters to miles */ +#define KNOTS_TO_MPH 1.1507794 /* Knots to miles per hour */ +#define KNOTS_TO_KPH 1.852 /* Knots to kilometers per hour */ +#define KNOTS_TO_MPS 0.51444444 /* Knots to meters per second */ +#define MPS_TO_KPH 3.6 /* Meters per second to klicks/hr */ +#define MPS_TO_MPH 2.2369363 /* Meters/second to miles per hour */ +#define MPS_TO_KNOTS 1.9438445 /* Meters per second to knots */ +/* miles and knots are both the international standard versions of the units */ + +/* angle conversion multipliers */ +#define GPS_PI 3.1415926535897932384626433832795029 +#define RAD_2_DEG 57.2957795130823208767981548141051703 +#define DEG_2_RAD 0.0174532925199432957692369076848861271 + +/* geodetic constants */ +#define WGS84A 6378137 /* equatorial radius */ +#define WGS84F 298.257223563 /* flattening */ +#define WGS84B 6356752.3142 /* polar radius */ + +/* netlib_connectsock() errno return values */ +#define NL_NOSERVICE -1 /* can't get service entry */ +#define NL_NOHOST -2 /* can't get host entry */ +#define NL_NOPROTO -3 /* can't get protocol entry */ +#define NL_NOSOCK -4 /* can't create socket */ +#define NL_NOSOCKOPT -5 /* error SETSOCKOPT SO_REUSEADDR */ +#define NL_NOCONNECT -6 /* can't connect to host/socket pair */ + +#define DEFAULT_GPSD_PORT "2947" /* IANA assignment */ +#define DEFAULT_RTCM_PORT "2101" /* IANA assignment */ + +#ifdef __cplusplus +} /* End of the 'extern "C"' block */ +#endif + +/* gps.h ends here */ +#endif /* _GPSD_GPS_H_ */ diff --git a/gps.xml b/gps.xml new file mode 100644 index 0000000..a8f548e --- /dev/null +++ b/gps.xml @@ -0,0 +1,312 @@ + + + + +9 Aug 2004 + +gps +1 +The GPSD Project +GPSD Documentation + + +gps +xgps +xgpsspeed +cgps +lcdgps +test clients for gpsd + + + + + xgps + -D debug-level + -h + -V + -l dms + -u inm + + server + + :port + :device + + + + + xgpsspeed + -D debug-level + -h + -V + --speedunits + + mphkphknots + + + + server + + :port + :device + + + + + cgps + -D debug-level + -h + -V + -l dms + -m + -s + -u inm + + server + + :port + :device + + + + + lcdgps + -h + -V + -l dms + -u inm + + server + + :port + :device + + + + + gpxlogger + + + gpxlogger + -D debug-level + -h + -V + -i track timeout + + server + + :port + :device + + + + + +DESCRIPTION + +These are the demonstration clients shipped with +gpsd. They have some common options: + +The option causes each client to emit a summary of its +options and then exit. + +The option causes each client to dump the package +version and exit. + + The option, when present, sets the format +of latitude and longitude reports. The value 'd' produces decimal +degrees and is the default. The value 'm' produces degrees and +decimal minutes. The value 's' produces degrees, minutes, and decimal +seconds. + +xgps, +cgps, and ldcgps +look at variables in the environment to figure out what units they +should default to using for display — imperial, nautical, or +metric. Here are the variables and values they check: + + + GPSD_UNITS one of: + imperial = miles/feet + nautical = knots/feet + metric = km/meters + LC_MEASUREMENT + en_US = miles/feet + C = miles/feet + POSIX = miles/feet + [other] = km/meters + LANG + en_US = miles/feet + C = miles/feet + POSIX = miles/feet + [other] = km/meters + +These preferences may be overridden by the +option. + +Where present, the option can be used to set +the system units for display; follow the keyword with 'i' for +'imperial' for American units (feet in altitude and error estimates, +miles per hour in speeds), 'n' for 'nautical' (feet in altitude and +error estimates, knots in speed) or 'm' for 'metric' (meters in +altitude and error estimates, kiliometers per hour in speeds). + + The option, when present, sets a debug +level; it is primarily for use by GPSD developers. It enables +various progress messages to standard error. + +By default, clients collect data from all compatible devices on +localhost, using the defalt GPSD port 2947. An optional argument to any +client may specify a server to get data from. A colon-separated suffix +is taken as a port number. If there is a second colon-separated +suffix, that is taken as a specific device name to be +watched. However, if the server specification contains square +brackets, the part inside them is taken as an IPv6 address and +port/device suffixes are obnly parsed after the trailing bracket. +Possible cases look like this: + + + +localhost:/dev/ttyS1 +Look at the default port of localhost, trying both +IPv4 and IPv6 and watching ouput from serial device 1. + + +example.com:2317 +Look at port 2317 on example.com, trying both +IPv4 and IPv6. + + +71.162.241.5:2317:/dev/ttyS3 +Look at port 2317 at the specified IPv4 +address, collecting data from attached serial device 3. + + +[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:2317:/dev/ttyS5 +Look at port 2317 at the specified IPv6 +address, collecting data from attached serial device 5. + + + +Not all clients shipped with GPSD are documented here. See also +the separate manual pages for +gpspipe1 +and +gpsmon1. + +xgps + +xgps is a simple test client for +gpsd with an X interface. It displays +current GPS position/time/velocity information and (for GPSes that +support the feature) the locations of accessible satellites. + +In the sky view, satellites are color-coded to indicate quality +of signal; consult the data display to the left for exact figures in +dB. Square icons indicate WAAS/EGNOS satellites, circles indicate +ordinary GPS satellites. Filled icons were used in the last fix, +outline icons were not. + + +xgpsspeed + +xgpsspeed is a speedometer that uses +position information from the GPS. It accepts an -h option and +optional argument as for gps, or a -V +option to dump the package version and exit. + +The -speedunits option can be used to set the speed units for +display; follow the keyword with knots for nautical miles per hour, +kph for kilometres per hour, or mph for miles per hour. The default +is miles per hour. + + +cgps + +cgps is a client resembling +xgps, but without the pictorial +satellite display and able to run on a serial terminal or +terminal emulator. + + The option prevents cgps +from displaying the raw data. This display can also be toggled with the s +command. + +The option will display your magnetic +heading (as opposed to your true heading). This is a calculated +value, not a measured value, and is subject to a potential error of up +to two degrees in the areas for which the calculation is valid +(currently Western Europe, Alaska, and Lower 48 in the USA). The +formulas used are those found in the Aviation Formulary v1.43. + +cgps terminates when you send it a +SIGHUP or SIGINT; given default terminal settings this will happen +when you type Ctl-C at it. It will also terminate on 'q' + + +lcdgps + +A client that passes gpsd data to +lcdproc, turning your car computer into a +very expensive and nearly feature-free GPS receiver. Currently +assumes a 4x40 LCD and writes data formatted to fit that size screen. +Also displays 4- or 6-character Maidenhead grid square output. + + +gpxlogger + +This program collects fixes from gpsd +and logs them to standard output in GPX, an XML profile for track +logging. + +The output may be composed of multiple tracks. A new track is +created if there's no fix for an interval specified by the + and defaulting to 5 seconds. + +If D-Bus support is available on the host and GPSD is +configured to use it, this program listens to DBUS broadcasts +from gpsd. (org.gpsd.fix). Otherwise, +it uses a conventional socket connection. + +Presence of a server-port-device specification forces use of +sockets even on a D-Bus capable system, though this is unlikely to be +of interest to anyone except GPSD developers. + + + +SEE ALSO + +gpsd8, +libgps3, +libgpsd3, +gpsfake1, +gpsctl1, +gpscat1, +gpsprof1. +gpspipe1. +gpsmon1. + + + +AUTHORS + + +Remco Treffcorn, Derrick Brashear, Russ Nelson & Eric S. Raymond, +Jeff Francis (cgps). Amaury Jacquot sxpert@sxpert.org +& Petter Reinholdtsen pere@hungry.com (gpxlogger). +Chris Kuethe chris.kuethe@gmail.com (cgpxlogger). + + +This manual page by Eric S. Raymond esr@thyrsus.com. +There is a project page, with xgps +screenshots, at berlios.de. + + + + + diff --git a/gps/__init__.py b/gps/__init__.py new file mode 100644 index 0000000..8766f7c --- /dev/null +++ b/gps/__init__.py @@ -0,0 +1,13 @@ +# Make core client functions available without prefix. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. + +api_major_version = 4 # bumped on incompatible changes +api_minor_version = 1 # bumped on compatible changes + +from gps import * +from misc import * + +# The 'client' module exposes some C utility functions for Python clients. +# The 'packet' module exposes the packet getter via a Python interface. diff --git a/gps/client.py b/gps/client.py new file mode 100644 index 0000000..6a62da5 --- /dev/null +++ b/gps/client.py @@ -0,0 +1,202 @@ +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +import time, socket, sys, select + +if sys.hexversion >= 0x2060000: + import json # For Python 2.6 +else: + import simplejson as json # For Python 2.4 and 2.5 + +GPSD_PORT="2947" + +class gpscommon: + "Isolate socket handling and buffering from the protcol interpretation." + def __init__(self, host="127.0.0.1", port=GPSD_PORT, verbose=0): + self.sock = None # in case we blow up in connect + self.linebuffer = "" + self.verbose = verbose + self.connect(host, port) + + def connect(self, host, port): + """Connect to a host on a given port. + + If the hostname ends with a colon (`:') followed by a number, and + there is no port specified, that suffix will be stripped off and the + number interpreted as the port number to use. + """ + if not port and (host.find(':') == host.rfind(':')): + i = host.rfind(':') + if i >= 0: + host, port = host[:i], host[i+1:] + try: port = int(port) + except ValueError: + raise socket.error, "nonnumeric port" + #if self.verbose > 0: + # print 'connect:', (host, port) + msg = "getaddrinfo returns an empty list" + self.sock = None + for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + try: + self.sock = socket.socket(af, socktype, proto) + #if self.debuglevel > 0: print 'connect:', (host, port) + self.sock.connect(sa) + except socket.error, msg: + #if self.debuglevel > 0: print 'connect fail:', (host, port) + self.close() + continue + break + if not self.sock: + raise socket.error, msg + + def close(self): + if self.sock: + self.sock.close() + self.sock = None + + def __del__(self): + self.close() + + def waiting(self): + "Return True if data is ready for the client." + if self.linebuffer: + return True + (winput, woutput, wexceptions) = select.select((self.sock,), (), (), 0) + return winput != [] + + def read(self): + "Wait for and read data being streamed from the daemon." + if self.verbose > 1: + sys.stderr.write("poll: reading from daemon...\n") + eol = self.linebuffer.find('\n') + if eol == -1: + frag = self.sock.recv(4096) + self.linebuffer += frag + if self.verbose > 1: + sys.stderr.write("poll: read complete.\n") + if not self.linebuffer: + if self.verbose > 1: + sys.stderr.write("poll: returning -1.\n") + # Read failed + return -1 + eol = self.linebuffer.find('\n') + if eol == -1: + if self.verbose > 1: + sys.stderr.write("poll: returning 0.\n") + # Read succeeded, but only got a fragment + return 0 + else: + if self.verbose > 1: + sys.stderr.write("poll: fetching from buffer.\n") + + # We got a line + eol += 1 + self.response = self.linebuffer[:eol] + self.linebuffer = self.linebuffer[eol:] + + # Can happen if daemon terminates while we're reading. + if not self.response: + return -1 + if self.verbose: + sys.stderr.write("poll: data is %s\n" % repr(self.response)) + self.received = time.time() + # We got a \n-terminated line + return len(self.response) + + def send(self, commands): + "Ship commands to the daemon." + if not commands.endswith("\n"): + commands += "\n" + self.sock.send(commands) + +WATCH_DISABLE = 0x0000 +WATCH_ENABLE = 0x0001 +WATCH_JSON = 0x0002 +WATCH_NMEA = 0x0004 +WATCH_RARE = 0x0008 +WATCH_RAW = 0x0010 +WATCH_SCALED = 0x0020 +WATCH_DEVICE = 0x0040 + +class gpsjson(gpscommon): + "Basic JSON decoding." + def __iter__(self): + return self + + def json_unpack(self, buf): + def asciify(d): + "De-Unicodify everything so we can copy dicts into Python objects." + t = {} + for (k, v) in d.items(): + ka = k.encode("ascii") + if type(v) == type(u"x"): + va = v.encode("ascii") + elif type(v) == type({}): + va = asciify(v) + elif type(v) == type([]): + va = map(asciify, v) + else: + va = v + t[ka] = va + return t + self.data = dictwrapper(**asciify(json.loads(buf.strip(), encoding="ascii"))) + # Should be done for any other array-valued subobjects, too. + if self.data["class"] == "SKY" and hasattr(self.data, "satellites"): + self.data.satellites = map(lambda x: dictwrapper(**x), self.data.satellites) + + def stream(self, flags=0, outfile=None): + "Control streaming reports from the daemon," + if flags & WATCH_DISABLE: + arg = '?WATCH={"enable":false' + if flags & WATCH_JSON: + arg += ',"json":false' + if flags & WATCH_NMEA: + arg += ',"nmea":false' + if flags & WATCH_RARE: + arg += ',"raw":1' + if flags & WATCH_RAW: + arg += ',"raw":2' + if flags & WATCH_SCALED: + arg += ',"scaled":false' + else: # flags & WATCH_ENABLE: + arg = '?WATCH={"enable":true' + if flags & WATCH_JSON: + arg += ',"json":true' + if flags & WATCH_NMEA: + arg += ',"nmea":true' + if flags & WATCH_RAW: + arg += ',"raw":1' + if flags & WATCH_RARE: + arg += ',"raw":0' + if flags & WATCH_SCALED: + arg += ',"scaled":true' + if flags & WATCH_DEVICE: + arg += ',"device":"%s"' % outfile + return self.send(arg + "}") + +class dictwrapper: + "Wrapper that yields both class and dictionary behavior," + def __init__(self, **ddict): + self.__dict__ = ddict + def get(self, k, d=None): + return self.__dict__.get(k, d) + def keys(self): + return self.__dict__.keys() + def __getitem__(self, key): + "Emulate dictionary, for new-style interface." + return self.__dict__[key] + def __setitem__(self, key, val): + "Emulate dictionary, for new-style interface." + self.__dict__[key] = val + def __contains__(self, key): + return key in self.__dict__ + def __str__(self): + return "" + __repr__ = __str__ + +# +# Someday a cleaner Python iterface using this machiner will live here +# + +# End diff --git a/gps/fake.py b/gps/fake.py new file mode 100644 index 0000000..9d742f2 --- /dev/null +++ b/gps/fake.py @@ -0,0 +1,593 @@ +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +""" +gpsfake.py -- classes for creating a controlled test environment around gpsd. + +The gpsfake(1) regression tester shipped with gpsd is a trivial wrapper +around this code. For a more interesting usage example, see the +valgrind-audit script shipped with the gpsd code. + +To use this code, start by instantiating a TestSession class. Use the +prefix argument if you want to run the daemon under some kind of run-time +monitor like valgrind or gdb. Here are some particularly useful possibilities: + +valgrind --tool=memcheck --gen-suppressions=yes --leak-check=yes + Run under Valgrind, checking for malloc errors and memory leaks. + +xterm -e gdb -tui --args + Run under gdb, controlled from a new xterm. + +You can use the options argument to pass in daemon options; normally you will +use this to set the debug-logging level. + +On initialization, the test object spawns an instance of gpsd with no +devices or clients attached, connected to a control socket. + +TestSession has methods to attach and detch fake GPSes. The +TestSession class simulates GPS devices for you with objects composed +from a pty and a class instance that cycles sentences into the master side +from some specified logfile; gpsd reads the slave side. A fake GPS is +identified by the string naming its slave device. + +TestSession also has methods to start and end client sessions. Daemon +responses to a client are fed to a hook function which, by default, +discards them. You can change the hook to sys.stdout.write() to dump +responses to standard output (this is what the gpsfake executable +does) or do something more exotic. A client session is identified by a +small integer that counts the number of client session starts. + +There are a couple of convenience methods. TestSession.wait() does nothing, +allowing a specified number of seconds to elapse. TestSession.send() +ships commands to an open client session. + +TestSession does not currently capture the daemon's log output. It is +run with -N, so the output will go to stderr (along with, for example, +Valgrind notifications). + +Each FakeGPS instance tries to packetize the data from the logfile it +is initialized with. It uses the same packet-getter as the daeomon. + +The TestSession code maintains a run queue of FakeGPS and gps.gs (client- +session) objects. It repeatedly cycles through the run queue. For each +client session object in the queue, it tries to read data from gpsd. For +each fake GPS, it sends one line of stored data. When a fake-GPS's +go predicate becomes false, the fake GPS is removed from the run queue. + +There are two ways to use this code. The more deterministic is +non-threaded mode: set up your client sessions and fake GPS devices, +then call the run() method. The run() method will terminate when +there are no more objects in the run queue. Note, you must have +created at least one fake client or fake GPS before calling run(), +otherwise it will terminate immediately. + +To allow for adding and removing clients while the test is running, +run in threaded mode by calling the start() method. This simply calls +the run method in a subthread, with locking of critical regions. +""" +import sys, os, time, signal, pty, termios # fcntl, array, struct +import exceptions, threading, socket +import gps +import packet as sniffer + +# The two magic numbers below have to be derived from observation. If +# they're too high you'll slow the tests down a lot. If they're too low +# you'll get random spurious regression failures that usually look +# like lines missing from the end of the test output relative to the +# check file. These numbers might have to be adjusted upward on faster +# machines. The need for them may be symnptomatic of race conditions +# in the pty layer or elsewhere. + +# Define a per-line delay on writes so we won't spam the buffers in +# the pty layer or gpsd itself. Removing this entirely was tried but +# caused failures under NetBSD. Values smaller than the system timer +# tick don't make any difference here. +WRITE_PAD = 0.001 + +# We delay briefly after a GPS source is exhausted before removing it. +# This should give its subscribers time to get gpsd's response before +# we call the cleanup code. Note that using fractional seconds in +# CLOSE_DELAY may have no effect; Python time.time() returns a float +# value, but it is not guaranteed by Python that the C implementation +# underneath will return with precision finer than 1 second. (Linux +# and *BSD return full precision.) +CLOSE_DELAY = 1 + +class TestLoadError(exceptions.Exception): + def __init__(self, msg): + self.msg = msg + +class TestLoad: + "Digest a logfile into a list of sentences we can cycle through." + def __init__(self, logfp, predump=False): + self.sentences = [] # This is the interesting part + if type(logfp) == type(""): + logfp = open(logfp, "r"); + self.name = logfp.name + self.logfp = logfp + self.predump = predump + self.logfile = logfp.name + self.type = None + self.sourcetype = "pty" + self.serial = None + # Grab the packets + getter = sniffer.new() + #gps.packet.register_report(reporter) + type_latch = None + while True: + (len, ptype, packet) = getter.get(logfp.fileno()) + if len <= 0: + break + elif ptype == sniffer.COMMENT_PACKET: + # Some comments are magic + if "Serial:" in packet: + # Change serial parameters + packet = packet[1:].strip() + try: + (xx, baud, params) = packet.split() + baud = int(baud) + if params[0] in ('7', '8'): + databits = int(params[0]) + else: + raise ValueError + if params[1] in ('N', 'O', 'E'): + parity = params[1] + else: + raise ValueError + if params[2] in ('1', '2'): + stopbits = int(params[2]) + else: + raise ValueError + except (ValueError, IndexError): + raise TestLoadError("bad serial-parameter spec in %s"%\ + logfp.name) + self.serial = (baud, databits, parity, stopbits) + elif "UDP" in packet: + self.sourcetype = "UDP" + elif "%" in packet: + # Pass through for later interpretation + self.sentences.append(packet) + else: + if type_latch is None: + type_latch = ptype + if self.predump: + print `packet` + if not packet: + raise TestLoadError("zero-length packet from %s"%\ + logfp.name) + self.sentences.append(packet) + # Look at the first packet to grok the GPS type + self.textual = (type_latch == sniffer.NMEA_PACKET) + if self.textual: + self.legend = "gpsfake: line %d: " + else: + self.legend = "gpsfake: packet %d" + +class PacketError(exceptions.Exception): + def __init__(self, msg): + self.msg = msg + +class FakeGPS: + def __init__(self, testload, progress=None): + self.testload = testload + self.progress = progress + self.go_predicate = lambda: True + self.readers = 0 + self.index = 0 + self.progress("gpsfake: %s provides %d sentences\n" % (self.testload.name, len(self.testload.sentences))) + + def feed(self): + "Feed a line from the contents of the GPS log to the daemon." + line = self.testload.sentences[self.index % len(self.testload.sentences)] + if "%Delay:" in line: + # Delay specified number of seconds + delay = line.split()[1] + time.sleep(int(delay)) + # self.write has to be set by the derived class + self.write(line) + if self.progress: + self.progress("gpsfake: %s feeds %d=%s\n" % (self.testload.name, len(line), `line`)) + time.sleep(WRITE_PAD) + self.index += 1 + +class FakePTY(FakeGPS): + "A FakePTY is a pty with a test log ready to be cycled to it." + def __init__(self, testload, + speed=4800, databits=8, parity='N', stopbits=1, + progress=None): + FakeGPS.__init__(self, testload, progress) + # Allow Serial: header to be overridden by explicit spped. + if self.testload.serial: + (speed, databits, parity, stopbits) = self.testload.serial + self.speed = speed + baudrates = { + 0: termios.B0, + 50: termios.B50, + 75: termios.B75, + 110: termios.B110, + 134: termios.B134, + 150: termios.B150, + 200: termios.B200, + 300: termios.B300, + 600: termios.B600, + 1200: termios.B1200, + 1800: termios.B1800, + 2400: termios.B2400, + 4800: termios.B4800, + 9600: termios.B9600, + 19200: termios.B19200, + 38400: termios.B38400, + 57600: termios.B57600, + 115200: termios.B115200, + 230400: termios.B230400, + } + speed = baudrates[speed] # Throw an error if the speed isn't legal + (self.fd, self.slave_fd) = pty.openpty() + self.byname = os.ttyname(self.slave_fd) + (iflag, oflag, cflag, lflag, ispeed, ospeed, cc) = termios.tcgetattr(self.slave_fd) + cc[termios.VMIN] = 1 + cflag &= ~(termios.PARENB | termios.PARODD | termios.CRTSCTS) + cflag |= termios.CREAD | termios.CLOCAL + iflag = oflag = lflag = 0 + iflag &=~ (termios.PARMRK | termios.INPCK) + cflag &=~ (termios.CSIZE | termios.CSTOPB | termios.PARENB | termios.PARODD) + if databits == 7: + cflag |= termios.CS7 + else: + cflag |= termios.CS8 + if stopbits == 2: + cflag |= termios.CSTOPB + if parity == 'E': + iflag |= termios.INPCK + cflag |= termios.PARENB + elif parity == 'O': + iflag |= termios.INPCK + cflag |= termios.PARENB | termios.PARODD + ispeed = ospeed = speed + termios.tcsetattr(self.slave_fd, termios.TCSANOW, + [iflag, oflag, cflag, lflag, ispeed, ospeed, cc]) + def read(self): + "Discard control strings written by gpsd." + # A tcflush implementation works on Linux but fails on OpenBSD 4. + termios.tcflush(self.fd, termios.TCIFLUSH) + # Alas, the FIONREAD version also works on Linux and fails on OpenBSD. + #try: + # buf = array.array('i', [0]) + # fcntl.ioctl(self.master_fd, termios.FIONREAD, buf, True) + # n = struct.unpack('i', buf)[0] + # os.read(self.master_fd, n) + #except IOError: + # pass + + def write(self, line): + os.write(self.fd, line) + + def drain(self): + "Wait for the associated device to drain (e.g. before closing)." + termios.tcdrain(self.fd) + +class FakeUDP(FakeGPS): + "A UDP broadcaster with a test log ready to be cycled to it." + def __init__(self, testload, + ipaddr, port, + progress=None): + FakeGPS.__init__(self, testload, progress) + self.ipaddr = ipaddr + self.port = port + self.byname = "udp://" + ipaddr + ":" + port + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + def read(self): + "Discard control strings written by gpsd." + pass + + def write(self, line): + self.sock.sendto(line, (self.ipaddr, int(self.port))) + + def drain(self): + "Wait for the associated device to drain (e.g. before closing)." + pass # shutdown() fails on UDP + +class DaemonError(exceptions.Exception): + def __init__(self, msg): + self.msg = msg + def __str__(self): + return repr(self.msg) + +class DaemonInstance: + "Control a gpsd instance." + def __init__(self, control_socket=None): + self.sockfile = None + self.pid = None + if control_socket: + self.control_socket = control_socket + else: + self.control_socket = "/tmp/gpsfake-%d.sock" % os.getpid() + self.pidfile = "/tmp/gpsfake_pid-%s" % os.getpid() + def spawn(self, options, port, background=False, prefix=""): + "Spawn a daemon instance." + self.spawncmd = None + + # Look for gpsd in GPSD_HOME env variable + if os.environ.get('GPSD_HOME'): + for path in os.environ['GPSD_HOME'].split(':'): + _spawncmd = "%s/gpsd" % path + if os.path.isfile(_spawncmd) and os.access(_spawncmd, os.X_OK): + self.spawncmd = _spawncmd + break + + # if we could not find it yet try PATH env variable for it + if not self.spawncmd: + if not '/usr/sbin' in os.environ['PATH']: + os.environ['PATH']=os.environ['PATH'] + ":/usr/sbin" + for path in os.environ['PATH'].split(':'): + _spawncmd = "%s/gpsd" % path + if os.path.isfile(_spawncmd) and os.access(_spawncmd, os.X_OK): + self.spawncmd = _spawncmd + break + + if not self.spawncmd: + raise DaemonError("Cannot execute gpsd: executable not found. Set GPSD_HOME env variable") + # The -b option to suppress hanging on probe returns is needed to cope + # with OpenBSD (and possibly other non-Linux systems) that don't support + # anything we can use to implement the FakeGPS.read() method + self.spawncmd += " -b -N -S %s -F %s -P %s %s" % (port, self.control_socket, self.pidfile, options) + if prefix: + self.spawncmd = prefix + " " + self.spawncmd.strip() + if background: + self.spawncmd += " &" + status = os.system(self.spawncmd) + if os.WIFSIGNALED(status) or os.WEXITSTATUS(status): + raise DaemonError("daemon exited with status %d" % status) + def wait_pid(self): + "Wait for the daemon, get its PID and a control-socket connection." + while True: + try: + fp = open(self.pidfile) + except IOError: + time.sleep(0.1) + continue + try: + fp.seek(0) + pidstr = fp.read() + self.pid = int(pidstr) + except ValueError: + time.sleep(0.5) + continue # Avoid race condition -- PID not yet written + fp.close() + break + def __get_control_socket(self): + # Now we know it's running, get a connection to the control socket. + if not os.path.exists(self.control_socket): + return None + try: + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0) + self.sock.connect(self.control_socket) + except socket.error: + if self.sock: + self.sock.close() + self.sock = None + return self.sock + def is_alive(self): + "Is the daemon still alive?" + try: + os.kill(self.pid, 0) + return True + except OSError: + return False + def add_device(self, path): + "Add a device to the daemon's internal search list." + if self.__get_control_socket(): + self.sock.sendall("+%s\r\n\x00" % path) + self.sock.recv(12) + self.sock.close() + def remove_device(self, path): + "Remove a device from the daemon's internal search list." + if self.__get_control_socket(): + self.sock.sendall("-%s\r\n\x00" % path) + self.sock.recv(12) + self.sock.close() + def kill(self): + "Kill the daemon instance." + if self.pid: + try: + os.kill(self.pid, signal.SIGTERM) + # Raises an OSError for ESRCH when we've killed it. + while True: + os.kill(self.pid, signal.SIGTERM) + time.sleep(0.01) + except OSError: + pass + self.pid = None + +class TestSessionError(exceptions.Exception): + def __init__(self, msg): + self.msg = msg + +class TestSession: + "Manage a session including a daemon with fake GPSes and clients." + def __init__(self, prefix=None, port=None, options=None, verbose=0, predump=False, udp=False): + "Initialize the test session by launching the daemon." + self.prefix = prefix + self.port = port + self.options = options + self.verbose = verbose + self.predump = predump + self.udp = udp + self.daemon = DaemonInstance() + self.fakegpslist = {} + self.client_id = 0 + self.readers = 0 + self.writers = 0 + self.runqueue = [] + self.index = 0 + if port: + self.port = port + else: + self.port = gps.GPSD_PORT + self.progress = lambda x: None + self.reporter = lambda x: None + self.default_predicate = None + self.fd_set = [] + self.threadlock = None + def spawn(self): + for sig in (signal.SIGQUIT, signal.SIGINT, signal.SIGTERM): + signal.signal(sig, lambda signal, frame: self.cleanup()) + self.daemon.spawn(background=True, prefix=self.prefix, port=self.port, options=self.options) + self.daemon.wait_pid() + def set_predicate(self, pred): + "Set a default go predicate for the session." + self.default_predicate = pred + def gps_add(self, logfile, speed=19200, pred=None): + "Add a simulated GPS being fed by the specified logfile." + self.progress("gpsfake: gps_add(%s, %d)\n" % (logfile, speed)) + if logfile not in self.fakegpslist: + testload = TestLoad(logfile, predump=self.predump) + if testload.sourcetype == "UDP" or self.udp: + newgps = FakeUDP(testload, ipaddr="127.0.0.1", port="5000", + progress=self.progress) + else: + newgps = FakePTY(testload, speed=speed, + progress=self.progress) + if pred: + newgps.go_predicate = pred + elif self.default_predicate: + newgps.go_predicate = self.default_predicate + self.fakegpslist[newgps.byname] = newgps + self.append(newgps) + newgps.exhausted = 0 + self.daemon.add_device(newgps.byname) + return newgps.byname + def gps_remove(self, name): + "Remove a simulated GPS from the daemon's search list." + self.progress("gpsfake: gps_remove(%s)\n" % name) + self.fakegpslist[name].drain() + self.remove(self.fakegpslist[name]) + self.daemon.remove_device(name) + del self.fakegpslist[name] + def client_add(self, commands): + "Initiate a client session and force connection to a fake GPS." + self.progress("gpsfake: client_add()\n") + newclient = gps.gps(port=self.port, verbose=self.verbose) + self.append(newclient) + newclient.id = self.client_id + 1 + self.client_id += 1 + self.progress("gpsfake: client %d has %s\n" % (self.client_id,newclient.device)) + if commands: + self.initialize(newclient, commands) + return self.client_id + def client_remove(self, cid): + "Terminate a client session." + self.progress("gpsfake: client_remove(%d)\n" % cid) + for obj in self.runqueue: + if isinstance(obj, gps.gps) and obj.id == cid: + self.remove(obj) + return True + else: + return False + def wait(self, seconds): + "Wait, doing nothing." + self.progress("gpsfake: wait(%d)\n" % seconds) + time.sleep(seconds) + def gather(self, seconds): + "Wait, doing nothing but watching for sentences." + self.progress("gpsfake: gather(%d)\n" % seconds) + #mark = time.time() + time.sleep(seconds) + #if self.timings.c_recv_time <= mark: + # TestSessionError("no sentences received\n") + def cleanup(self): + "We're done, kill the daemon." + self.progress("gpsfake: cleanup()\n") + if self.daemon: + self.daemon.kill() + self.daemon = None + def run(self): + "Run the tests." + try: + self.progress("gpsfake: test loop begins\n") + while self.daemon: + # We have to read anything that gpsd might have tried + # to send to the GPS here -- under OpenBSD the + # TIOCDRAIN will hang, otherwise. + for device in self.runqueue: + if isinstance(device, FakeGPS): + device.read() + had_output = False + chosen = self.choose() + if isinstance(chosen, FakeGPS): + if chosen.exhausted and (time.time() - chosen.exhausted > CLOSE_DELAY): + self.gps_remove(chosen.byname) + self.progress("gpsfake: GPS %s removed\n" % chosen.byname) + elif not chosen.go_predicate(chosen.index, chosen): + if chosen.exhausted == 0: + chosen.exhausted = time.time() + self.progress("gpsfake: GPS %s ran out of input\n" % chosen.byname) + else: + chosen.feed() + elif isinstance(chosen, gps.gps): + if chosen.enqueued: + chosen.send(chosen.enqueued) + chosen.enqueued = "" + while chosen.waiting(): + chosen.poll() + if chosen.valid & gps.PACKET_SET: + self.reporter(chosen.response) + had_output = True + else: + raise TestSessionError("test object of unknown type") + if not self.writers and not had_output: + self.progress("gpsfake: no writers and no output\n") + break + self.progress("gpsfake: test loop ends\n") + finally: + self.cleanup() + + # All knowledge about locks and threading is below this line, + # except for the bare fact that self.threadlock is set to None + # in the class init method. + + def append(self, obj): + "Add a producer or consumer to the object list." + if self.threadlock: + self.threadlock.acquire() + self.runqueue.append(obj) + if isinstance(obj, FakeGPS): + self.writers += 1 + elif isinstance(obj, gps.gps): + self.readers += 1 + if self.threadlock: + self.threadlock.release() + def remove(self, obj): + "Remove a producer or consumer from the object list." + if self.threadlock: + self.threadlock.acquire() + self.runqueue.remove(obj) + if isinstance(obj, FakeGPS): + self.writers -= 1 + elif isinstance(obj, gps.gps): + self.readers -= 1 + self.index = min(len(self.runqueue)-1, self.index) + if self.threadlock: + self.threadlock.release() + def choose(self): + "Atomically get the next object scheduled to do something." + if self.threadlock: + self.threadlock.acquire() + chosen = self.index + self.index += 1 + self.index %= len(self.runqueue) + if self.threadlock: + self.threadlock.release() + return self.runqueue[chosen] + def initialize(self, client, commands): + "Arrange for client to ship specified commands when it goes active." + client.enqueued = "" + if not self.threadlock: + client.send(commands) + else: + client.enqueued = commands + def start(self): + self.threadlock = threading.Lock() + threading.Thread(target=self.run) + +# End diff --git a/gps/gps.py b/gps/gps.py new file mode 100755 index 0000000..9b2c62f --- /dev/null +++ b/gps/gps.py @@ -0,0 +1,374 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# gps.py -- Python interface to GPSD. +# +# This interface has a lot of historical cruft in it related to old +# protocol, and was modeled on the C interface. It won't be thrown +# away, but it's likely to be deprecated in favor of something more +# Pythonic. +# +# The JSON parts of this (which will be reused by any new interface) +# now live in a different module. +# +import time +from client import * + +NaN = float('nan') +def isnan(x): return str(x) == 'nan' + +# Don't hand-hack this list, it's generated. +ONLINE_SET = 0x00000001 +TIME_SET = 0x00000002 +TIMERR_SET = 0x00000004 +LATLON_SET = 0x00000008 +ALTITUDE_SET = 0x00000010 +SPEED_SET = 0x00000020 +TRACK_SET = 0x00000040 +CLIMB_SET = 0x00000080 +STATUS_SET = 0x00000100 +MODE_SET = 0x00000200 +DOP_SET = 0x00000400 +VERSION_SET = 0x00000800 +HERR_SET = 0x00001000 +VERR_SET = 0x00002000 +ATTITUDE_SET = 0x00004000 +POLICY_SET = 0x00008000 +SATELLITE_SET = 0x00010000 +RAW_SET = 0x00020000 +USED_SET = 0x00040000 +SPEEDERR_SET = 0x00080000 +TRACKERR_SET = 0x00100000 +CLIMBERR_SET = 0x00200000 +DEVICE_SET = 0x00400000 +DEVICELIST_SET = 0x00800000 +DEVICEID_SET = 0x01000000 +ERROR_SET = 0x02000000 +RTCM2_SET = 0x04000000 +RTCM3_SET = 0x08000000 +AIS_SET = 0x10000000 +PACKET_SET = 0x20000000 +AUXDATA_SET = 0x80000000 +UNION_SET = (RTCM2_SET|RTCM3_SET|AIS_SET|VERSION_SET|DEVICELIST_SET|ERROR_SET) + +STATUS_NO_FIX = 0 +STATUS_FIX = 1 +STATUS_DGPS_FIX = 2 +MODE_NO_FIX = 1 +MODE_2D = 2 +MODE_3D = 3 +MAXCHANNELS = 20 +SIGNAL_STRENGTH_UNKNOWN = NaN + +WATCH_NEWSTYLE = 0x00080 +WATCH_OLDSTYLE = 0x10000 + +class gpsfix: + def __init__(self): + self.mode = MODE_NO_FIX + self.time = NaN + self.ept = NaN + self.latitude = self.longitude = 0.0 + self.epx = NaN + self.epy = NaN + self.altitude = NaN # Meters + self.epv = NaN + self.track = NaN # Degrees from true north + self.speed = NaN # Knots + self.climb = NaN # Meters per second + self.epd = NaN + self.eps = NaN + self.epc = NaN + +class gpsdata: + "Position, track, velocity and status information returned by a GPS." + + class satellite: + def __init__(self, PRN, elevation, azimuth, ss, used=None): + self.PRN = PRN + self.elevation = elevation + self.azimuth = azimuth + self.ss = ss + self.used = used + def __repr__(self): + return "PRN: %3d E: %3d Az: %3d Ss: %3d Used: %s" % ( + self.PRN, self.elevation, self.azimuth, self.ss, "ny"[self.used] + ) + + def __init__(self): + # Initialize all data members + self.online = 0 # NZ if GPS on, zero if not + + self.valid = 0 + self.fix = gpsfix() + + self.status = STATUS_NO_FIX + self.utc = "" + + self.satellites_used = 0 # Satellites used in last fix + self.xdop = self.ydop = self.vdop = self.tdop = 0 + self.pdop = self.hdop = self.gdop = 0.0 + + self.epe = 0.0 + + self.satellites = [] # satellite objects in view + + self.gps_id = None + self.driver_mode = 0 + self.baudrate = 0 + self.stopbits = 0 + self.cycle = 0 + self.mincycle = 0 + self.device = None + self.devices = [] + + self.version = None + self.timings = None + + def __repr__(self): + st = "Time: %s (%s)\n" % (self.utc, self.fix.time) + st += "Lat/Lon: %f %f\n" % (self.fix.latitude, self.fix.longitude) + if isnan(self.fix.altitude): + st += "Altitude: ?\n" + else: + st += "Altitude: %f\n" % (self.fix.altitude) + if isnan(self.fix.speed): + st += "Speed: ?\n" + else: + st += "Speed: %f\n" % (self.fix.speed) + if isnan(self.fix.track): + st += "Track: ?\n" + else: + st += "Track: %f\n" % (self.fix.track) + st += "Status: STATUS_%s\n" % ("NO_FIX", "FIX", "DGPS_FIX")[self.status] + st += "Mode: MODE_%s\n" % ("ZERO", "NO_FIX", "2D", "3D")[self.fix.mode] + st += "Quality: %d p=%2.2f h=%2.2f v=%2.2f t=%2.2f g=%2.2f\n" % \ + (self.satellites_used, self.pdop, self.hdop, self.vdop, self.tdop, self.gdop) + st += "Y: %s satellites in view:\n" % len(self.satellites) + for sat in self.satellites: + st += " %r\n" % sat + return st + +class gps(gpsdata, gpsjson): + "Client interface to a running gpsd instance." + def __init__(self, host="127.0.0.1", port=GPSD_PORT, verbose=0, mode=0): + gpscommon.__init__(self, host, port, verbose) + gpsdata.__init__(self) + self.raw_hook = None + self.newstyle = False + if mode: + self.stream(mode) + + def set_raw_hook(self, hook): + self.raw_hook = hook + + def __oldstyle_unpack(self, buf): + # unpack a daemon response into the gps instance members + self.fix.time = 0.0 + fields = buf.strip().split(",") + if fields[0] == "GPSD": + for field in fields[1:]: + if not field or field[1] != '=': + continue + cmd = field[0].upper() + data = field[2:] + if data[0] == "?": + continue + if cmd == 'F': + self.device = data + elif cmd == 'I': + self.gps_id = data + elif cmd == 'O': + fields = data.split() + if fields[0] == '?': + self.fix.mode = MODE_NO_FIX + else: + def default(i, vbit=0, cnv=float): + if fields[i] == '?': + return NaN + else: + try: + value = cnv(fields[i]) + except ValueError: + return NaN + self.valid |= vbit + return value + # clear all valid bits that might be set again below + self.valid &= ~( + TIME_SET | TIMERR_SET | LATLON_SET | ALTITUDE_SET | + HERR_SET | VERR_SET | TRACK_SET | SPEED_SET | + CLIMB_SET | SPEEDERR_SET | CLIMBERR_SET | MODE_SET + ) + self.utc = fields[1] + self.fix.time = default(1, TIME_SET) + if not isnan(self.fix.time): + self.utc = isotime(self.fix.time) + self.fix.ept = default(2, TIMERR_SET) + self.fix.latitude = default(3, LATLON_SET) + self.fix.longitude = default(4) + self.fix.altitude = default(5, ALTITUDE_SET) + self.fix.epx = self.epy = default(6, HERR_SET) + self.fix.epv = default(7, VERR_SET) + self.fix.track = default(8, TRACK_SET) + self.fix.speed = default(9, SPEED_SET) + self.fix.climb = default(10, CLIMB_SET) + self.fix.epd = default(11) + self.fix.eps = default(12, SPEEDERR_SET) + self.fix.epc = default(13, CLIMBERR_SET) + if len(fields) > 14: + self.fix.mode = default(14, MODE_SET, int) + else: + if self.valid & ALTITUDE_SET: + self.fix.mode = MODE_2D + else: + self.fix.mode = MODE_3D + self.valid |= MODE_SET + elif cmd == 'X': + self.online = float(data) + self.valid |= ONLINE_SET + elif cmd == 'Y': + satellites = data.split(":") + prefix = satellites.pop(0).split() + d1 = int(prefix.pop()) + newsats = [] + for i in range(d1): + newsats.append(gps.satellite(*map(int, satellites[i].split()))) + self.satellites = newsats + self.valid |= SATELLITE_SET + + def __oldstyle_shim(self): + # The rest is backwards compatibility for the old interface + def default(k, dflt, vbit=0): + if k not in self.data.keys(): + return dflt + else: + self.valid |= vbit + return self.data[k] + if self.data.get("class") == "VERSION": + self.version = self.data + elif self.data.get("class") == "DEVICE": + self.valid = ONLINE_SET | DEVICE_SET + self.path = self.data["path"] + self.activated = default("activated", None) + driver = default("driver", None, DEVICEID_SET) + subtype = default("subtype", None, DEVICEID_SET) + self.gps_id = driver + if subtype: + self.gps_id += " " + subtype + self.driver_mode = default("native", 0) + self.baudrate = default("bps", 0) + self.serialmode = default("serialmode", "8N1") + self.cycle = default("cycle", NaN) + self.mincycle = default("mincycle", NaN) + elif self.data.get("class") == "TPV": + self.valid = ONLINE_SET + self.fix.time = default("time", NaN, TIME_SET) + self.fix.ept = default("ept", NaN, TIMERR_SET) + self.fix.latitude = default("lat", NaN, LATLON_SET) + self.fix.longitude = default("lon", NaN) + self.fix.altitude = default("alt", NaN, ALTITUDE_SET) + self.fix.epx = default("epx", NaN, HERR_SET) + self.fix.epy = default("epy", NaN, HERR_SET) + self.fix.epv = default("epv", NaN, VERR_SET) + self.fix.track = default("track", NaN, TRACK_SET) + self.fix.speed = default("speed", NaN, SPEED_SET) + self.fix.climb = default("climb", NaN, CLIMB_SET) + self.fix.epd = default("epd", NaN) + self.fix.eps = default("eps", NaN, SPEEDERR_SET) + self.fix.epc = default("epc", NaN, CLIMBERR_SET) + self.fix.mode = default("mode", 0, MODE_SET) + elif self.data.get("class") == "SKY": + for attrp in "xyvhpg": + setattr(self, attrp+"dop", default(attrp+"dop", NaN, DOP_SET)) + if "satellites" in self.data.keys(): + self.satellites = [] + for sat in self.data['satellites']: + self.satellites.append(gps.satellite(PRN=sat['PRN'], elevation=sat['el'], azimuth=sat['az'], ss=sat['ss'], used=sat['used'])) + self.satellites_used = 0 + for sat in self.satellites: + if sat.used: + self.satellites_used += 1 + self.valid = ONLINE_SET | SATELLITE_SET + elif self.data.get("class") == "TIMING": + self.data["c_recv"] = self.received + self.data["c_decode"] = time.time() + self.timings = self.data + + def poll(self): + "Read and interpret data from the daemon." + status = gpscommon.read(self) + if status <= 0: + return status + if self.raw_hook: + self.raw_hook(self.response); + if self.response.startswith("{") and self.response.endswith("}\r\n"): + self.json_unpack(self.response) + self.__oldstyle_shim() + self.newstyle = True + self.valid |= PACKET_SET + elif self.response.startswith("GPSD"): + self.__oldstyle_unpack(self.response) + self.valid |= PACKET_SET + return 0 + + def next(self): + if self.poll() == -1: + raise StopIteration + if hasattr(self, "data"): + return self.data + else: + return self.response + + def stream(self, flags=0, outfile=None): + "Ask gpsd to stream reports at your client." + if (flags & (WATCH_JSON|WATCH_OLDSTYLE|WATCH_NMEA|WATCH_RAW)) == 0: + # If we're looking at a daemon that speaks JSON, this + # should have been set when we saw the initial VERSION + # response. Note, however, that this requires at + # least one poll() before stream() is called + if self.newstyle or flags & WATCH_NEWSTYLE: + flags |= WATCH_JSON + else: + flags |= WATCH_OLDSTYLE + if flags & WATCH_OLDSTYLE: + if flags & WATCH_DISABLE: + arg = "w-" + if flags & WATCH_NMEA: + arg += 'r-' + return self.send(arg) + else: # flags & WATCH_ENABLE: + arg = 'w+' + if self.raw_hook or (flags & WATCH_NMEA): + arg += 'r+' + return self.send(arg) + else: # flags & WATCH_NEWSTYLE: + gpsjson.stream(self, flags) + +if __name__ == '__main__': + import readline, getopt, sys + (options, arguments) = getopt.getopt(sys.argv[1:], "v") + streaming = False + verbose = False + for (switch, val) in options: + if switch == '-v': + verbose = True + if len(arguments) > 2: + print 'Usage: gps.py [-v] [host [port]]' + sys.exit(1) + + opts = { "verbose" : verbose } + if len(arguments) > 0: + opts["host"] = arguments[0] + if len(arguments) > 1: + opts["port"] = arguments[1] + + session = gps(**opts) + session.set_raw_hook(lambda s: sys.stdout.write(s.strip() + "\n")) + session.stream(WATCH_ENABLE|WATCH_NEWSTYLE) + for report in session: + print report + +# gps.py ends here diff --git a/gps/misc.py b/gps/misc.py new file mode 100644 index 0000000..021874d --- /dev/null +++ b/gps/misc.py @@ -0,0 +1,101 @@ +# misc.py - miscellaneous geodesy and time functions +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. + +import time, calendar, math + +# some multipliers for interpreting GPS output +METERS_TO_FEET = 3.2808399 # Meters to U.S./British feet +METERS_TO_MILES = 0.00062137119 # Meters to miles +KNOTS_TO_MPH = 1.1507794 # Knots to miles per hour +KNOTS_TO_KPH = 1.852 # Knots to kilometers per hour +KNOTS_TO_MPS = 0.51444444 # Knots to meters per second +MPS_TO_KPH = 3.6 # Meters per second to klicks/hr +MPS_TO_MPH = 2.2369363 # Meters/second to miles per hour +MPS_TO_KNOTS = 1.9438445 # Meters per second to knots + +# EarthDistance code swiped from Kismet and corrected + +def Deg2Rad(x): + "Degrees to radians." + return x * (math.pi/180) + +def Rad2Deg(x): + "Radians to degress." + return x * (180/math.pi) + +def CalcRad(lat): + "Radius of curvature in meters at specified latitude." + a = 6378.137 + e2 = 0.081082 * 0.081082 + # the radius of curvature of an ellipsoidal Earth in the plane of a + # meridian of latitude is given by + # + # R' = a * (1 - e^2) / (1 - e^2 * (sin(lat))^2)^(3/2) + # + # where a is the equatorial radius, + # b is the polar radius, and + # e is the eccentricity of the ellipsoid = sqrt(1 - b^2/a^2) + # + # a = 6378 km (3963 mi) Equatorial radius (surface to center distance) + # b = 6356.752 km (3950 mi) Polar radius (surface to center distance) + # e = 0.081082 Eccentricity + sc = math.sin(Deg2Rad(lat)) + x = a * (1.0 - e2) + z = 1.0 - e2 * sc * sc + y = pow(z, 1.5) + r = x / y + + r = r * 1000.0 # Convert to meters + return r + +def EarthDistance((lat1, lon1), (lat2, lon2)): + "Distance in meters between two points specified in degrees." + x1 = CalcRad(lat1) * math.cos(Deg2Rad(lon1)) * math.sin(Deg2Rad(90-lat1)) + x2 = CalcRad(lat2) * math.cos(Deg2Rad(lon2)) * math.sin(Deg2Rad(90-lat2)) + y1 = CalcRad(lat1) * math.sin(Deg2Rad(lon1)) * math.sin(Deg2Rad(90-lat1)) + y2 = CalcRad(lat2) * math.sin(Deg2Rad(lon2)) * math.sin(Deg2Rad(90-lat2)) + z1 = CalcRad(lat1) * math.cos(Deg2Rad(90-lat1)) + z2 = CalcRad(lat2) * math.cos(Deg2Rad(90-lat2)) + a = (x1*x2 + y1*y2 + z1*z2)/pow(CalcRad((lat1+lat2)/2), 2) + # a should be in [1, -1] but can sometimes fall outside it by + # a very small amount due to rounding errors in the preceding + # calculations (this is prone to happen when the argument points + # are very close together). Thus we constrain it here. + if abs(a) > 1: a = 1 + elif a < -1: a = -1 + return CalcRad((lat1+lat2) / 2) * math.acos(a) + +def MeterOffset((lat1, lon1), (lat2, lon2)): + "Return offset in meters of second arg from first." + dx = EarthDistance((lat1, lon1), (lat1, lon2)) + dy = EarthDistance((lat1, lon1), (lat2, lon1)) + if lat1 < lat2: dy *= -1 + if lon1 < lon2: dx *= -1 + return (dx, dy) + +def isotime(s): + "Convert timestamps in ISO8661 format to and from Unix time." + if type(s) == type(1): + return time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(s)) + elif type(s) == type(1.0): + date = int(s) + msec = s - date + date = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(s)) + return date + "." + `msec`[2:] + elif type(s) == type(""): + if s[-1] == "Z": + s = s[:-1] + if "." in s: + (date, msec) = s.split(".") + else: + date = s + msec = "0" + # Note: no leap-second correction! + return calendar.timegm(time.strptime(date, "%Y-%m-%dT%H:%M:%S")) + float("0." + msec) + else: + raise TypeError + +# End + diff --git a/gps_json.h b/gps_json.h new file mode 100644 index 0000000..8202a7d --- /dev/null +++ b/gps_json.h @@ -0,0 +1,43 @@ +/* gps_json.h - JSON handling for libgps and gpsd + * + * By Eric S. Raymond, 2009 + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#include "json.h" + +#define GPS_JSON_COMMAND_MAX 80 +#define GPS_JSON_RESPONSE_MAX 1536 + +#ifdef __cplusplus +extern "C" { +#endif +char *json_stringify(/*@out@*/char *, size_t, /*@in@*/const char *); +void json_tpv_dump(const struct gps_data_t *, /*@out@*/char *, size_t); +void json_sky_dump(const struct gps_data_t *, /*@out@*/char *, size_t); +void json_att_dump(const struct gps_data_t *, /*@out@*/char *, size_t); +void json_device_dump(const struct gps_device_t *, /*@out@*/char *, size_t); +void json_watch_dump(const struct policy_t *, /*@out@*/char *, size_t); +int json_watch_read(const char *, /*@out@*/struct policy_t *, + /*@null@*/const char **); +int json_device_read(const char *, /*@out@*/struct devconfig_t *, + /*@null@*/const char **); +void json_version_dump(/*@out@*/char *, size_t); +int json_rtcm2_read(const char *, char *, size_t, struct rtcm2_t *, + /*@null@*/const char **); +int json_ais_read(const char *, char *, size_t, struct ais_t *, + /*@null@*/const char **); +int libgps_json_unpack(const char *, struct gps_data_t *, + /*@null@*/const char **); +#ifdef __cplusplus +} +#endif + +/* these values don't matter in themselves, they just have to be out-of-band */ +#define DEVDEFAULT_BPS 0 +#define DEVDEFAULT_PARITY 'X' +#define DEVDEFAULT_STOPBITS 3 +#define DEVDEFAULT_NATIVE -1 + +/* gps_json.h ends here */ diff --git a/gpscap.ini b/gpscap.ini new file mode 100644 index 0000000..60939e6 --- /dev/null +++ b/gpscap.ini @@ -0,0 +1,2031 @@ +# GPS capability description file +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# Our apologies to all Unix hackers in advance for the grubby .INI syntax, +# we're using it because the format has good cross-Unix support in Python. +# +# Each section may have the following capabilities +# +# type = "engine", "vendor", or "device" +# date = date of submission +# submitter = email of submitter, name may need quoting for RFC822 +# description = Human-readable description of this item +# packaging = A device's form factor +# techdoc = URL to technical documentation, or at least a spec sheet +# vendor_site = URL of a vendor site +# vendor = vendor name +# eval_unit = Which GPSD devs have one for testing (list) +# engine = GPS chipset (may reference another section) +# subtype = engine subtype or firmware revision level +# interfaces = interface types: USB, RS232, Bluetooth, CF, TTL. May be a list. +# usbchip = USB I/O chipset +# pps = supports pulse-per-second precision time reporting +# noconfigure = can be bricked by baud-rate changes (requires -b option) +# tested = last gpsd tested, or "regression" if we have a test load +# nmea = NMEA version this emits, if known +# notes = Miscellaneous notes on this item. To be interpreted as HTML. +# rating = excellent, good, fair, poor, broken, other +# discontinued = If present, product has been discontinued +# +# Capability strings: +# +# to_nmea = if present, how to switch to NMEA 0183 mode from native binary +# to_native = if present, how to swith to native binary mode from NMEA +# modeset = set protocol, baud rate, 8N1 +# +# Inheritance +# +# To inherit capabilities from a specified section, name the section in +# a "uses =" attribute. Use chains are followed recursively. An attribute +# in a section overrides all attributes of the same name in all ancestor +# sections. +# +# Certain escapes in capability strings are translated: +# +# %b - baud rate as ASCII numeral +# +# A string beginning with 0x is interpreted as a sequence of paired hex bytes, +# leading 0x not included. +# +# Comment lines led with "#%" are vendor section marks to be used when +# generating an HTML table from this file. Each should consist of a vendor +# name. +# +# Further notes: +# * In the packaging feld, a "GPS mouse" is a standalone sensor in a +# display-less case designed be used as an outbard peripheral. An +# "OEM module" is an un-cased circuit board with edge connectors; a +# "chipset" is what it sounds like. +# A "handset" is a standalone GPS with a display and human-usable +# controls. A "handsfree" is a hands-free unit with display designed for +# mounting on a car windshield or boat dash. +# * In the rating field: +# "excellent" - gpsd recognizes the GPS rapidly and reliably, +# reports are complete and correct. +# "good" -- gpsd has minor problems or lag recognizing the device, +# but reports are complete and correct. +# "fair" -- Reports have minor dropouts or problems, including occasional +# transient nonsense values. +# "poor" -- Reports frequently have values that are wrong or nonsense. +# "broken" -- gpsd frequently fails to recognize the device at all. +# "other -- See Technical Notes. + +# +# Chipsets +# + +[GenericSiRF] +type = engine +description = Capabilities generic to all SiRF chips +# Sets 4800 baud shipping GGA+GSA+GSV+RMC +to_nmea = 0xa0a200188102010100000101050101010000000100010001000112c00000b0b3 +to_native = $PSRF100,0,%b,8,1,0 # Sets 8N1 with specified speed + +[SiRF-1] +type = engine +description = Version 1 of the SiRF GPS engine +engine = SiRF-1 +nmea = 2.2 +uses = GenericSiRF +tested = 2.34 +rating = good +logs = uBlox-sirf1.log +notes = uBlox-sirf1.log was made from a device with uBlox firmware and + may not be typical of SirF-1 chips. + +[SiRF-2] +type = engine +description = Version 2 of the SiRF GPS engine +engine = SiRF-2 +# Later versions may do 2.3 +nmea = 2.2 +uses = GenericSiRF +tested = 2.37 +rating = good +logs = bu303b-nofix.log, bu303-climbing.log, bu303-moving.log, + bu303-nofix.log, bu303-stillfix.log, haicom-305N.log, holux-gm-210.log, + pharos-360.log, tn200-all.log, tn200.log, tn204.log +notes = The bu* logs are in native binary format; the Haicom, Holux, Pharos, + and TripNav logs in NMEA. NMEA starts with GGA and ends with RMC. The + tn204 NMEA looks remarkably like older Garmin cruft and may be emulating + one, including the split reporting cycle. + +[SiRF-3] +type = engine +description = Version 3 of the SiRF GPS engine +engine = SiRF-3 +nmea = 3.01 +uses = GenericSiRF +rating = good +logs = blumax-gps009.log, gpslim236.log, motorola-t805.log, rgm3800.log, et-332.log, tomtom-mkII.log +notes = The Blumax log is in NMEA mode. Start of cycle is GGA, End of cycle + is RMC. Some variants (like the Blumax) emit ZDA before GGA; others + (like the GPSlim 1236, Motorola T805, RGM3800) do not. + +[MSB2122] +type = engine +engine = MSB2122 +nmea = 2.3 +rating = good +techdoc = http://www.mstar-europe.com/products.php +notes = Code-named "Poseidon 2", this appears to be a MIPS core. May + ship with serious bugs that cause bogus fixes or hard crashes. + +[ANTARIS] +type = engine +engine = ANTARIS +nmea = 2.3 +rating = good +techdoc = http://www.u-blox.com/products/tim_lp.html +discontinued = True +notes = The ANTARIS chipset has been end-of-lifed. + +[ANTARIS4] +type = engine +engine = ANTARIS4 +techdoc = http://www.u-blox.com/products/a4products.html +nmea = 2.3 +rating = good +notes = Sends 'E' in second field of GSA record, not an NMEA value. + Actually sends '6' in the GGA rating record for dead-reckoning fixes. + (This behavior reported on the 4H chipset.) +logs = uBlox-lea-4h.log, uBlox-lea-4s.log, uBlox-lea-4t.log + +[FastraX iTrax03] +type = engine +techdoc = http://www.fastraxgps.com/products/gpsmodules/index.cfm?template=products.show.cfm&productGuid=4594da1a-503c-469c-91b2-6948043189be +engine = FastraX iTrax03 +rating = good +logs = com-1289.log +notes = Start of fix cycle is RMC, end is GGA (GSVs may come after). + +[Garmin] +type = engine +engine = Garmin +description = There are several versions; the differences are not clear. +techdoc = http://www.garmin.com/support/commProtocol.html +rating = good + +[MTK] +type = engine +nmea = 3.01 +engine = MTK +rating = good + +[Nemerix] +type = engine +engine = Nemerix +nmea = 3.01 +rating = good +notes = NemeriX has gone into liquidation as of Jan 2009). It's funny, they + didn't understand why they should give me an unencumbered protocol + techdoc. + +[NovAtel-L1] +type = engine +engine = NovAtel-L1 +techdoc = http://www.novatel.com/Documents/Manuals/om-20000086.pdf +nmea = 2.20 +rating = good +notes = Seems to be built around the Zarlink GP4020. + +[Sony CXD2951] +type = engine +techdoc = http://gpsd.berlios.de/vendor-docs/cxd2951-commands.pdf +engine = Sony CXD2951 +rating = good + +[Touchstone ASIC] +type = engine +engine = Touchstone ASIC +rating = good +techdoc = http://www.navcomtech.com/Products/GPS/Touchstone.cfm + +[uNav] +type = engine +engine = uN3010 +nmea = 3.01 +notes = uNav was acquired by Atheros in 2007. They have inherited + one GPS product, now designated uN3010. +rating = good + +[Zodiac] +type = engine +engine = Zodiac +nmea = 2.2 +tested = 2.0 +techdoc = http://www.gpskit.nl/downloads-en.htm +notes = This chip was made by Rockwell International. It was + also known as the Jupiter. It has been EOLed. +rating = good +logs = zodiac.log + +[BD960] +type = engine +engine = BD960 +nmea = 3.0? +tested = 2.39 +notes = Spec sheet says it emits GSV, AVR, RMC, HDT, VGK, VHD, GGLK, GGA, GSA, + ZDA, VTG, GST, and PIT in NMEA mode. Many of these are nonstandard. + Also says: "JK and Binary: Trimble GSOF". Other web sources say + it has RTK capability. +rating = good + +[Skytraq Venus 6] +type = engine +nmea = 3.01 +rating = good +tested = 2.90 + +[UBLOX NEO-5Q] +type = engine +nmea = 2.3 +rating = good +tested = 2.39 +notes = Supports WAAS. + +# +# Vendors (alphabetical by vendor) +# + +[Altina] +type = vendor +vendor_site = http://www.altina.com + +[Adapt Mobile] +type = vendor +vendor_site = http://www.adapt-mobile.com> + +[Axiom] +type = vendor +vendor_site = http://gpsd.berlios.de/vendor-docs/axiom + +[Billionton] +type = vendor +vendor_site = http://www.billionton.com/english/index.htm + +[Bluenext] +type = vendor +vendor_site = http://www.bluenext.co.uk/ + +[Canmore] +type = vendor +vendor_site = http://www.canmore.com.tw/ + +[Columbus] +type = vendor +vendor_site = http://www.columbus-gps.de/ + +[Central Pacific] +type = vendor +vendor_site = http://www.cpit.com + +[Delorme] +type = vendor +vendor_site = http://www.delorme.com + +[Digital Yacht] +type = vendor +vendor_site = http://digitalyacht.mesltd.co.uk/ + +[Eurotech] +type = vendor +vendor_site = http://www.eurotech-inc.com/ + +[EuroTronics] +type = vendor +vendor_site = http://www.eurotronic.net/ + +[Garmin] +type = vendor +vendor_site = http://www.garmin.com + +[Geostar] +type = vendor +vendor_site = http://www.geostar-navigation.com + +[GlobalSat] +type = vendor +vendor_site = http://www.globalsat.com.tw/english/products.php + +[Haicom] +type = vendor +vendor_site = http://www.haicom.com.tw/ + +[Holux] +type = vendor +vendor_site = http://www.holux.com + +[Humminbird] +type = vendor +vendor_site = http://www.humminbird.com/ +notes = These guys make fish-finders that incorporate GPSes + +[iTrek] +type = vendor +vendor_site = http://www.i-trek.jp + +[Jackson Labs] +type = vendor +vendor_site = http://jackson-labs.com/ + +[Magellan] +type = vendor +vendor_site = http://www.magellangps.com +notes = Now owns what used to be the Thales and Asht product lines + +[Motorola] +type = vendor +vendor_site = http://www.motorola.com/ies/GPS/products_legacy.html +notes = Motorola has exited the GPS business + +[Navcom] +type = vendor +vendor_site = http://www.navcomtech.com/ + +[Navis Engineering Bureau] +type = vendor +vendor_site = http://www.navis.ru/ + +[Navius] +type = vendor +vendor_site = http://www.navius.biz/ +notes = This vendor has also traded as "Navisky". + +[NaviLock] +type = vendor +vendor_site = http://www.navilock.de + +[Navisys] +type = vendor +vendor_site = http://www.navisys.com.tw/ + +[NavMan] +type = vendor +vendor_site = http://www.navmanwirelessoem.com/ + +[Nokia] +type = vendor +vendor_site = http://www.nokia.com/ + +[NovAtel] +type = vendor +vendor_site = http://www.novatel.com/ + +[Parrot] +type = vendor +vendor_site = http://www.parrot.biz + +[Pharos] +type = vendor +vendor_site = http://www.pharosgps.co/ + +[Phonix] +type=vendor +vendor_site = http://www.phonix.it/ + +[Qstarz] +type=vendor +vendor_site = http://www.qstarz.com/ + +[Rikaline] +type = vendor +vendor_site = http://www.rikaline.com + +[Royaltek] +type = vendor +vendor_site = http://www.royaltek.com/ + +[San Jose Navigation] +type = vendor +vendor_site = http://www.sanav.com + +[SkyTraq] +type = vendor +vendor_site = http://www.skytraq.tw/ + +[Transystem] +type = vendor +vendor_site = http://www.transystem.com.tw/ + +[Techway] +type = vendor +vendor_site = http://www.techwayinc.com.tw/ +notes = This vendor has drooped off the web + +[TomTom] +type = vendor +vendor_site = http://www.tomtom.com + +[Trimble] +type = vendor +vendor_site = http://www.trimble.com/ + +[uBlox] +type = vendor +vendor_site = http://www.u-blox.de/ + +[UniTraq] +type = vendor +vendor_site = http://www.unitraq.com/ + +[Variotek] +type = vendor +vendor_site = http://variotek.de/ + +[Wintec] +type = vendor +vendor_site = http://www.wintec.com.tw/ + +# +# Devices (alphabetical by vendor) +# + +#% Altina + +[GBT709] +type = device +vendor = Altina +packaging = handset +techdoc = http://www.altina.com/produkty.php?destCatId=&mainCatId=13&subCatId=&prId=19 +interfaces = Bluetooth +noconfigure = True +tested = 2.35 +uses = SiRF-3 +submitter = Benoit Panizzon +notes = Requires the "-b" flag to prevent mode switching. If the receiver locks + up due to a mode switch, remove the battery for 5 to 10 minutes. + +#% Adapt Mobile + +[AD-500] +type = device +vendor = Adapt Mobile +packaging = mouse +techdoc = http://adapt-mobile.bosqom.com/default.php?page_ID=3&spage_ID=1 +uses = Nemerix +interfaces = Bluetooth, USB +iochip = pl2303 +tested = 2.32 +submitter = Dennis van Zuijlekom . + +#% Axiom + +[Sandpiper] +type = device +vendor = Axiom +packaging = OEM module +techdoc = http://gpsd.berlios.de/vendor-docs/axiom +uses = SiRF-1 +interfaces = RS232C +tested = 2.34 +pps = True +notes = The vendor is out of business, but there are lots of these still + around in 2006. Complete documentation for this OEM module has been + archived at the GPSD site. + +#% Billionton + +[Billionton CF-GPS] +type = device +vendor = Billionton +packaging = mouse +techdoc = http://www.billionton.com/english/product/CF-GPS.htm +uses = SiRF-2 +interfaces = CF +tested = 2.16 +submitter = Oleg Gusev . +notes = Uses SiRF firmware version 220.006.000ES. Accepts WAAS Mode Disable + ($PSRF108,00*02) and WAAS Mode Enable ($PSRF108,01*03) + controls. + +#%Bluenext + +[BN-901S] +type = device +engine = Skytraq Venus 6 +date = 12 June 2010 +location = +model = BN-901S +packaging = mouse +interfaces = Bluetooth +rating = excellent +submitter = Andrew Gray +techdoc =http://www.bluenext.co.uk/customer-support/downloads/doc_download/34-bluenext-bn-901s-gps-receiver.html +tested = 2.39 +vendor = Bluenext +notes = Device reports protocol as "Generic NMEA" without a version number. + Purchased retail (30GBP) to work with a Nokia 5233 - which is does well. + Best performing GPS receiver I've seen - fast fix and robust against + obstructions to sky view. +logs = bn-9015.log + +#% Canmore + +[GT-730F] +type = device +engine = SKYTRAK +interfaces = USB +nmea = 3.01 +packaging = mouse +rating = good +submitter = Rene Warren +techdoc = http://www.canmore.com.tw/pdf/English%20user%20manual_GT-730F_L.pdf +tested = 2.33 +vendor = Canmore +notes = + +#% Columbus +[V900] +type = device +uses = MTK +interfaces = Bluetooth +model = V900 +nmea = 3.01 +packaging = mouse +rating = fair +submitter = Konstantin Ristl +techdoc = http://www.columbus-gps.de/v-900_support.php +tested = 2.38 +vendor = Columbus +notes = Device is also a GPS-Logger + +#% Central Pacific + +[CPIT GP-27] +type = device +vendor = Central Pacific +packaging = mouse +techdoc = http://www.cpit.com/en/GP-27.html +uses = Nemerix +interfaces = Bluetooth +tested = 2.28 +noconfigure = True +submitter = Tobias Minich +notes =

    +
  • There are proprietary PNMRX{30[0124],603} sentences that are only sent + on change or by request
  • +
  • Several sentences can be sent to the device to change settings or + request information. DO NOT USE THE PNMRX100 SENTENCE TO CHANGE THE BAUD + RATE! This is not supported by the bluetooth chip on the device.
  • +
  • Settings are saved in flash powered by a backup battery and persistent + over connections and when you turn it off.
  • +
  • The syntax of the PNMRX303 message and part 4 of the PNMRX603 message + may differ from the syntax found in several documents on the net.
  • +
+ +#% Delorme + +[EarthMate USB] +type = device +vendor = Delorme +packaging = mouse +techdoc = http://www.delorme.com/earthmate/default.asp +uses = SiRF-2 +interfaces = USB +usbchip = Cypress M8 CY7C64013 +tested = 2.5 +notes = This was the replacement for the old Zodiac version that spoke + Rockwell binary protocol; it in turn has been discontinued. Some + other sentences can be enabled. Requires a 2.6.10 or better + kernel for the Cypress USB-HID support. + +[EarthMate] +type = device +vendor = Delorme +packaging = mouse +uses = Zodiac +interfaces = RS232C +notes = These models have been discontinued. + +[TripMate] +type = device +vendor = Delorme +packaging = mouse +techdoc = http://vancouver-webpages.com/peter/tripmate.faq +uses = Zodiac +interfaces = RS232C +discontinued = True +notes = Discontinued sometime before November 1998. + +#% Digital Yacht + +[AIT250] +type = device +vendor = Digital Yacht +engine = unknown +packaging = handsfree +techdoc = http://www.yachtronics.com/yachtronics/manuals/DIGITAL%20YACHT%20AIT250%20OPERATION.pdf +interfaces = RS232C +discontinued = False +tested = regression +rating = good +submitter = Jan Veninga +notes = Both a Class B AIS transceiver and a GPS. +logs = ait250.log + +#% Eurotech + +[Com-1289] +type = device +vendor = Eurotech +packaging = OEM module +techdoc = http://www.eurotech.fi/products/COM-1289.html +engine = FastraX iTrax03 +interfaces = RS232 +tested = regression +rating = good +submitter = Simon Le Pape +notes = + +#% EuroTronics + +[Blumax GPS009] +type = device +vendor = EuroTronics +packaging = mouse +techdoc = http://www.eurotronic.net/products/produktdetails/gps_receiver.html +uses = SiRF-3 +interfaces = Bluetooth +noconfigure = True +tested = regression +submitter = Hartmut Holzgraefe +notes = Requires "-b" ... I had to totally drain the battery of the device + and let it rest for a few days before i was able to use it again + after a first attempt of using it with without "-b" + +#% Garmin + +[Garmin GPS-15] +type = device +packaging = OEM module +vendor = Garmin +techdoc = http://www.garmin.com/products/gps15/spec.html +uses = Garmin +interfaces = RS232 +tested = 2.33 +nmea = 2.0 +pps = True +submitter = Jason Hecker +notes = "$PGRMI,,,,,,,R" must be sent to reset the device before PPS + works; after about 5 minutes the PPS signal is detected properly + by GPSD. + +[Garmin GPS-16] +type = device +packaging = mouse +vendor = Garmin +techdoc = http://www.garmin.com/products/gps16/spec.html +uses = Garmin +interfaces = RS232 +tested = 2.38 +nmea = 2.0 +submitter = Reported by Ron Marosko, Jr. , + Amaury Jacquot , + Jeff Francis +notes = DGPS information in GPGGA sentence is not returned. Satellite + azimuths/elevations and magnetic variation information are not + available in binary mode. Garmin uses a nonstandard 16-bit SNR + scale for signal quality in GSA. Can be switched to NMEA 3.0 + with PGRMC1. . + +[Garmin GPS-17N] +type = device +packaging = mouse +vendor = Garmin +techdoc = http://www.garmin.com/products/gps17/spec.html +uses = Garmin +interfaces = RS232 +tested = regression +nmea = 2.0 or 3.0 +submitter = Wojciech Kazubski . +notes = The 17N has been discontinued and replaced by the 17HVS. + The interface was RS232 but used a custom RJ-45 jack. +logs = garmin17n.log + +[Garmin GPS-17HVS] +type = device +vendor = Garmin +packaging = mouse +techdoc = https://buy.garmin.com/shop/shop.do?cID=158&pID=8630 +engine = unknown +interfaces = RS232 +tested = 2.37 +rating = good +nmea = 2.0 or 3.0 +notes = Reported by Ulrich Voigt (no email address) + +[Garmin GPS-18 USB] +interfaces = USB +nmea = N/A +packaging = mouse +submitter = Gary E. Miller +techdoc = http://www.garmin.com/manuals/GPS18_TechnicalSpecification.pdf +tested = 2.38 +type = device +uses = Garmin +vendor = Garmin +notes = The USB version requires the Linux kernel garmin_usb driver. + usbfs is not required after gpsd version 2.39. + DOP (Dilution of Precision) information is not available (Garmin protocol + includes EPE only); gpsd uses EPE to approximate DOP. Magnetic variation + information is not available. Garmin uses a nonstandard 16-bit SNR scale. + The 18 series, unlike the 16, reports skyview via a packet 114. They will + not operate indoors and require a good sky view. + +[Garmin GPS-18 (all but USB)] +interfaces = RS232 +nmea = 2.0 and 2.3 +packaging = mouse +pps = True +submitter = Gary E. Miller +techdoc = http://www.garmin.com/manuals/GPS18_TechnicalSpecification.pdf +tested = 2.5 +type = device +uses = Garmin +vendor = Garmin +notes = The RS232 versions can emit NMEA and are found by normal autoconfiguration. + GPS-18 LVC and GPS-18 LVC/5m have PPS outputs. WAAS is supported. + The 18 series, unlike the 16, reports skyview via a packet 114. They will + not operate indoors and require a good sky view. + +[GPS-25LP] +type = device +packaging = OEM module +vendor = Garmin +techdoc = http://www8.garmin.com/products/gps25/spec.html +uses = Garmin +interfaces = RS232 +nmea = 2.0 +tested = regression +discontinued = True +submitter = Daniele Giangrazi +notes = Discontinued embedded module. +logs = garmin25lp.log + +[Garmin 38] +type = device +vendor = Garmin +packaging = handset +techdoc = http://au.geocities.com/glennbaddeley/gps/data/GPS38_OwnersManualAndTechdoc_June1997_RevB.pdf +uses = Garmin +interfaces = RS232 +rating = excellent +tested = regression +nmea = 2.0 +discontinued = True +submitter = Pascal F. Martin +notes = Start-of-cycle is RMC. 2-second cycle time, 1 fix per cycle. +logs = garmin38.log + +[Garmin 48] +type = device +vendor = Garmin +packaging = handset +techdoc = https://buy.garmin.com/shop/shop.do?pID=85 +uses = Garmin +interfaces = RS232 +nmea = 2.0 +discontinued = True +rating = excellent +tested = regression +notes = Start-of-cycle is RMC. 2-second cycle time, 2 fixes per cycle, GLL + reports second fix. The 48 has been discontinued. The Garmin + 12XL and 45 are nearly identical and should work as well. + Details on the Garmin proprietary protocol can be found at here. + +[Garmin GPS 60] +type = device +vendor = Garmin +packaging = handset +techdoc = http://www.garmin.com/manuals/GPS60_OwnersManual.pdf +uses = Garmin +interfaces = USB, RS232 +tested = 2.33 +nmea = 3.01 +submitter = Diego Berge + +[Garmin GPS 76] +type = device +vendor = Garmin +packaging = handset +techdoc = http://www.garmin.com/manuals/GPS76_OwnersManual.pdf +uses = Garmin +interfaces = RS232 +tested = 2.39 +nmea = 2.3 +submitter = Sebastian Niehaus , + Geoff Childs +notes = The device has a four pin socket described by Garmin as a serial + interface. Connection to a standard 9 pin RS-232 computer socket + is made using the special adaptor lead supplied by Garmin. Sebastian + Niehaus says it annunces "Software Version 3.70". Geoff Childs adds: + "The Garmin GPS 76 comms MUST be set to 'NMEA'. The kernel module + garmin_gps is not needed and should not be specially loaded." + +[Geko 201] +type = device +vendor = Garmin +packaging = handset +techdoc = http://www.garmin.com/manuals/Geko201_OwnersManual.pdf +uses = Garmin +interfaces = RS232 +tested = regression +nmea = 3.0 +submitter = Jose Luis Domingo Lopez +notes = +logs = garmin-geko201.log + +[eTrex Vista] +type = device +vendor = Garmin +packaging = handset +techdoc = http://www.garmin.com/manuals/eTrexVista_OwnersManual.pdf +uses = Garmin +interfaces = RS232 +tested = 2.32 +nmea = 3.0 +submitter = Reed Hedges +notes = + +[Nuvi 650] +type = device +vendor = Garmin +packaging = handsfree +techdoc = http://www.garmin.com/manuals/nuvi650_OwnersManual.pdf +uses = SiRF-3 +interfaces = USB +tested = * +nmea = 3.0 +rating = broken +notes = This device does not have real-time data output, and is incompatible with GPSD. + +#% Geostar Navigation + +[GeoS-1M] +type = device +date = 09 July 2010 +location = Minsk, Belarus, 53N 27E +model = GeoS-1M +engine = custom +interfaces = TTL +nmea = 3.01 +packaging = OEM module +rating = fair +sample_notes = NMEA output for a few minutes after power up. +submitter = Viktar Palstsiuk +techdoc = http://geostar-navigation.com/fail/manuals/User_Manual_GeoS-1M_en.pdf +tested = 2.90 +vendor = Geostar +notes = GeoS-1M is the combined GPS/GLONASS OEM receiver board. Its + architecture includes 24 tracking channels. Triggers an internal + error from gpsd 2.95dev because with the GLONASS satellites the + number of visible birds can excedd MAXCHANNELS. + +#% GlobalSat + +[BC-307] +type = device +vendor = GlobalSat +packaging = mouse +techdoc = http://www.usglobalsat.com/item.asp?itemid=12 +uses = SiRF-2 +interfaces = CF +tested = 2.35 +nmea = 2.2 +submitter = Chris Kuethe . +notes = Acceptably functional running firmware 231ES. + +[BT-318] +type = device +vendor = GlobalSat +packaging = mouse +techdoc = http://www.globalsat.com.tw/english/products_detail.php?main_id=21&p_id=107 +uses = SiRF-2 +interfaces = Bluetooth +tested = 2.20 +nmea = 2.2 +notes = Reported by Frank Nicholas . + +[BT-338] +type = device +vendor = GlobalSat +packaging = mouse +techdoc = http://www.usglobalsat.com/item.asp?itemid=6 +uses = SiRF-3 +interfaces = Bluetooth +tested = 2.13 +submitter = Michal Panczyk + +[BU-303] +type = device +vendor = GlobalSat +packaging = mouse +techdoc = http://www.usglobalsat.com/item.asp?itemid=11&catid=13 +uses = SiRF-2 +interfaces = USB +usbchip = pl2303 +tested = regression +rating = excellent +eval_unit = esr +nmea = 2.2 +notes = Older versions of the BU-303 had a + design + defect that made it likely to fail if subjected to vibration or + +[BU-353] +type = device +vendor = GlobalSat +packaging = mouse +techdoc = http://www.usglobalsat.com/item.asp?itemid=60&catid=17 +uses = SiRF-3 +interfaces = USB +usbchip = pl2303 +tested = pre-2.29 +nmea = 2.3 +notes = This receiver, or at least the firmware it ships with does not + support PPS timing output, nor does it support WAAS - something + born out by the claimed 10m positioning accuracy. These will + hopefully be fixed in future firmware revisions. The increased + sensitivity is nice, but the lack of WAAS and PPS could be + show-stoppers for various applications. + +[BT-359] +vendor = GlobalSat +uses = SiRF-3 +interfaces = Bluetooth +nmea = 2.2 +packaging = mouse +rating = excellent +submitter = Patrick Forristal +techdoc = http://www.globalsat.com.tw/eng/support_check.php?check_id=126&checkType=Manual +tested = 2.37 + +[BT-451] +type = device +chipset = ANTARIS ATR062x +engine= ANTARIS4 +date = 9 Dec 2009 +location = Lithuania, 55.8N 23.6E +model = BT-451 +packaging = mouse +interfaces = USB +rating = good +submitter = Mindaugas +techdoc = http://www.navilock.de/produkte/gruppen/28/Nicht_mehr_lieferbare_Artikel/60307_BT-451.html?show=spec +tested = 2.39 +vendor = NaviLock +logs = bt451.log + +[ET-332 Engine Board] +type = device +engine = SiRF-3 +firmware = unknown +model = ET-322 Engine Board +interfaces = TTL +notes = This is an OEM module but it is available in small quantities. +logs = et-332.log +packaging = OEM module +rating = good +submitter = Val Schmidt +techdoc =http://www.globalsat.com.tw/products-page.php?menu=2&gs_en_product_id=4&gs_en_product_cnt_id=44&img_id=110&product_cnt_folder=4 +vendor = GlobalSat + +[MR-350P] +date = 3 Feb 2010 +interfaces = RS232 +nmea = 3.01 +packaging = mouse +pps = True +rating = excellent +submitter = Gary E. Miller +techdoc = http://www.usglobalsat.com/p-58-mr-350p-bulkhead.aspx +tested = 2.90 +type = device +uses = SiRF-3 +vendor = GlobalSat +notes = May work inside wood frame buildings. PPS pulse is only 1uS wide, but newer gpsd handles that fine. + Be careful, there is also an MR-350 (no suffix P) that does NOT have PPS. + +[TripNav TN-200] +type = device +vendor = GlobalSat +packaging = mouse +techdoc = http://www.usglobalsat.com/item.asp?itemid=45&catid=13 +uses = SiRF-2 +interfaces = USB +usbchip = FTDI FT232 +tested = regression +rating = excellent +notes = We tested a version with SiRF Firmware level 231ES. The FTDI USB-to-serial + chip is supported only as alpha software not yet + incorporated into the Linux kernel, though it seems to be well + supported by OS X and various BSDs. It seems like the only + difference between this and the BU-303 is the different + USB-to-serial chip. + +[TripNav TN-204] +type = device +vendor = GlobalSat +packaging = mouse +uses = SiRF-2 +interfaces = CF +tested = regression +rating = excellent +submitter = Pascal F. Martin +notes = Sometimes sold under the brand name "Rayming", but that vendor + seems to have disappeared. Chipset said ton be SiRF 2 but the + output looks more like old Garmin GPSes. + +[ND100] +type = device +uses = MSB2122 +interfaces = USB +usbchip = pl2303 +nmea = 3.0 +packaging = mouse +rating = excellent +submitter = Arnaud Le Meur +techdoc = http://www.globalsat.com.tw/eng/product_detail_00000124.htm +tested = 2.38 +vendor = GlobalSat +notes = May ship with broken firmware that incorrectly reports the + current year (2009) as 1953. A firmware update is available + to resolve this issue. + +#% Haicom + +[HI-204S] +type = device +vendor = Haicom +packaging = mouse +techdoc = http://www.haicom.com.tw/products.htm +uses = SiRF-2 +interfaces = USB +usbchip = pl2303 +tested = 2.24 +rating = excellent +eval_unit = esr +nmea = 2.2 +notes = SiRF firmware level 231ES (XTrac). Haicom provided a test unit. Manual + states incorrectly that VTG is off by default. + +[HI-204E] +type = device +vendor = Haicom +packaging = mouse +techdoc = http://www.haicom.com.tw/gps204E.shtml +engine = Evermore BBP1202 +interfaces = USB +tested = 2.6 +rating = excellent +nmea = 2.2 +notes = Probably uses PL2303 but we have not verified this. + +[HI-303S] +type = device +vendor = Haicom +packaging = handsfree +techdoc = http://www.haicom.com.tw/gps303s.shtml +uses = SiRF-3 +interfaces = RS232 +tested = 2.25 +nmea = 2.2 +aubmitter = Denis Perchine +notes = NMEA works, but SiRF binary does not. This device seems to ignore the + $PSRF100 mode switch command. (SiRF binary may be available on the + auxiliary serial port, but this is unconfirmed.) This device ships + This device ships with XTrac Firmware. It has been discontinued. + +[HI-305N] +type = device +vendor = Haicom +packaging = mouse +techdoc = http://www.haicom.com.tw/ +uses = Nemerix +interfaces = CF +tested = regression +discontinued = True +submitter = David Findlay +notes = Adaptors for RS232, USB, and Bluetooth operation are available. + +#% Holux + +[GM-210] +type = device +vendor = Holux +packaging = mouse +techdoc = http://www.amazon.com/Holux-GM-210-Receiver-Laptop-Pocket/dp/B0006ZMBTW +uses = SiRF-2 +interfaces = RS232 +tested = regression +nmea = 2.2 +discontinued = True +submitter = Patrick L. McGillan . + + +[GR-230] +type = device +vendor = Holux +packaging = mouse +techdoc = http://www.holux.com.tw/Temp%20web/GR-230.html +uses = SiRF-2 +interfaces = Bluetooth +noconfigure = True +tested = 2.19 +nmea = 2.2 +discontinued = True +notes = 4 color LED showing: Bluetooth, Navigation Update and Battery + and Charger Rating Indication. FLASH based program + memory. Firmware upgradeable through serial interface. Water + resistant. + +[GPSlim 236] +type = device +vendor = Holux +packaging = mouse +techdoc = http://en.holux.com.cn/product/search.htm?filename=gpsreceiver_bluetooth_gpslim2+36.htm&target=bluetooth00&level=grandsonson +uses = SiRF-3 +interfaces = Bluetooth +tested = regression +rating = poor +nmea = 2.2 +submitter = Kévin Redon +notes = Does not report altitude reliably. + Optional interfaces: + mini-USB -> USB, needing a special cable : GR230-A2 (USB data cable), + otherwise it will not work; + mini-USB -> RS232, need cable GR230-A1(RS232 data cable), I didn't + try it with a normal cable; + mini-USB -> PS2, need cable GR230-A3 (Mini USB port to PS2 port ), I + didn't try it with a normal cable. + +[Holux GR-239] +type = device +vendor = Holux +packaging = mouse +techdoc = http://www.holux.com/JCore/en/support/DLF.jsp?DLU=http://www1.holux.com.tw:8080/JCore/UploadFile/79754.pdf +uses = SiRF-3 +interfaces = Bluetooth, USB +noconfigure = True +tested = 2.36 +rating = poor +nmea = 2.2 +notes = Bluetooth operation requires -b option. Powered from a car + cigarette-lighter. + +[M-241] +type = device +vendor = Holux +packaging = mouse +techdoc = http://www.holux.com/JCore/en/products/products_content.jsp?pno=341 +uses = MTK +interfaces = Bluetooth, USB +usbchip = CP2101 +noconfigure = True +tested = 2.37 +btglitch = yes +submitter = Roland Ager +notes = gpsd crashes the device when autoprobing @ baud rate 9600 (unless + '-b'/broken-device-safety is enabled - need to unplug/reset the device). + 'stty -F /dev/ttyUSB1 ispeed 38400' helps avoiding too much autoprobing - + though stty complains about not being able to perform all requested + operations. + +#% Humminbird + +[Matrix-37] +type = device +vendor = Humminbird +packaging = handsfree +techdoc = http://www.retrevo.com/support/Humminbird-37-GPS-manual/ +engine = unknown +interfaces = RS232 +discontinued = True +tested = regression +rating = good +submitter = Carl Brown +notes = Depth finder and water-temperature sensor. +logs = humminbird-M37.log + +#% iTrek + +[M3] +type = device +vendor = iTrek +packaging = mouse +techdoc = http://www.semsons.com/im3blgpsresi.html +uses = SiRF-3 +interfaces = Bluetooth +tested = 2.28 +submitter = Lance Fetters +notes = The product page points at a retail site carrying these + because the vendor site is in Japanese only. This GPS emits a + weirdly broken GSA sentence that crashed gpsd versions prior to + 2.28. Serial parameters default to 38400; 8, N, 1. May come + bundled with Microsoft Streets and Trips. +logs = iTrek.log + +#% Jackson Labs + +[Firefly-1a] +type = device +engine = UBLOX NEO-5Q +firmware = 0.918 +interfaces = RS-232 +packaging = OEM module +rating = excellent +submitter = Don Weeks , + Said Jackson +techdoc = http://jackson-labs.com/docs/FireFly_quickstart.pdf +vendor = Jackson Labs +notes = Only outputs GGA and RMC NMEA strings. There are other proprietary + commands. See the gpsd-dev list for patches. GPSD works as far back + as the 0.914 version, which emitted \r\r\n terminations. All the + FireFly units are OCXO drive, so the 1PPS output stays accurate even + if GPS reception is lost. + +[FireFly-II] +type = device +engine = UBLOX NEO-5Q +date = July 7th, 2010 +firmware = 2.18 +interfaces = RS-232 +model = FireFly-1A and FireFly-II GPSDO's +notes = Uses uBlox Antaris 5 with Kick Start and Super Sense, + soon movingto uBlox-6. Defective \r\r\n string terminations + have been fixed in the 2.18 firmware version. All the + FireFly units are OCXO drive, so the 1PPS output stays accurate even + if GPS reception is lost. +packaging = OEM module +rating = good +sample_notes = Stationary state, roof-mounted antenna, three levels of + GPS distribution Amplifier between antenna and receiver. +submitter = Said Jackson +techdoc = http://www.jackson-labs.com/docs/Quickstart_FireFly_IIA_FW-rev_2.x.pdf +vendor = Jackson Labs + +#% Magellan + +[EC-10X] +type = device +vendor = Magellan +packaging = handset +techdoc = http://www.herman-nelson.com/itemInfo.cfm?itemID=205 +uses = Zodiac +interfaces = RS232 +pps = True +tested = regression +discontinued = True +submitter = Gary E. Miller +notes = It was cool in its day, now a dinosaur mainly good for + regression testing. NMEA time is accurate to about 500mS. + Start of cycle is GPMRC on odd seconds, GPRMB on even seconds. +logs = magellan315.log + +[315] +type = device +vendor = Magellan +packaging = handset +techdoc = https://www.magellangps.com/assets/manuals/gps_310_315_en.pdf +engine = unknown +interfaces = RS232 +tested = regression +rating = good +submitter = Ángel Marqués Mateu +notes = +logs = magellan315.log + +[Meridian Platinum] +type = device +vendor = Magellan +packaging = handset +techdoc = http://www.amazon.com/Magellan-Meridian-Platinum-Handheld-GPS/dp/B00005OLYD +engine = Motorola +interfaces = RS232 +tested = 2.21 +rating = excellent +nmea = v1.5 APA, v1.5 XTE, v2.1 GSA +discontinued = true +submitter = Chris S. Newell + +[eXplorist 210] +type = device +vendor = Magellan +packaging = handset +techdoc = http://www.magellangps.com/assets/manuals/newprod/eXplorist%20210_US.pdf +engine = unknown +interfaces = USB +tested = regression +rating = good +nmea = 2.1 +submitter = Paul van den Berg +notes = USB has 3 modes — NMEA data comm (3 submodes): outputs GPS data + (creates /dev/ttyACM0), USB file transfer: transfer files (creates + /dev/sdX and /dev/sdX1), or Power Only: use USB only for electrical + power. The APA and XTE extensions choke gpsd, so select V2.1 GSA + under . +logs = eXplorist210.log + +[Thales AC12] +type = device +vendor = Magellan +packaging = OEM module +techdoc = ftp://ftp.magellangps.com/OEM,%20Sensor%20&%20ADU/A12,%20%20B12,%20&%20AC12/Techdoc%20Material/A12,%20B12%20&%20AC12%20RM%20rev%20E.pdf +engine = unknown +interfaces = TTL +nmea = 3.0 +tested = regression +rating = good +pps = True +submitter = Chris Kuethe +notes = Receiver comes up in silent mode, you may need to use ashctl to turn + on a default set of messages. Tested with firmware BQ00 and BQ04. +logs=ac12.log + +#% Motorola + +[Oncore GT+] +type = device +vendor = Motorola +packaging = OEM module +techdoc = http://www.tapr.org/gps_oncorevp.html +engine = Motorola +interfaces = RS232 or TTL +tested = 2.20 +nmea = 2.2 +pps = True +rating = good +discontinued = True +submitter = Wojciech Kazubski +notes = The Motorola Oncore product family has been discontinued. + RTCM input, no WAAS. In binary mode can deliver differential + correction for another Oncore GT+. Similar Motorola Oncore UT + timing receiver has less functions but better timing + accuracy. +logs = oncore.log + +[T805] +type = device +vendor = Motorola +packaging = mouse +techdoc = http://www.motorola.com/motoinfo/product/detailsPf.jsp?globalObjectId=185 +uses = SiRF-3 +subtype = GSC3f-7879 +interfaces = Bluetooth +tested = 2.35 +submitter = Reported by Olivier Lahaye + +#% Navcom + +[SF-2040G] +type = device +vendor = Navcom +packaging = survey +techdoc = http://www.navcomtech.com/Products/GPS/sf2040g.cfm +uses = Touchstone ASIC +interfaces = RS232, Bluetooth, Radio (untested) +tested = 2.35 +rating = good +nmea = 3.0 +submitter = Diego Berge + +#% Navius + +[NSA-U3] +type = device +vendor = Navius +packaging = mouse +techdoc = http://www.navius.biz/ +uses = SiRF-2 +interfaces = USB +usbchip = pl2303 +tested = 2.24 +rating = excellent +submitter = Jeff Francis +notes = Included with the horrible Windows navigation software from + Rand McNally. + +#% NaviLock + +[NL-209P] +type = device +vendor = NaviLock +packaging = mouse +techdoc = http://www.navilock.de/produkte/gruppen/3/Kabel_Empfaenger/61371_NL-209PU.html?show=spec +uses = Sony CXD2951 +interfaces = USB, RS232, Bluetooth +noconfigure = True +usbchip = pl2303 +tested = 2.35 +nmea = 2.2 +submitter = Jason Curl +notes = When running, need to use the -b option, else the device will + hang during the GPSD probing phase and it needs to be unplugged + and reinserted. To use this device with NTPd, set the the + "fudge" factor to 0.840. There is no known PPS signal associated + with this device. While the technical information claims 1us + accuracy on the clock, the interface is undocumented, so there + is no way to know if there is a usable 1PPS signal. + +[NL-302U] +type = device +vendor = NaviLock +packaging = mouse +techdoc = http://www.navilock.de/produkte/gruppen/3/Kabel_Empfaenger/61422_NL-302U.html?show=spec +uses = SiRF-3 +subtype = GSW3.2.4_3.1.00.12-SDK003P1 +interfaces = USB +usbchip = pl2303 +nmea = 2.34 +submitter = Beat Bolli +notes = gpsprof output can be found + here. + +[NL-402U USB] +type = device +engine = u-blox5 GPS & GALILEO SuperSense +date = 2008:07:24 +location = Neustadt / Holstein 54.05N 10.49 E +model = NL-402U USB Empfänger +interfaces = USB +packaging = mouse +rating = excellent +submitter = Klaus Plöger +techdoc = http://www.navilock.de/download/PDFs/60095_-_NL-402U_Datenblatt/531 +tested = regression +vendor = NaviLock +logs = nl402u.log +notes = Starts with RMC, ends with GLL. + +#% NavMan + +[Jupiter 20] +type = device +vendor = NavMan +packaging = chipset +techdoc = +uses = SiRF-2 +subtype = Jupiter 21DR Firmware +interfaces = RS232 +tested = 2.32 +nmea = 2.2 +discontinued = True +submitter = Andreas Stricker +notes = Not a complete GPS, but a chipset. It is running with an external + gyro on a our self-developed board. + +#%Navis Engineering Bureau + +[CH-4711] +type = device +vendor = Navis Engineering Bureau +engine = CH-4706 +date = 11/21/09 +firmware = m4706 03.10 02/06/09 | 12044 | M2002 05.01 02/06/09 +nmea = 3.0? +packaging = mouse +interfaces = USB +usbchip = FTDI FT232 +rating = good +submitter = walkie@mail.ru +techdoc = http://www.navis.ru/downloads/CH-4711_USB/ +logs = ch-4711.log +notes = By default the evice does not report 2d fixes; the vendor + configuration tool offers checkboxes to enable any combination of + none, 2D fixes, 3D fixes, or both. The devices has only a very + limited set of NMEA controls but speaks a proprietary vendor format + called BINR with more capabilities. + +[NAVIOR-24] +type = device +engine = CH-4701 +interfaces = TTL +date = 29 May 2008 +location = Minsk, Belarus, 53N 27E +model = NAVIOR-24 +packaging = OEM module +rating = good +submitter = Viktar Palstsiuk +techdoc = http://www.navis.ru/en/catalog_110_139.html +vendor = Navis Engineering Bureau +notes = NAVIOR-24 is the single board 24-channel navigation OEM receiver + supporting GLONASS/GPS systems. +logs = ch-4701.log + +#%Navisys + +[GR-300] +type = device +uses = SiRF-3 +date = 2009:07:03 +firmware = GSW3.2.4Pat2_3.1.00.12-SDK001P1.00 +interfaces = USB +location = East Haddon, Northampton, England, UK, 53.3N, 1.02W +model = GR-300 +nmea = 3.0 +packaging = mouse +rating = excellent +submitter = sk1ppy14@yahoo.co.uk +techdoc = http://www.navisys.com.tw/products/image/GR-300_flyer-080409.pdf +tested = 2.38 +vendor = Navisys +notes = Also includes an (untested) Bluetooth interface. Has two LEDs: + blue for bluetooth, green for rating. Solid green = on and searching + for satellite fixes. Blinking green = on and has 3D fix. + Also a similar GR-310 version available. It is possible that only GR-310 + supports Bluetooth. Programs only seem to be able to communicate + with the dongle at 4800 baud rates, though this is autodetected by gpsd + with no problems. Approx £40 per dongle. + +#%Nokia + +[LD-4W] +type = device +uses = SiRF-3 +date = 5 Dec 2009 +location = Oulu, FI, 65N 25E +model = LD-4W +interfaces = Bluetooth +noconfigure = yes +packaging = mouse +rating = fair +submitter = jussi.kivilinna@mbnet.fi +techdoc = http://europe.nokia.com/find-products/accessories/all-accessories/navigation/gps-modules/ld-4w +tested = 2.39 +vendor = Nokia +logs = nokia-ld-4w.log +notes = I first tried gpsd package from Ubuntu 9.10, which broke + device on probe. Luckily this device has 'reset' function by + pressing power button for 10 sec. Then I recompiled gpsd with + only support for Generic NMEA and SiRF binary and with fixed + speed (--enable-fixed-port-speed=9600). Now device works in sirf + mode, and does not break on probe. + +#% Novatel + +[SuperStar II (202)] +type = device +vendor = NovAtel +packaging = OEM Module +uses = NovAtel-L1 +techdoc = http://www.novatel.com/Documents/Manuals/om-20000077.pdf +tested = 2.38 +discontinued = True +interfaces = RS232 +pps = True +submitter = Chris Kuethe +notes = There are quite a number of models of SuperStarII, this is a + 169-613955-202 (1Hz, Carrier Phase, Timing, 19200). Other SuperStarII + boards should work. + +#% Parrot + +[CK3300] +type = device +vendor = Parrot +packaging = handsfree +techdoc = http://www.parrot.biz/uk/products/ck3300gps +engine = unknown +interfaces = Bluetooth +tested = 2.35 +rating = good +nmea = 2.? +submitter = Andy Brown +notes = In-car hands-free bluetooth phone and GPS device. Outputs NMEA + +#% Pharos + +[GPS-360] +type = device +vendor = Pharos +packaging = mouse +techdoc = http://www.pharosgps.com/support/igps360_spec.htm +uses = SiRF-2 +interfaces = USB +usbchip = pl2303 +tested = regression +nmea = 2.3 +discontinued = True +submitter = Robert Pouliot +notes = The Pharos comes with adaptors for SDIO, CF, USB and plain + RS232. Usually ships with XTrac firmware. It is strongly + recommended that this device not be flashed with a different + firmware as all reflashed receivers tested thus far fail to work + afterward. May come bundled with Microsoft Streets and Trips. + +[iGPS-500] +type = device +vendor = Pharos +packaging = mouse +techdoc = http://www.pharosgps.com/products/proddetail.asp?prod=006_PB010_1.00&cat=141 +uses = SiRF-3 +subtype = GSC3f +usbchip = PL2303 +interfaces = USB +tested = 2.3 +submitter = Aurelian Maga + +#% Phonix + +[BGR6205] +type = device +vendor = Phonix +packaging = mouse +techdoc = http://www.phonix.it/html/catalogo_dettaglio.cfm?idProducts=E09B5AB7-BCDF-DF66-24853E2B4680AB2C +uses = SiRF-2 +interfaces = Bluetooth +noconfigure = True +tested = 2.34 +nmea = 2.2 +notes = As this is a Bluetooth device, gpsd must either be run with "-b" or must + be compiled with fixed port speed, as the Bluetooth interface does not + tolerate port speed changes at all. Reported by Sebastiano Zabert + (no emal address) + +#% Qstarz + +[BT-Q818] +type = device +vendor = Qstarz +uses = MTK +interfaces = Bluetooth +date = June 3rd 2010 7:53 PST +location = +34? 1' 58.80", -117? 44' 49.56" +model = BT-Q818 +notes = Had to use the -b option. +packaging = mouse +rating = excellent +sample_notes = Not moving. Left unit on a north facing window sill. +submitter = jason.komut+gpsd@gmail.com +techdoc = http://www.qstarz.com/download/BT-Q818%20Quick%20Guide-V1.pdf +tested = 2.92-4 +logs=bt-q818.log + +#% Rikaline + +[GPS-6010 USB] +type = device +vendor = Rikaline +packaging = mouse +techdoc = http://www.rikaline.com/download/GPS-6010-Manual-E.pdf +uses = SiRF-2 +interfaces = USB +usbchip = pl2303 +tested = 2.20 +nmea = 2.2 +notes = Uses SiRF firmware version 2.3.2-GSW2-2.05.024-C1Prod1.1. Manufacturer + claims it is waterproof (1 meter), WAAS and EGNOS are supported. + +[GPS-6010-X5] +type = device +vendor = Rikaline +packaging = mouse +techdoc = http://www.rikaline.com/gps_receiver.htm +uses = SiRF-2 +interfaces = USB +usbchip = PL2303 +tested = 2.20 +nmea = 2.2 +submitter = Koos van den Hout +notes = The USB cable is a separate item to order. You can also order an + RS232 cable or a PDA cable. + +#% Royaltek + +[Sapphire USB] +type = device +vendor = Royaltek +packaging = mouse +techdoc = http://www.royaltek.com/content/view/27/27/ +uses = SiRF-2 +interfaces = USB +tested = 1.97 +nmea = 2.2 +notes = There is an RS232 variant as well, not yet tested. + +[RGM-3600] +type = device +uses = SiRF-3 +firmware = GSW3.2.5_3.3.01.06_SDK001P1.00 +interfaces = USB +nmea = 3.0 +notes = Works out of the box. +packaging = mouse +rating = excellent +submitter = Stijn Ghesquiere +techdoc = http://www.royaltek.com/FileDownload.php?dir=Product_C1_Info&file=RGM-3600%20operational%20manual%20V1_1209966059.pdf +tested = 2.37 +vendor = Royaltek + +[RGM-3800] +type = device +techdoc = http://www.royaltek.com/products_dtl.php?cid=2&id=23&argPage=1&argI=3 +vendor = Royaltek +packaging = mouse +uses = SiRF-2 +subtype = GSC3f/LP +interfaces = USB (PL2303) +tested = regression +nmea = 3.0 +submitter = Philipp Klenze +notes = This is a GPS data logger with mouse functionality. Before it can be + used with gpsd, the mouse functionality has to be switched on. That + can be done with the rgm3800py utility by Karsten Petersen. The author of + said tool has been very helpful to me by describing how to do that on + the + projectpage. Basically, one needs to run "rgm3800.py -d + /dev/ttyUSB0 gmouse on" before starting gpsd. + +#% San Jose Navigation + +[FV-18] +type = device +vendor = San Jose Navigation +packaging = OEM module +techdoc = http://www.sanav.com/gps_engine_board/fv-18.htm +engine = FV-18 +interfaces = UART +tested = 2.0 +rating = good +nmea = 2.3 +notes = Special gpsd support uses 8N2 and requests sentences that gpsd requires. + OEM module only, not a retail product. + +[FV-25] +type = device +vendor = San Jose Navigation +packaging = OEM module +techdoc = http://www.tri-m.com/products/systems/fv25.html +uses = ANTARIS +subtype = TIM-LP +interfaces = UART +tested = 2.34 +pps = True +notes = OEM module, available in small quantities from Tri-M + systems. The ANTARIS chipset is obsolete, replaced by + ANTARIS4. This module works in NMEA mode; gpsd also supports the + UBX binary protocol. Firmware updates are available from uBlox; + the update is strongly recommended as it fixes a number of UBX + bugs, and adds useful new features. + +[FV-M11] +type = device +vendor = San Jose Navigation +engine = MTK +packaging = OEM module +techdoc = http://www.sanav.com/gps_engine_board/FV-M7_FV-M11.htm +interfaces = UART +nmea = 3.01 +rating = good +tested = regression +submitter = Henk Fijnvandraat (no email address) +notes = +logs = mkt-3301.log + +[GM-38/12V] +type = device +vendor = San Jose Navigation +packaging = mouse +techdoc = http://www.tri-m.com/products/systems/gm38.html +engine = Furuno GN-77 +interfaces = RS232 +tested = 2.21 +nmea = 2.x +discontinued = True +rating = broken +notes = Ships bad packet checksums when it does not have a fix. + +#%Skytraq + +[Venus634LP] +type = device +engine = SkyTraq Venus 6 +interfaces = TTL +date = 05 Feb 2010 +firmware = ver,011023,rev,090210 +location = Minsk, Belarus, 53N 27E +model = Venus634LP +nmea = 3.01 +notes = Supports A-GPS from the SkyTraq FTP server. +packaging = OEM module +rating = good +submitter = Viktar Palstsiuk +techdoc = http://www.skytraq.com.tw/download/Venus634LPx_PB_v3.pdf +tested = 2.90 +vendor = SkyTraq +logs = venus634lp.log + +#% Techway + +[TP-051] +type = device +vendor = Techway +packaging = mouse +techdoc = http://www.techwayinc.com.tw/TP-051.htm +uses = SiRF-2 +interfaces = USB +usbchip = pl2303 +tested = 2.3 +nmea = 2.x +discontinued = True +notes = Advertises that it is waterproof. + +#% TomTom + +[TomTom Go910] +type = device +vendor = TomTom +packaging = handsfree +techdoc = http://www.tomtom.com/products/product.php?ID=475&Category=0&Lid=4 +engine = SiRF-3 +interfaces = USB +nmea = None +rating = broken +notes = This device does not have real-time data output, and is incompatible + with GPSD. + +[Mark II Bluetooth GPS] +type = device +vendor = TomTom +engine = SiRF-3 +interfaces = Bluetooth +date = 20 June 2010 +location = Veldhoven, NL +nmea = Version 2.2 +packaging = mouse +rating = good +sample_notes = The unit was stationary (sorry). It is a putty log after connecting to port 2947. +submitter = Jose Baars peut@peut.org +techdoc = http://download.tomtom.com/open/manuals/mob5_nav5/Wireless_GPS_manual_NAV5_MOB5.pdf +tested = 2.36 +logs = tomtom-mkII.log +notes = I use this GPS as a time source. I use a time1 parameter of + -1.4 in /etc/ntp.conf, but then it appears to provide time + reliably within 100ms and only limited sky view. + +#% Transystem + +[iGPS-M] +type = device +vendor = Transystem +packaging = mouse +techdoc = http://www.transystem.com.tw/products/index_detail.php?mcat_no=2&cat_no=32&pno=10&ver=en +uses = uNav +interfaces = USB +usbchip = pl2303 +tested = 2.28 +submitter = Romain Goyet +notes = Formerly sold under the corporate name "Bona CompuTech". + +#% Trimble + +[Trimble Lassen SK] +type = device +vendor = Trimble +packaging = OEM module +techdoc = http://www.trimble.com/lassensk2.shtml +engine = Colossus RF ASIC, Scorpion DSP +interfaces = UART +tested = 2.26 +rating = good +nmea = 2.1 +notes = Reported by Rob Janssen (no email address) + +[Trimble Lassen IQ] +type = device +vendor = Trimble +packaging = OEM module +techdoc = http://www.trimble.com/lasseniq.shtml +engine = Colossus RF ASIC, IO-C33 (Epson C33 RISC) +interfaces = USB,RS232 +pps = True +usbchip = CP2102 +tested = regression +rating = good +nmea = 3.0 +submitter = Chris Kuethe +logs = trimble-lassen_iq-3dfix.log, trimble-lassen_iq-playacar.log, + trimble-lassen_iq.log + +[Trimble BX960] +type = device +vendor = Trimble +packaging = OEM module +techdoc = http://www.trimble.com/embeddedsystems/pdf/bx960_ds.pdf +engine = BD960 +interfaces = Ethernet +tested = regression +rating = good +submitter = Miika Ojanen +notes = Firmware versoon 4.00, dated 2009-03-10 + +#% uBlox + +[ANTARIS LEA-4H] +type = device +vendor = uBlox +packaging = OEM module +techdoc = http://www.u-blox.com/products/lea_4h.html +uses = ANTARIS4 +tested = regression +interfaces = RS232 +pps = True +submitter = Andreas Stricker + +[ANTARIS LEA-4S] +type = device +vendor = uBlox +packaging = OEM module +techdoc = http://www.u-blox.com/products/lea_4s.html +uses = ANTARIS4 +interfaces = USB,UART +tested = regression +submitter = Ali Utku Selen + +[ANTARIS LEA-4T] +type = device +vendor = uBlox +packaging = OEM module +techdoc = http://www.u-blox.com/products/lea_4t.html +uses = ANTARIS4 +interfaces = USB,UART +tested = regression +pps = True +submitter = Chris Kuethe + +#% UniTraq + +[WGM-300U] +type = device +vendor = UniTraq +packaging = mouse +techdoc = http://www.wintec.com.tw/en/support_detail.php?cate_id=11&support_id=14 +uses = Sony CXD2951 +noconfigure = True +interfaces = USB +usbchip = CP2101 +tested = 2.35 +nmea = 3.0 +submitter = Reported by Ian Darwin +notes = This receiver operates as a generic NMEA device, the Sony + binary protocol is unsupported. The receiver seems to lock up if + too much data is thrown at it (ie. gpsd probes) thus it may + require a read-only (-b) instance of gpsd. (We say 'may' because + more recent instances of gpsd break the probe writes into pieces + interleaved with read, and may no longer trigger this problem) + +#%Variotek + +[VT-BT-204] +type = device +engine = Skytraq Venus 6 +date = 20 March 2010 +model = VT-BT-204 +packaging = mouse +interfaces = Bluetooth +#location = 48.13333 N 11.593281 E +#sample_notes = all time fixed +submitter = Claus Seitter +techdoc = http://variotek.de/wp-content/uploads/2009/02/vt_bt204_guide_english.pdf +vendor = Variotek +rating = good + +#% Wintec + +[WBT-200] +type = device +vendor = Wintec +packaging = mouse +techdoc = http://www.wintec.com.tw/en/product_detail.php?pro_id=57 +engine = FastraX iTrax03 +interfaces = Bluetooth, USB +usbchip = CP2101 +tested = regression +nmea = 3.0 +rating = good +submitter = Chris Kuethe +notes = This receiver operates correctly as a generic NMEA device, + iTalk support is also functional, though switching between NMEA + and iTalk does not yet work, nor does any device configuration. + + +[WBT-201] +type = device +vendor = Wintec +packaging = mouse +techdoc = http://www.wintec.com.tw/en/product_detail.php?pro_id=65 +uses = ANTARIS4 +interfaces = Bluetooth, USB +usbchip = CP2101 +tested = 2.33 +submitter = Espen Talberg +notes = This receiver operates correctly as a generic NMEA device, UBX support + is also functional, though switching between NMEA and UBX does not yet + work, nor does any device configuration. + + diff --git a/gpscap.py b/gpscap.py new file mode 100644 index 0000000..950284a --- /dev/null +++ b/gpscap.py @@ -0,0 +1,151 @@ +""" + +gpscap - GPS/AIS capability dictionary class. + +This file is Copyright (c) 2010 by the GPSD project +BSD terms apply: see the file COPYING in the distribution root for details. +""" +import ConfigParser + +class GPSDictionary(ConfigParser.RawConfigParser): + def __init__(self, *files): + "Initialize the capability dictionary" + ConfigParser.RawConfigParser.__init__(self) + if not files: + files = ["gpscap.ini", "/usr/share/gpsd/gpscap.ini"] + self.read(files) + # Resolve uses= members + while True: + keepgoing = False + for section in self.sections(): + if self.has_option(section, "uses"): + parent = self.get(section, "uses") + if self.has_option(parent, "uses"): + continue + # Found a parent section without a uses = part. + for heritable in self.options(parent): + if not self.has_option(section, heritable): + self.set(section, + heritable, + self.get(parent, heritable)) + keepgoing = True + self.remove_option(section, "uses") + if not keepgoing: + break + # Sanity check: All items must have a type field. + for section in self.sections(): + if not self.has_option(section, "type"): + raise ConfigParser.Error("%s has no type" % section) + elif self.get(section, "type") not in ("engine", "vendor", "device"): + raise ConfigParser.Error("%s has invalid type" % section) + # Sanity check: All devices must point at a vendor object. + # Side effect: build the lists of vendors and devices. + self.vendors = [] + self.devices = [] + for section in self.sections(): + if self.get(section, "type") == "vendor": + self.vendors.append(section) + if self.get(section, "type") == "device": + self.devices.append(section) + self.vendors.sort() + for section in self.sections(): + if self.get(section, "type") == "device": + if not self.has_option(section, "vendor"): + raise ConfigParser.Error("%s has no vendor" % section) + if self.get(section, "vendor") not in self.vendors: + raise ConfigParser.Error("%s has invalid vendor" % section) + + def HTMLDump(self, ofp): + thead = """ + + + + + + + + + + +""" + vhead = "\n" + hotpluggables = ("pl2303", "CP2101") + ofp.write(thead % (len(self.devices), len(self.vendors))) + for vendor in self.vendors: + ofp.write(vhead % (self.get(vendor, "vendor_site"), vendor)) + relevant = [] + for dev in self.devices: + if self.get(dev, "vendor") == vendor: + relevant.append(dev) + relevant.sort() + for dev in relevant: + rowcolor = "#FFFFFF" + if self.get(dev, "packaging") == "OEM module": + rowcolor = "LimeGreen" + elif self.get(dev, "packaging") == "chipset": + rowcolor = "LightYellow" + elif self.get(dev, "packaging") == "handset": + rowcolor = "Cyan" + elif self.get(dev, "packaging") == "hansdfree": + rowcolor = "DarkCyan" + + ofp.write("\n" % rowcolor) + namefield = dev + if self.has_option(dev, "techdoc"): + namefield = "%s" % (self.get(dev, "techdoc"), dev) + if self.has_option(dev, "discontinued"): + namefield = namefield + " " + ofp.write("\n" % namefield) + ofp.write("\n" % self.get(dev, "packaging")) + engine = self.get(dev, "engine") + if self.has_option(engine, "techdoc"): + engine = "%s" % (self.get(engine, "techdoc"), engine) + if self.has_option(dev, "subtype"): + engine += " (" + self.get(dev, "subtype") + ")" + ofp.write("\n" % engine) + interfaces = self.get(dev, "interfaces") + if self.has_option(dev, "pps"): + interfaces += ",PPS" + ofp.write("\n" % interfaces) + testfield = "" + if self.has_option(dev, "tested"): + tested = self.get(dev, "tested") + if tested == "regression": + testfield += "" + else: + testfield += tested + if self.has_option(dev, "noconfigure"): + testfield += "" + if self.get(dev, "rating") == "excellent": + testfield += "" + elif self.get(dev, "rating") == "good": + testfield += "" + elif self.get(dev, "rating") == "fair": + testfield += "" + elif self.get(dev, "rating") == "poor": + testfield += "" + elif self.get(dev, "rating") == "broken": + testfield += "" + if self.has_option(dev, "usbchip") and self.get(dev, "usbchip") in hotpluggables: + testfield += "" + ofp.write("\n" % testfield) + nmea = " " + if self.has_option(dev, "nmea"): + nmea = self.get(dev, "nmea") + ofp.write("\n" % nmea) + if self.has_option(dev, "notes"): + notes = self.get(dev, "notes") + else: + notes = "" + if self.has_option(dev, "submitter"): + notes += " Reported by %s." % self.get(dev, "submitter") + notes = notes.replace("@", "@").replace("<", "<").replace(">", ">") + ofp.write("\n" % notes) + ofp.write("\n") + ofp.write("
Listing %s devices from %s vendors
NamePackagingEngineInterfaceTested withNMEA versionNotes
%s
%s%s%s%s%s%s%s
\n") + + +if __name__ == "__main__": + import sys + d = GPSDictionary() + d.HTMLDump(sys.stdout) diff --git a/gpscat b/gpscat new file mode 100755 index 0000000..f51cacb --- /dev/null +++ b/gpscat @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# Display GPS output. Hexify it if necessary. +# +import os, sys, termios, socket, select, getopt, curses.ascii +import gps.packet as sniffer + +# The spec says 82, but some receivers (TN-200, GSW 2.3.2) output 86 characters +NMEA_MAX = 86 + +# Lowest debug level at which packet getter begins to emit messages, minus one +BASELEVEL = sniffer.LOG_IO + +highhalf_latch = True + +def hexdump(str): + dmp = "" + for (i, ch) in enumerate(str): + if curses.ascii.isprint(ord(ch)) or curses.ascii.isspace(ord(ch)): + dmp += ch + else: + dmp += "\\x%02x" % ord(ch) + return dmp + +debuglevel = 0 + +def reporter(errlevel, msg): + if errlevel <= debuglevel: + sys.stdout.write(msg) + +if __name__ == '__main__': + buf = "" + try: + try: + (options, arguments) = getopt.getopt(sys.argv[1:], "hps:tD:V") + except getopt.GetoptError, msg: + print "gpscat: " + str(msg) + raise SystemExit, 1 + + speed = None + parity = None + stopbits = None + rawmode = True + typeflag = False + for (switch, val) in options: + if switch == '-p': + rawmode = False + elif switch == '-s': + if val[-2] in ('N', 'E', 'O'): + parity = val[-2] + stopbits = int(val[-1]) + val = val[:-2] + speed = int(val) + elif switch == '-t': + typeflag = True + rawmode = False + elif switch == '-D': + debuglevel = BASELEVEL + int(val) + elif switch == '-h': + sys.stderr.write("usage: gpscat [-s speed] serial-port\n") + raise SystemExit, 0 + + if "rfcomm" in arguments[0]: # Bluetooth special case + s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM) + s.connect((arguments[0], 1)) + tty = s.fileno() + else: # Ordinary device + tty = os.open(arguments[0], os.O_RDWR) + + if speed != None: + (iflag, oflag, cflag, lflag, ispeed, ospeed, cc) = termios.tcgetattr(tty) + try: + ispeed = ospeed = eval("termios.B%d" % speed) + except AttributeError: + sys.stderr.write("gpscat: unknown baud rate %d\n" % speed) + raise SystemExit, 1 + if stopbits: + cflag &= ~termios.CSIZE + cflag |= (termios.CS8, termios.CS7)[stopbits-1] + if parity: + if parity == 'N': + iflag &= ~termios.PARENB + iflag &= ~termios.INPCK + elif parity == 'O': + iflag |= termios.INPCK + cflag |= termios.PARENB + cflag |= termios.PARODD + elif parity == 'E': + iflag |= termios.INPCK + cflag |= termios.PARENB + cflag &= ~termios.PARODD + termios.tcsetattr(tty, termios.TCSANOW, + [iflag, oflag, cflag, lflag, ispeed, ospeed, cc]) + + poller = select.poll() + poller.register(tty, select.POLLIN) + + buf = "" + if not rawmode: + getter = sniffer.new() + sniffer.register_report(reporter) + seqno = 0 + while True: + (fd, event) = poller.poll()[0] + if fd == tty and event == select.POLLIN: + if rawmode: + buf += os.read(tty, NMEA_MAX) + sys.stdout.write(hexdump(buf)) + buf = "" + else: + (length, ptype, packet) = getter.get(tty) + seqno += 1 + if length == 0: + break + if typeflag: + sys.stdout.write(`ptype` + " (" + `length` + "): " + hexdump(packet)) + sys.stdout.write("\n") + else: + sys.stdout.write(hexdump(packet) + "\n") + except KeyboardInterrupt: + if rawmode: + sys.stdout.write("\n") + raise SystemExit, 0 + +# Local variables: +# mode: python +# end: + + diff --git a/gpscat.xml b/gpscat.xml new file mode 100644 index 0000000..53d1be9 --- /dev/null +++ b/gpscat.xml @@ -0,0 +1,135 @@ + + + + +16 Nov 2006 + +gpscat +1 +The GPSD Project +GPSD Documentation + + +gpscat +dump the output from a GPS + + + + + gpscat + -s speed + -p + -t + -D debuglevel + serial-port + + + +DESCRIPTION + +gpscat is a simple program for +logging and packetizing GPS data streams. It takes input from a +specified file or serial device (presumed to have a GPS attached) and +reports to standard output. The program runs until end of input or it is +interrupted by ^C or other means. It does not terminate on a bad +backet; this is intentional. + +In raw mode (the default) gpscat +simply dumps its input to standard output. Nonprintable characters +other than ASCII whitepace are rendered as hexadecimal string escapes. + +In packetizing mode, gpscat uses the +same code as +gpsd8's +packet sniffer to break the input into packets. Packets are reported +one per line; line breaks in the packets themselves are +escaped. + +This program is useful as a sanity checker when examining a new +device. It can be used as a primitive NMEA logger, but beware that +(a) interrupting it likely to cut off output in mid-sentence, and (b) +to avoid displaying incomplete NMEA sentences right up next to shell +prompts that often contain a $, raw mode always emits an extra final +linefeed. + +Also, be aware that packetizing mode will produce useless +results — probably consuming the entirety of input and appearing +to hang — if it is fed data that is not a sequence of packets +of one of the known types. + +The program accepts the following options: + + + +-p + +Invoke packetizer mode. + + + + +-s + +Set the port's baud rate (and optionally its parity and stop +bits) before reading. Argument should begin with one of the normal integer +baud rates (300, 1200, 4800, 9600, 19200, 38400, etc.). It may be +followed by an optional suffix [NOE][12] to set parity (None, Even, +Odd) and stop bits (1 or 2). + + + + +-t + +Invoke packetizer mode, with the packet type and length (in +parentheses) reported before a colon and space on each line. + + + + +-D + +In packetizer mode, enable progress messages from the packet +getter. Probably only of interest to developers testing packet +getter changes. + + + + +-h + +Display program usage and exit. + + + + +Specifying -s 4800N1 is frequently helpful with unknown +devices. + + + +SEE ALSO + +gpsd8, +gps1, +libgps3, +libgpsd3, +gpsfake1. +gpsprof1, +gpsctl1, +gpsmon1. + + + +AUTHOR + +Eric S. Raymond esr@thyrsus.com. There is a +project page for gpsd here. + + diff --git a/gpsclient.c b/gpsclient.c new file mode 100644 index 0000000..f32b8af --- /dev/null +++ b/gpsclient.c @@ -0,0 +1,84 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + * Python binding for selected libgps library functions + */ +#include + +#include +#include "gps.h" +#include "gpsdclient.h" + +/* + * Client utility functions + */ + +static PyObject * +gpsclient_deg_to_str(PyObject *self, PyObject *args) +{ + int fmt; + double degrees; + + if (!PyArg_ParseTuple(args, "id", &fmt, °rees)) + return NULL; + return Py_BuildValue("s", deg_to_str((enum deg_str_type)fmt, degrees)); +} + +static PyObject * +gpsclient_gpsd_units(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + return Py_BuildValue("i", (int)gpsd_units()); +} + +/* + * Miscellanea + */ + +static PyObject * +gpsclient_wgs84_separation(PyObject *self, PyObject *args) +{ + const double lat, lon; + double sep; + + if (!PyArg_ParseTuple(args, "dd", &lat, &lon)) + return NULL; + sep = wgs84_separation(lat, lon); + return Py_BuildValue("d", sep); +} + +/* List of functions defined in the module */ + +static PyMethodDef gpsclient_methods[] = { + {"wgs84_separation", gpsclient_wgs84_separation, METH_VARARGS, + PyDoc_STR("Return WGS84 geodetic separation in meters.")}, + {"deg_to_str", gpsclient_deg_to_str, METH_VARARGS, + PyDoc_STR("String-format a latitude/longitude.")}, + {"gpsd_units", gpsclient_gpsd_units, METH_VARARGS, + PyDoc_STR("Deduce a set of units from locale and environment.")}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(module_doc, +"Python wrapper for selected libgps library routines.\n\ +"); + +PyMODINIT_FUNC +initclienthelpers(void) +{ + PyObject *m; + + m = Py_InitModule3("gps.clienthelpers", gpsclient_methods, module_doc); + + PyModule_AddIntConstant(m, "deg_dd", deg_dd); + PyModule_AddIntConstant(m, "deg_ddmm", deg_ddmm); + PyModule_AddIntConstant(m, "deg_ddmmss", deg_ddmmss); + + PyModule_AddIntConstant(m, "unspecified", unspecified); + PyModule_AddIntConstant(m, "imperial", imperial); + PyModule_AddIntConstant(m, "nautical", nautical); + PyModule_AddIntConstant(m, "metric", metric); +} + diff --git a/gpsctl.c b/gpsctl.c new file mode 100644 index 0000000..f45baab --- /dev/null +++ b/gpsctl.c @@ -0,0 +1,673 @@ +/* gpsctl.c -- tweak the control settings on a GPS + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + */ +#include +#include +#include +#include "gpsd_config.h" +#if HAVE_SYS_IOCTL_H + #include +#endif /* HAVE_SYS_IOCTL_H */ +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "revision.h" + +static int debuglevel; + +/* + * Set this as high or higher than the maximum number of subtype + * probes in drivers.c. + */ +#define REDIRECT_SNIFF 15 + +void gpsd_report(int errlevel UNUSED, const char *fmt, ... ) +/* our version of the logger */ +{ + if (errlevel <= debuglevel) { + va_list ap; + va_start(ap, fmt); + (void)fputs("gpsctl: ", stderr); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + } +} + +/*@ -noret @*/ +static gps_mask_t get_packet(struct gps_device_t *session) +/* try to get a well-formed packet from the GPS */ +{ + gps_mask_t fieldmask; + + for (;;) { + int waiting = 0; + (void)ioctl(session->gpsdata.gps_fd, FIONREAD, &waiting); + if (waiting == 0) { + (void)usleep(300); + continue; + } + fieldmask = gpsd_poll(session); + if ((fieldmask &~ ONLINE_IS)!=0) + return fieldmask; + } +} +/*@ +noret @*/ + +static int gps_query(struct gps_data_t *gpsdata, const char *fmt, ... ) +/* query a gpsd instance for new data */ +{ + char buf[BUFSIZ]; + va_list ap; + int ret; + + va_start(ap, fmt); + (void)vsnprintf(buf, sizeof(buf)-2, fmt, ap); + va_end(ap); + if (buf[strlen(buf)-1] != '\n') + (void)strlcat(buf, "\n", BUFSIZ); + if (write(gpsdata->gps_fd, buf, strlen(buf)) <= 0) { + gpsd_report(LOG_ERROR, "gps_query(), write failed\n"); + return -1; + } + gpsd_report(LOG_PROG, "gps_query(), wrote, %s\n", buf); + ret = gps_read(gpsdata); + if (ERROR_IS & gpsdata->set) { + gpsd_report(LOG_ERROR, "gps_query() error '%s'\n", gpsdata->error); + } + return ret; + +} + +static void onsig(int sig) +{ + if (sig == SIGALRM) { + gpsd_report(LOG_ERROR, "packet recognition timed out.\n"); + exit(1); + } else { + gpsd_report(LOG_ERROR, "killed by signal %d\n", sig); + exit(0); + } +} + +int main(int argc, char **argv) +{ + int option, status; + char *device = NULL, *devtype = NULL; + char *speed = NULL, *control = NULL, *rate = NULL; + bool to_binary = false, to_nmea = false, reset = false; + bool lowlevel=false, echo=false; + struct gps_data_t gpsdata; + const struct gps_type_t *forcetype = NULL; + const struct gps_type_t **dp; + unsigned int timeout = 4; +#ifdef ALLOW_CONTROLSEND + char cooked[BUFSIZ]; + ssize_t cooklen = 0; +#endif /* ALLOW_RECONFIGURE */ + +#define USAGE "usage: gpsctl [-l] [-b | -n | -r] [-D n] [-s speed] [-c rate] [-T timeout] [-V] [-t devtype] [-x control] [-e] \n" + while ((option = getopt(argc, argv, "bec:fhlnrs:t:x:D:T:V")) != -1) { + switch (option) { + case 'b': /* switch to vendor binary mode */ + to_binary = true; + break; + case 'c': +#ifdef ALLOW_RECONFIGURE + rate = optarg; +#else + gpsd_report(LOG_ERROR, "cycle-change capability has been conditioned out.\n"); +#endif /* ALLOW_RECONFIGURE */ + break; + case 'x': /* ship specified control string */ +#ifdef ALLOW_CONTROLSEND + control = optarg; + lowlevel = true; + if ((cooklen = hex_escapes(cooked, control)) <= 0) { + gpsd_report(LOG_ERROR, + "invalid escape string (error %d)\n", (int)cooklen); + exit(1); + } +#else + gpsd_report(LOG_ERROR, "control_send capability has been conditioned out.\n"); +#endif /* ALLOW_CONTROLSEND */ + break; + case 'e': /* echo specified control string with wrapper */ + lowlevel = true; + echo = true; + break; + case 'f': /* force direct access to the device */ + lowlevel = true; + break; + case 'l': /* list known device types */ + for (dp = gpsd_drivers; *dp; dp++) { +#ifdef ALLOW_RECONFIGURE + if ((*dp)->mode_switcher != NULL) + (void)fputs("-[bn]\t", stdout); + else + (void)fputc('\t', stdout); + if ((*dp)->speed_switcher != NULL) + (void)fputs("-s\t", stdout); + else + (void)fputc('\t', stdout); + if ((*dp)->rate_switcher != NULL) + (void)fputs("-c\t", stdout); + else + (void)fputc('\t', stdout); +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + if ((*dp)->control_send != NULL) + (void)fputs("-x\t", stdout); + else + (void)fputc('\t', stdout); +#endif /* ALLOW_CONTROLSEND */ + (void)puts((*dp)->type_name); + } + exit(0); + case 'n': /* switch to NMEA mode */ +#ifdef ALLOW_RECONFIGURE + to_nmea = true; +#else + gpsd_report(LOG_ERROR, "speed-change capability has been conditioned out.\n"); +#endif /* ALLOW_RECONFIGURE */ + break; + case 'r': /* force-switch to default mode */ +#ifdef ALLOW_RECONFIGURE + reset = true; + lowlevel = false; /* so we'll abort if the daemon is running */ +#else + gpsd_report(LOG_ERROR, "reset capability has been conditioned out.\n"); +#endif /* ALLOW_RECONFIGURE */ + break; + case 's': /* change output baud rate */ +#ifdef ALLOW_RECONFIGURE + speed = optarg; +#else + gpsd_report(LOG_ERROR, "speed-change capability has been conditioned out.\n"); +#endif /* ALLOW_RECONFIGURE */ + break; + case 't': /* force the device type */ + devtype = optarg; + break; + case 'T': /* set the timeout on packet recognition */ + timeout = (unsigned)atoi(optarg); + break; + case 'D': /* set debugging level */ + debuglevel = atoi(optarg); + gpsd_hexdump_level = debuglevel; +#ifdef CLIENTDEBUG_ENABLE + gps_enable_debug(debuglevel, stderr); +#endif /* CLIENTDEBUG_ENABLE */ + break; + case 'V': + (void)fprintf(stderr, "gpsctl: version %s (revision %s)\n", + VERSION, REVISION); + break; + case 'h': + default: + fprintf(stderr, USAGE); + break; + } + } + + if (optind < argc) + device = argv[optind]; + + if (devtype != NULL) { + int matchcount = 0; + for (dp = gpsd_drivers; *dp; dp++) { + if (strstr((*dp)->type_name, devtype) != NULL) { + forcetype = *dp; + matchcount++; + } + } + if (matchcount == 0) + gpsd_report(LOG_ERROR, "no driver type name matches '%s'.\n", devtype); + else if (matchcount == 1) { + assert(forcetype != NULL); + gpsd_report(LOG_PROG, "%s driver selected.\n", forcetype->type_name); + } else { + forcetype = NULL; + gpsd_report(LOG_ERROR, "%d driver type names match '%s'.\n", + matchcount, devtype); + } + } + + if ((int)to_nmea + (int)to_binary + (int)reset > 1) { + gpsd_report(LOG_ERROR, "make up your mind, would you?\n"); + exit(0); + } + + (void) signal(SIGINT, onsig); + (void) signal(SIGTERM, onsig); + (void) signal(SIGQUIT, onsig); + + /*@-nullpass@*/ /* someday, add null annotation to the gpsopen_r() params */ + if (!lowlevel) { + /* Try to open the stream to gpsd. */ + if (gps_open_r(NULL, NULL, &gpsdata) != 0) { + gpsd_report(LOG_ERROR, "no gpsd running or network error: %s.\n", + netlib_errstr(errno)); + lowlevel = true; + } + } + /*@-nullpass@*/ + + /* ^ someday, add out annotation to the gpspoll() param and remove */ + if (!lowlevel) { + /* OK, there's a daemon instance running. Do things the easy way */ + struct devconfig_t *devlistp; + (void)gps_read(&gpsdata); + if ((gpsdata.set & DEVICELIST_SET) != 0) { + gpsd_report(LOG_ERROR, "no VERSION response received; update your gpsd.\n"); + (void)gps_close(&gpsdata); + exit(1); + } + (void)gps_query(&gpsdata, "?DEVICES;\n"); + if ((gpsdata.set & DEVICELIST_SET) == 0) { + gpsd_report(LOG_ERROR, "no DEVICES response received.\n"); + (void)gps_close(&gpsdata); + exit(1); + } + + if (gpsdata.devices.ndevices == 0) { + gpsd_report(LOG_ERROR, "no devices connected.\n"); + (void)gps_close(&gpsdata); + exit(1); + } else if (gpsdata.devices.ndevices > 1 && device == NULL) { + gpsd_report(LOG_ERROR, + "multiple devices and no device specified.\n"); + (void)gps_close(&gpsdata); + exit(1); + } + gpsd_report(LOG_PROG,"%d device(s) found.\n",gpsdata.devices.ndevices); + + if (gpsdata.devices.ndevices == 1) { + devlistp = &gpsdata.devices.list[0]; + device = devlistp->path; + } else { + int i; + assert(device != NULL); + for (i = 0; i < gpsdata.devices.ndevices; i++) + if (strcmp(device, gpsdata.devices.list[i].path) == 0) + goto foundit; + gpsd_report(LOG_ERROR, "specified device not found.\n"); + (void)gps_close(&gpsdata); + exit(1); + foundit: + devlistp = &gpsdata.devices.list[i]; + } + + /* if no control operation was specified, just ID the device */ + if (speed==NULL && rate == NULL && !to_nmea && !to_binary && !reset) { + gpsd_report(LOG_SHOUT, "%s identified as %s at %d\n", + devlistp->path, devlistp->driver, devlistp->baudrate); + exit(0); + } + + status = 0; +#ifdef ALLOW_RECONFIGURE + if (reset) + { + gpsd_report(LOG_PROG, "cannot reset with gpsd running.\n"); + exit(0); + } + + /*@-boolops@*/ + if (to_nmea) { + (void)gps_query(&gpsdata, "?DEVICE={\"path\":\"%s\",\"native\":0}\r\n", device); + if ((gpsdata.set & ERROR_SET) || (gpsdata.dev.driver_mode != MODE_NMEA)) { + gpsd_report(LOG_ERROR, "%s mode change to NMEA failed\n", gpsdata.dev.path); + status = 1; + } else + gpsd_report(LOG_PROG, "%s mode change succeeded\n", gpsdata.dev.path); + } + else if (to_binary) { + (void)gps_query(&gpsdata, "?DEVICE={\"path\":\"%s\",\"native\":1}\r\n", device); + if ((gpsdata.set & ERROR_SET) || (gpsdata.dev.driver_mode != MODE_BINARY)) { + gpsd_report(LOG_ERROR, "%s mode change to native mode failed\n", gpsdata.dev.path); + status = 1; + } else + gpsd_report(LOG_PROG, "%s mode change succeeded\n", gpsdata.dev.path); + } + /*@+boolops@*/ + if (speed != NULL) { + char parity = 'N'; + char stopbits = '1'; + if (strchr(speed, ':') == NULL) + (void)gps_query(&gpsdata, + "?DEVICE={\"path\":\"%s\",\"bps\":%s}\r\n", + device, speed); + else { + char *modespec = strchr(speed, ':'); + /*@ +charint @*/ + status = 0; + if (modespec!=NULL) { + *modespec = '\0'; + if (strchr("78", *++modespec) == NULL) { + gpsd_report(LOG_ERROR, "No support for that word lengths.\n"); + status = 1; + } + parity = *++modespec; + if (strchr("NOE", parity) == NULL) { + gpsd_report(LOG_ERROR, "What parity is '%c'?\n", parity); + status = 1; + } + stopbits = *++modespec; + if (strchr("12", stopbits) == NULL) { + gpsd_report(LOG_ERROR, "Stop bits must be 1 or 2.\n"); + status = 1; + } + } + if (status == 0) + (void)gps_query(&gpsdata, + "?DEVICE={\"path\":\"%s\",\"bps\":%s,\"parity\":\"%c\",\"stopbits\":%c}\r\n", + device, speed, parity, stopbits); + } + if (atoi(speed) != (int)gpsdata.dev.baudrate) { + gpsd_report(LOG_ERROR, "%s driver won't support %s%c%c\n", + gpsdata.dev.path, + speed, parity, stopbits); + status = 1; + } else + gpsd_report(LOG_PROG, "%s change to %s%c%c succeeded\n", + gpsdata.dev.path, + speed, parity, stopbits); + } + if (rate != NULL) { + (void)gps_query(&gpsdata, + "?DEVICE={\"path\":\"%s\",\"cycle\":%s}\n", + device, rate); + } +#endif /* ALLOW_RECONFIGURE */ + (void)gps_close(&gpsdata); + exit(status); +#ifdef ALLOW_RECONFIGURE + } else if (reset) { + /* hard reset will go through lower-level operations */ + const int speeds[] = {2400, 4800, 9600, 19200, 38400, 57600, 115200}; + static struct gps_context_t context; /* start it zeroed */ + static struct gps_device_t session; /* zero this too */ + int i; + + if (device == NULL || forcetype == NULL) { + gpsd_report(LOG_ERROR, "device and type must be specified for the reset operation.\n"); + exit(1); + } + + /*@ -mustfreeonly -immediatetrans @*/ + session.context = &context; + gpsd_tty_init(&session); + (void)strlcpy(session.gpsdata.dev.path, device, sizeof(session.gpsdata.dev.path)); + session.device_type = forcetype; + (void)gpsd_open(&session); + (void)gpsd_set_raw(&session); + (void)session.device_type->speed_switcher(&session, 4800, 'N', 1); + (void)tcdrain(session.gpsdata.gps_fd); + for(i = 0; i < (int)(sizeof(speeds) / sizeof(speeds[0])); i++) { + (void)gpsd_set_speed(&session, speeds[i], 'N', 1); + (void)session.device_type->speed_switcher(&session, 4800, 'N', 1); + (void)tcdrain(session.gpsdata.gps_fd); + } + gpsd_set_speed(&session, 4800, 'N', 1); + for (i = 0; i < 3; i++) + if (session.device_type->mode_switcher) + session.device_type->mode_switcher(&session, MODE_NMEA); + gpsd_wrap(&session); + exit(0); + /*@ +mustfreeonly +immediatetrans @*/ +#endif /* ALLOW_RECONFIGURE */ + } else { + /* access to the daemon failed, use the low-level facilities */ + static struct gps_context_t context; /* start it zeroed */ + static struct gps_device_t session; /* zero this too */ + /*@ -mustfreeonly -immediatetrans @*/ + session.context = &context; /* in case gps_init isn't called */ + + if (echo) + context.readonly = true; + + (void) alarm(timeout); + (void) signal(SIGALRM, onsig); + /* + * Unless the user has forced a type and only wants to see the + * string (not send it) we now need to try to open the device + * and find out what is actually there. + */ + if (!(forcetype != NULL && echo)) { + int seq; + + if (device == NULL) { + gpsd_report(LOG_ERROR, "device must be specified for low-level access.\n"); + exit(1); + } + gpsd_init(&session, &context, device); + gpsd_report(LOG_PROG, "initialization passed.\n"); + if (gpsd_activate(&session) == -1) { + gpsd_report(LOG_ERROR, + "activation of device %s failed, errno=%d\n", + device, errno); + exit(2); + } + /* hunt for packet type and serial parameters */ + for (seq = 0; session.device_type == NULL; seq++) { + if (get_packet(&session) == ERROR_SET) { + gpsd_report(LOG_ERROR, + "autodetection failed.\n"); + exit(2); + } else { + gpsd_report(LOG_IO, + "autodetection after %d reads.\n", seq); + (void) alarm(0); + break; + } + } + gpsd_report(LOG_PROG, "%s looks like a %s at %d.\n", + device, gpsd_id(&session), session.gpsdata.dev.baudrate); + + if (forcetype!=NULL && strcmp("Generic NMEA", session.device_type->type_name) !=0 && strcmp(forcetype->type_name, session.device_type->type_name)!=0) { + gpsd_report(LOG_ERROR, "'%s' doesn't match non-generic type '%s' of selected device.\n", forcetype->type_name, session.device_type->type_name); + } + + /* + * If we've identified this as an NMEA device, we have to eat + * packets for a while to see if one of our probes elicits an + * ID response telling us that it's really a SiRF or + * something. If so, the libgpsd(3) layer will automatically + * redispatch to the correct driver type. + */ + if (strcmp(session.device_type->type_name, "Generic NMEA") == 0) { + int dummy; + for (dummy = 0; dummy < REDIRECT_SNIFF; dummy++) { + if ((get_packet(&session) & DEVICEID_SET)!=0) + break; + } + } + gpsd_report(LOG_SHOUT, "%s identified as a %s at %d.\n", + device, gpsd_id(&session), session.gpsdata.dev.baudrate); + } + + /* if no control operation was specified, we're done */ + if (speed==NULL && !to_nmea && !to_binary && control==NULL) + exit(0); + + /* maybe user wants to see the packet rather than send it */ + if (echo) + session.gpsdata.gps_fd = fileno(stdout); + + /* control op specified; maybe we forced the type */ + if (forcetype != NULL) + (void)gpsd_switch_driver(&session, forcetype->type_name); + + /* now perform the actual control function */ + status = 0; +#ifdef ALLOW_RECONFIGURE + /*@ -nullderef @*/ + if (to_nmea || to_binary) { + if (session.device_type->mode_switcher == NULL) { + gpsd_report(LOG_SHOUT, + "%s devices have no mode switch.\n", + session.device_type->type_name); + status = 1; + } else { + int target_mode = to_nmea ? MODE_NMEA : MODE_BINARY; + int target_type = to_nmea ? NMEA_PACKET : session.device_type->packet_type; + + gpsd_report(LOG_SHOUT, + "switching to mode %s.\n", + to_nmea ? "NMEA" : "BINARY"); + session.device_type->mode_switcher(&session, target_mode); + + + /* + * Hunt for packet type again (mode might have + * changed). We've found by experiment that you can't + * close the connection to the device after a mode + * change but before you see a packet of the right + * type come back from it - otherwise you can hit a + * timing window where the mode-change control message + * gets ignored or flushed. + */ + if (!echo) { + /* suppresses probing for subtypes */ + context.readonly = true; + (void)sleep(1); + (void) alarm(timeout); + for (;;) { + if (get_packet(&session) == ERROR_SET) { + continue; + } else if (session.packet.type == target_type) { + (void)alarm(0); + break; + } + } + context.readonly = false; + } + /*@ -nullpass @*/ + gpsd_report(LOG_SHOUT, "after mode change, %s looks like a %s at %d.\n", + device, gpsd_id(&session), session.gpsdata.dev.baudrate); + /*@ +nullpass @*/ + } + } + if (speed) { + char parity = echo ? 'N': session.gpsdata.dev.parity; + int stopbits = echo ? 1 : session.gpsdata.dev.stopbits; + char *modespec; + + modespec = strchr(speed, ':'); + /*@ +charint @*/ + status = 0; + if (modespec!=NULL) { + *modespec = '\0'; + if (strchr("78", *++modespec) == NULL) { + gpsd_report(LOG_ERROR, "No support for that word lengths.\n"); + status = 1; + } + parity = *++modespec; + if (strchr("NOE", parity) == NULL) { + gpsd_report(LOG_ERROR, "What parity is '%c'?\n", parity); + status = 1; + } + stopbits = *++modespec; + if (strchr("12", parity) == NULL) { + gpsd_report(LOG_ERROR, "Stop bits must be 1 or 2.\n"); + status = 1; + } + stopbits = (int)(stopbits-'0'); + } + if (status == 0) { + if (session.device_type->speed_switcher == NULL) { + gpsd_report(LOG_ERROR, + "%s devices have no speed switch.\n", + session.device_type->type_name); + status = 1; + } + else if (session.device_type->speed_switcher(&session, + (speed_t)atoi(speed), + parity, + stopbits)) { + /* + * See the 'deep black magic' comment in + * gpsd.c:set_serial() Probably not needed here, + * but it can't hurt. + */ + (void)tcdrain(session.gpsdata.gps_fd); + (void)usleep(50000); + gpsd_report(LOG_PROG, "%s change to %s%c%d succeeded\n", + session.gpsdata.dev.path, + speed, parity, stopbits); + } else { + gpsd_report(LOG_ERROR, "%s driver won't support %s%c%d.\n", + session.gpsdata.dev.path, + speed, parity, stopbits); + status = 1; + } + } + } + if (rate) { + bool write_enable = context.readonly; + context.readonly = false; + if (session.device_type->rate_switcher == NULL) { + gpsd_report(LOG_ERROR, + "%s devices have no rate switcher.\n", + session.device_type->type_name); + status = 1; + } else { + double rate_dbl = strtod(rate, NULL); + + if (!session.device_type->rate_switcher(&session, rate_dbl)) { + gpsd_report(LOG_ERROR, "rate switch failed.\n"); + status = 1; + } + } + context.readonly = write_enable; + } +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + /*@ -compdef @*/ + if (control) { + bool write_enable = context.readonly; + context.readonly = false; + if (session.device_type->control_send == NULL) { + gpsd_report(LOG_ERROR, + "%s devices have no control sender.\n", + session.device_type->type_name); + status = 1; + } else { + if (session.device_type->control_send(&session, + cooked, + (size_t)cooklen) == -1) { + gpsd_report(LOG_ERROR, "control transmission failed.\n"); + status = 1; + } + } + context.readonly = write_enable; + } + /*@ +compdef @*/ +#endif /* ALLOW_CONTROLSEND */ + + if (forcetype == NULL || !echo) { + /* + * Give the device time to settle before closing it. Alas, this is + * voodoo programming; we don't know it will have any effect, but + * GPSes are notoriously prone to timing-dependent errors. + */ + (void)usleep(300000); + + gpsd_wrap(&session); + } + exit(status); + /*@ +nullderef @*/ + /*@ +mustfreeonly +immediatetrans @*/ + } +} diff --git a/gpsctl.xml b/gpsctl.xml new file mode 100644 index 0000000..da74e62 --- /dev/null +++ b/gpsctl.xml @@ -0,0 +1,261 @@ + + + + +29 Oct 2006 + +gpsctl +1 +The GPSD Project +GPSD Documentation + + +gpsctl +control the modes of a GPS + + + + + gpsctl + -h + + -b + -n + + -x control + -e + -f + -l + -s speed + -t devicetype + -D debuglevel + -V + serial-port + + + +DESCRIPTION + +gpsctl can switch a dual-mode GPS +between NMEA and vendor-binary modes. It can also be used to set the +device baudrate. Note: Not all devices have these capabilities. + +If you have only one GPS attached to your machine, and gpsd is +running, it is not necessary to specify the device; +gpsctl does its work through +gpsd, which will locate it for you. + +When gpsd is not running, the device +specification is required, and you will almost certainly need to be +running as root in order to have write access to the device. + +The program accepts the following options: + + + +-b + +Put the GPS into binary mode. After the GPS resets itself, autobaud to +the new speed. + + + + +-c + +Change the GPS's cycle time. Units are seconds. Note, most +GPSes have a fixed cycle time of 1 second. + + + + +-e + +Generate the packet from any other arguments specified and ship +it to standard output instead of the device. This switch can be used +with the option without specifying a device. Note: +the packet data for a binary prototype will be raw, not ASCII-ized in +any way. + + + + +-f + +Force low-level access (not through the daemon). + + + + +-l + +List a table showing which option switches can be applied +to which device types, and exit. + + + + +-n + +Put GPS into NMEA mode. After the GPS resets itself autobaud to +its new speed. + + + + +-s + +Set the baud rate at which the GPS emits packets. + +Use this option with caution. On USB and Bluetooth GPSes it is +also possible for serial mode setting to fail either because the +serial adaptor chip does not support non-8N1 modes or because the +device firmware does not properly synchronize the serrial adaptor chip +with the UART on the GPS chipset whjen the speed changes. These +failures can hang your device, possibly requiring a GPS power cycle or (in +extreme cases) physically disconnecting the NVRAM backup battery. + + + + +-t + +Force the device type. + + + + +-x + +Send a specified control string to the GPS; +gpsctl will provide packet headers and +trailers and checksum as appropriate for binary packet types, and +whatever checksum and trailer is required for text packet types. (You +must include the leading $ for NMEA packets.) When sending to a UBX +device, the first two bytes of the string supplied will become the +message class and type, and the remainder the payload. When sending to +a Navcom NCT or Trimble TSIP device, the first byte is interpreted as +the command ID and the rest as payload. When sending to a Zodiac +device, the first two bytes are used as a message ID of type +little-endian short, and the remainder as payload in byte pairs +interpreted as little-endian short. C-style backslash escapes in the +string, notably \xNN for hex, will be interpreted; additionally, \e +will be replaced with ESC. This switch implies +. + + + + +-T + +Change the sampling timeout. Defaults to 4 seconds, which +should always be sufficient to get a packet from a device emitting at +the normal rate of 1 per second. + + + + +-h + +Display program usage and exit. + + + + +-D + +Set level of debug messages. + + + + +-V + +Display program version and exit. + + + + +The argument of the forcing option. , should be a +string which should be contained in exactly one of the known driver +names; for a list, do gpsctl -l. + +Forcing the device type behaves somewhat differently depending +on whether this tool is going through the daemon or not. In high-level +mode, if the device that daemon selects for you doesn't match the +driver you specified, gpsctl exits with +a warning. (This may be useful in scripts.) + +In low-level mode, if the device identifies as a Generic NMEA, +use the selected driver instead. This will be useful if you have a +GPS device of known type that is in NMEA mode and not responding to +probes. (This option was originally implemented for talking to +SiRFStar I chips, which don't respond to the normal SiRF ID +probe.) + +If no options are given, the program will display a message +identifying the GPS type of the selected device and exit. + +Reset (-r) operations must stand alone; others can be combined. +Multiple opations will be executed in tis order: mode changes (-b and +-n) first, speed changes (-s) second, and control-string sends (-c) +last. + + + +EXAMPLES + + + +gpsctl /dev/ttyUSB0 + +Attempt to identify the device on USB serial device 0. Time out +after the default number of seconds. Adding the will +force low-level access and suppress the normal complaint when this +tool can't find a GPSD to work through. + + + + +gpsctl -f -n -s 9600 /dev/ttyUSB0 + +Use low-level operations (not going through a gpsd instance) to +switch a GPS to NMEA mode at 9600bps. The tool will identify the +GPS type itself. + + + + + + +BUGS + +SiRF GPSes can only be identified by the success of an attempt +to flip them into SiRF binary mode. Thus, the process of probing one of +these running in NMEA will change its behavior. + + + +SEE ALSO + +gpsd8, +gps1, +libgps3, +libgpsd3, +gpsprof1, +gpsfake1. + + + +AUTHOR + +Eric S. Raymond esr@thyrsus.com. There is a +project page for gpsd here. + + diff --git a/gpsd.c b/gpsd.c new file mode 100644 index 0000000..4d09f52 --- /dev/null +++ b/gpsd.c @@ -0,0 +1,2070 @@ +/* + * This is the main sequence of the gpsd daemon. The IO dispatcher, main + * select loop, and user command handling lives here. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include "gpsd_config.h" +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#ifdef HAVE_SYSLOG_H +#include +#endif /* HAVE_SYSLOG_H */ +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#ifdef HAVE_SYS_SOCKET_H +#include +#else +#define AF_UNSPEC 0 +#endif /* HAVE_SYS_SOCKET_H */ +#ifdef HAVE_SYS_UN_H +#include +#endif /* HAVE_SYS_UN_H */ +#ifdef HAVE_NETINET_IN_H +#include +#endif /* HAVE_NETINET_IN_H */ +#ifdef HAVE_ARPA_INET_H +#include +#endif /* HAVE_ARPA_INET_H */ +#ifdef HAVE_NETDB_H +#include +#endif /* HAVE_NETDB_H */ +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#ifdef HAVE_PWD_H +#include +#endif /* HAVE_PWD_H */ +#ifdef HAVE_GRP_H +#include +#endif /* HAVE_GRP_H */ +#include +#include + +#if defined (HAVE_PATH_H) +#include +#else +#if !defined (_PATH_DEVNULL) +#define _PATH_DEVNULL "/dev/null" +#endif +#endif +#if defined (HAVE_SYS_SELECT_H) +#include +#endif +#if defined (HAVE_SYS_STAT_H) +#include +#endif +#if defined(HAVE_SYS_TIME_H) +#include +#endif +#ifdef HAVE_SETLOCALE +#include +#endif + +#ifdef DBUS_ENABLE +#include +#endif + +#include "gpsd.h" +#include "sockaddr.h" +#include "gps_json.h" +#include "timebase.h" +#include "revision.h" + +/* + * The name of a tty device from which to pick up whatever the local + * owning group for tty devices is. Used when we drop privileges. + */ +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#define PROTO_TTY "/dev/tty00" /* correct for *BSD */ +#else +#define PROTO_TTY "/dev/ttyS0" /* correct for Linux */ +#endif + +/* Name of (unprivileged) user to change to when we drop privileges. */ +#ifndef GPSD_USER +#define GPSD_USER "nobody" +#endif + +/* + * Timeout policy. We can't rely on clients closing connections + * correctly, so we need timeouts to tell us when it's OK to + * reclaim client fds. COMMAND_TIMEOUT fends off programs + * that open connections and just sit there, not issuing a WATCH or + * doing anything else that triggers a device assignment. Clients + * in watcher or raw mode that don't read their data will get dropped + * when throttled_write() fills up the outbound buffers and the + * NOREAD_TIMEOUT expires. + * + * RELEASE_TIMEOUT sets the amount of time we hold a device + * open after the last subscriber closes it; this is nonzero so a + * client that does open/query/close will have time to come back and + * do another single-shot query, if it wants to, before the device is + * actually closed. The reason this matters is because some Bluetooth + * GPSes not only shut down the GPS receiver on close to save battery + * power, they actually shut down the Bluetooth RF stage as well and + * only re-wake it periodically to see if an attempt to raise the + * device is in progress. The result is that if you close the device + * when it's powered up, a re-open can fail with EIO and needs to be + * tried repeatedly. Better to avoid this... + * + * DEVICE_REAWAKE says how long to wait before repolling after a zero-length + * read. It's there so we avoid spinning forever on an EOF condition. + */ +#define COMMAND_TIMEOUT 60*15 +#define NOREAD_TIMEOUT 60*3 +#define RELEASE_TIMEOUT 60 +#define DEVICE_REAWAKE 0.01 + +#define QLEN 5 + +/* + * If ntpshm is enabled, we renice the process to this priority level. + * For precise timekeeping increase priority. + */ +#define NICEVAL -10 + +/* Needed because 4.x versions of GCC are really annoying */ +#define ignore_return(funcall) assert(funcall != -23) + +/* IP version used by the program */ +/* AF_UNSPEC: all + * AF_INET: IPv4 only + * AF_INET6: IPv6 only + */ +#ifdef IPV6_ENABLE +static const int af = AF_UNSPEC; +#else +static const int af = AF_INET; +#endif + +#define AFCOUNT 2 + +static fd_set all_fds; +static int maxfd; +static int debuglevel; +static bool in_background = false; +static bool listen_global = false; +static bool nowait = false; +static jmp_buf restartbuf; + +/* *INDENT-OFF* */ +/*@ -initallelements -nullassign -nullderef @*/ +struct gps_context_t context = { + .valid = 0, + .readonly = false, + .sentdgps = false, + .netgnss_service = netgnss_none, + .fixcnt = 0, + .dsock = -1, + .netgnss_privdata = NULL, + .rtcmbytes = 0, + .rtcmbuf = {'\0'}, + .rtcmtime = 0, + .leap_seconds = LEAP_SECONDS, + .gps_week = 0, + .gps_tow = 0, + .century = CENTURY_BASE, +#ifdef NTPSHM_ENABLE + .enable_ntpshm = false, + .shmTime = {0}, + .shmTimeInuse = {0}, +# ifdef PPS_ENABLE + .shmTimePPS = false, +# endif /* PPS_ENABLE */ +#endif /* NTPSHM_ENABLE */ +}; +/*@ +initallelements +nullassign +nullderef @*/ +/* *INDENT-ON* */ + +static volatile sig_atomic_t signalled; + +static void onsig(int sig) +{ + /* just set a variable, and deal with it in the main loop */ + signalled = (sig_atomic_t) sig; +} + +static int daemonize(void) +{ + int fd; + pid_t pid; + + /*@ -type @*//* weirdly, splint 3.1.2 is confused by fork() */ + switch (pid = fork()) { + case -1: + return -1; + case 0: /* child side */ + break; + default: /* parent side */ + exit(0); + } + /*@ +type @*/ + + if (setsid() == -1) + return -1; + if (chdir("/") == -1) + return -1; + /*@ -nullpass @*/ + if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > 2) + (void)close(fd); + } + /*@ +nullpass @*/ + in_background = true; + return 0; +} + +#if defined(PPS_ENABLE) +static pthread_mutex_t report_mutex; +#endif /* PPS_ENABLE */ + +static void visibilize(/*@out@*/char *buf2, size_t len, const char *buf) +{ + const char *sp; + + buf2[0] = '\0'; + for (sp = buf; *sp != '\0' && strlen(buf2)+4 < len; sp++) + if (isprint(*sp) || (sp[0] == '\n' && sp[1] == '\0') || (sp[0] == '\r' && sp[2] == '\0')) + (void)snprintf(buf2 + strlen(buf2), 2, "%c", *sp); + else + (void)snprintf(buf2 + strlen(buf2), 6, "\\x%02x", + (unsigned)*sp); +} + +void gpsd_report(int errlevel, const char *fmt, ...) +/* assemble command in printf(3) style, use stderr or syslog */ +{ +#ifndef SQUELCH_ENABLE + if (errlevel <= debuglevel) { + char buf[BUFSIZ], buf2[BUFSIZ]; + va_list ap; + +#if defined(PPS_ENABLE) + /*@ -unrecog (splint has no pthread declarations as yet) @*/ + (void)pthread_mutex_lock(&report_mutex); + /* +unrecog */ +#endif /* PPS_ENABLE */ + (void)strlcpy(buf, "gpsd: ", BUFSIZ); + va_start(ap, fmt); + (void)vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, + ap); + va_end(ap); + + visibilize(buf2, sizeof(buf2), buf); + + if (in_background) + syslog((errlevel == 0) ? LOG_ERR : LOG_NOTICE, "%s", buf2); + else + (void)fputs(buf2, stderr); +#if defined(PPS_ENABLE) + /*@ -unrecog (splint has no pthread declarations as yet) @*/ + (void)pthread_mutex_unlock(&report_mutex); + /* +unrecog */ +#endif /* PPS_ENABLE */ + } +#endif /* !SQUELCH_ENABLE */ +} + +static void usage(void) +{ + const struct gps_type_t **dp; + + (void)printf("usage: gpsd [-b] [-n] [-N] [-D n] [-F sockfile] [-G] [-P pidfile] [-S port] [-h] device...\n\ + Options include: \n\ + -b = bluetooth-safe: open data sources read-only\n\ + -n = don't wait for client connects to poll GPS\n\ + -N = don't go into background\n\ + -F sockfile = specify control socket location\n\ + -G = make gpsd listen on INADDR_ANY\n\ + -P pidfile = set file to record process ID \n\ + -D integer (default 0) = set debug level \n\ + -S integer (default %s) = set port for daemon \n\ + -h = help message \n\ + -V = emit version and exit.\n\ +A device may be a local serial device for GPS input, or a URL of the form:\n\ + {dgpsip|ntrip}://[user:passwd@]host[:port][/stream]\n\ + gpsd://host[:port][/device][?protocol]\n\ +in which case it specifies an input source for GPSD, DGPS or ntrip data.\n\ +\n\ +The following driver types are compiled into this gpsd instance:\n", + DEFAULT_GPSD_PORT); + for (dp = gpsd_drivers; *dp; dp++) { + (void)printf(" %s\n", (*dp)->type_name); + } +} + +static int passivesock_af(int af, char *service, char *tcp_or_udp, int qlen) +/* bind a passive command socket for the daemon */ +{ + /* + * af = address family, + * service = IANA protocol name or number. + * tcp_or_udp = TCP or UDP + * qlen = maximum wait-queue length for connections + */ + struct servent *pse; + struct protoent *ppe; /* splint has a bug here */ + sockaddr_t sat; + int sin_len = 0; + int s = -1, type, proto, one = 1; + in_port_t port; + char *af_str = ""; + + if ((pse = getservbyname(service, tcp_or_udp))) + port = ntohs((in_port_t) pse->s_port); + else if ((port = (in_port_t) atoi(service)) == 0) { + gpsd_report(LOG_ERROR, "can't get \"%s\" service entry.\n", service); + return -1; + } + ppe = getprotobyname(tcp_or_udp); + if (strcmp(tcp_or_udp, "udp") == 0) { + type = SOCK_DGRAM; + /*@i@*/ proto = (ppe) ? ppe->p_proto : IPPROTO_UDP; + } else { + type = SOCK_STREAM; + /*@i@*/ proto = (ppe) ? ppe->p_proto : IPPROTO_TCP; + } + + /*@ -mustfreefresh +matchanyintegral @*/ + switch (af) { + case AF_INET: + sin_len = sizeof(sat.sa_in); + + memset((char *)&sat.sa_in, 0, sin_len); + sat.sa_in.sin_family = (sa_family_t) AF_INET; + if (listen_global) + sat.sa_in.sin_addr.s_addr = htonl(INADDR_ANY); + else + sat.sa_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sat.sa_in.sin_port = htons(port); + + af_str = "IPv4"; + /* see PF_INET6 case below */ + s = socket(PF_INET, type, proto); + break; +#ifdef IPV6_ENABLE + case AF_INET6: + sin_len = sizeof(sat.sa_in6); + + memset((char *)&sat.sa_in6, 0, sin_len); + sat.sa_in6.sin6_family = (sa_family_t) AF_INET6; + if (listen_global) { + /* BAD: sat.sa_in6.sin6_addr = in6addr_any; + * the simple assignment will not work (except as an initializer) + * because sin6_addr is an array not a simple type + * we could do something like this: + * memcpy(sat.sa_in6.sin6_addr, in6addr_any, sizeof(sin6_addr)); + * BUT, all zeros is IPv6 wildcard, and we just zeroed the array + * so really nothing to do here + */ + } else + sat.sa_in6.sin6_addr = in6addr_loopback; + sat.sa_in6.sin6_port = htons(port); + + /* + * Traditionally BSD uses "communication domains", named by + * constants starting with PF_ as the first argument for + * select. In practice PF_INET has the same value as AF_INET + * (on BSD and Linux, and probably everywhere else). POSIX + * leaves much of this unspecified, but requires that AF_INET + * be recognized. We follow tradition here. + */ + af_str = "IPv6"; + s = socket(PF_INET6, type, proto); + break; +#endif + default: + gpsd_report(LOG_ERROR, "unhandled address family %d\n", af); + return -1; + } + gpsd_report(LOG_IO, "opening %s socket\n", af_str); + + if (s == -1) { + gpsd_report(LOG_ERROR, "can't create %s socket\n", af_str); + return -1; + } + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&one, + (int)sizeof(one)) == -1) { + gpsd_report(LOG_ERROR, "Error: SETSOCKOPT SO_REUSEADDR\n"); + return -1; + } + if (bind(s, &sat.sa, sin_len) < 0) { + gpsd_report(LOG_ERROR, "can't bind to %s port %s, %s\n", af_str, + service, strerror(errno)); + if (errno == EADDRINUSE) { + gpsd_report(LOG_ERROR, "maybe gpsd is already running!\n"); + } + return -1; + } + if (type == SOCK_STREAM && listen(s, qlen) == -1) { + gpsd_report(LOG_ERROR, "can't listen on port %s\n", service); + return -1; + } + + gpsd_report(LOG_SPIN, "passivesock_af() -> %d\n", s); + return s; + /*@ +mustfreefresh -matchanyintegral @*/ +} + +/* *INDENT-OFF* */ +static int passivesocks(char *service, char *tcp_or_udp, + int qlen, /*@out@*/int socks[]) +{ + int numsocks = AFCOUNT; + int i; + + for (i = 0; i < AFCOUNT; i++) + socks[i] = -1; + + if (AF_UNSPEC == af || (AF_INET == af)) + socks[0] = passivesock_af(AF_INET, service, tcp_or_udp, qlen); + + if (AF_UNSPEC == af || (AF_INET6 == af)) + socks[1] = passivesock_af(AF_INET6, service, tcp_or_udp, qlen); + + for (i = 0; i < AFCOUNT; i++) + if (socks[i] < 0) + numsocks--; + + /* Return the number of succesfully opened sockets + * The failed ones are identified by negative values */ + return numsocks; +} +/* *INDENT-ON* */ + +static int filesock(char *filename) +{ + struct sockaddr_un addr; + int sock; + + /*@ -mayaliasunique -usedef @*/ + if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + gpsd_report(LOG_ERROR, "Can't create device-control socket\n"); + return -1; + } + (void)strlcpy(addr.sun_path, filename, 104); /* from sys/un.h */ + addr.sun_family = AF_UNIX; + (void)bind(sock, (struct sockaddr *)&addr, (int)sizeof(addr)); + if (listen(sock, QLEN) == -1) { + gpsd_report(LOG_ERROR, "can't listen on local socket %s\n", filename); + return -1; + } + /*@ +mayaliasunique +usedef @*/ + return sock; +} + +struct subscriber_t +{ + int fd; /* client file descriptor. -1 if unused */ + double active; /* when subscriber last polled for data */ + struct policy_t policy; /* configurable bits */ +}; + +/* + * This hackery is intended to support SBCs that are resource-limited + * and only need to support one or a few devices each. It avoids the + * space overhead of allocating thousands of unused device structures. + * This array fills from the bottom, so as an extreme case you could + * reduce LIMITED_MAX_DEVICES to 1. + */ +#ifdef LIMITED_MAX_DEVICES +#define MAXDEVICES LIMITED_MAX_DEVICES +#else +/* we used to make this FD_SETSIZE, but that cost 14MB of wasted core! */ +#define MAXDEVICES 4 +#endif + +#ifdef LIMITED_MAX_CLIENTS +#define MAXSUBSCRIBERS LIMITED_MAX_CLIENTS +#else +/* subscriber structure is small enough that there's no need to limit this */ +#define MAXSUBSCRIBERS FD_SETSIZE +#endif +#define sub_index(s) (int)((s) - subscribers) +#define allocated_device(devp) ((devp)->gpsdata.dev.path[0] != '\0') +#define free_device(devp) (devp)->gpsdata.dev.path[0] = '\0' +#define initialized_device(devp) ((devp)->context != NULL) +#define subscribed(sub, devp) (sub->policy.devpath[0]=='\0' || strcmp(sub->policy.devpath, devp->gpsdata.dev.path)==0) + +struct gps_device_t devices[MAXDEVICES]; +struct subscriber_t subscribers[MAXSUBSCRIBERS]; /* indexed by client file descriptor */ + +static void adjust_max_fd(int fd, bool on) +/* track the largest fd currently in use */ +{ + if (on) { + if (fd > maxfd) + maxfd = fd; + } +#if !defined(LIMITED_MAX_DEVICES) && !defined(LIMITED_MAX_CLIENT_FD) + /* + * I suspect there could be some weird interactions here if + * either of these were set lower than FD_SETSIZE. We'll avoid + * potential bugs by not scavenging in this case at all -- should + * be OK, as the use case for limiting is SBCs where the limits + * will be very low (typically 1) and the maximum size of fd + * set to scan through correspondingly small. + */ + else { + if (fd == maxfd) { + int tfd; + + for (maxfd = tfd = 0; tfd < FD_SETSIZE; tfd++) + if (FD_ISSET(tfd, &all_fds)) + maxfd = tfd; + } + } +#endif /* !defined(LIMITED_MAX_DEVICES) && !defined(LIMITED_MAX_CLIENT_FD) */ +} + +#define UNALLOCATED_FD -1 + +static /*@null@*//*@observer@ */ struct subscriber_t *allocate_client(void) +/* return the address of a subscriber structure allocated for a new session */ +{ + int si; + +#if UNALLOCATED_FD == 0 +#error client allocation code will fail horribly +#endif + for (si = 0; si < NITEMS(subscribers); si++) { + if (subscribers[si].fd == UNALLOCATED_FD) { + subscribers[si].fd = 0; /* mark subscriber as allocated */ + return &subscribers[si]; + } + } + return NULL; +} + +static void detach_client(struct subscriber_t *sub) +/* detach a client and terminate the session */ +{ + char *c_ip; + if (sub->fd == UNALLOCATED_FD) + return; + c_ip = netlib_sock2ip(sub->fd); + (void)shutdown(sub->fd, SHUT_RDWR); + gpsd_report(LOG_SPIN, "close(%d) in detach_client()\n", sub->fd); + (void)close(sub->fd); + gpsd_report(LOG_INF, "detaching %s (sub %d, fd %d) in detach_client\n", + c_ip, sub_index(sub), sub->fd); + FD_CLR(sub->fd, &all_fds); + adjust_max_fd(sub->fd, false); + sub->active = 0; + sub->policy.watcher = false; + sub->policy.nmea = false; + sub->policy.raw = 0; + sub->policy.scaled = false; + sub->policy.timing = false; + sub->policy.devpath[0] = '\0'; + sub->fd = UNALLOCATED_FD; + /*@+mustfreeonly@*/ +} + +static ssize_t throttled_write(struct subscriber_t *sub, char *buf, + size_t len) +/* write to client -- throttle if it's gone or we're close to buffer overrun */ +{ + ssize_t status; + + if (debuglevel >= 3) { + if (isprint(buf[0])) + gpsd_report(LOG_IO, "=> client(%d): %s\n", sub_index(sub), buf); + else { + char *cp, buf2[MAX_PACKET_LENGTH * 3]; + buf2[0] = '\0'; + for (cp = buf; cp < buf + len; cp++) + (void)snprintf(buf2 + strlen(buf2), + sizeof(buf2) - strlen(buf2), + "%02x", (unsigned int)(*cp & 0xff)); + gpsd_report(LOG_IO, "=> client(%d): =%s\n", sub_index(sub), + buf2); + } + } + + status = send(sub->fd, buf, len, 0); + if (status == (ssize_t) len) + return status; + else if (status > -1) { + gpsd_report(LOG_INF, "short write disconnecting client(%d)\n", + sub_index(sub)); + detach_client(sub); + return 0; + } else if (errno == EAGAIN || errno == EINTR) + return 0; /* no data written, and errno says to retry */ + else if (errno == EBADF) + gpsd_report(LOG_WARN, "client(%d) has vanished.\n", sub_index(sub)); + else if (errno == EWOULDBLOCK + && timestamp() - sub->active > NOREAD_TIMEOUT) + gpsd_report(LOG_INF, "client(%d) timed out.\n", sub_index(sub)); + else + gpsd_report(LOG_INF, "client(%d) write: %s\n", sub_index(sub), + strerror(errno)); + detach_client(sub); + return status; +} + +static void notify_watchers(struct gps_device_t *device, char *sentence, ...) +/* notify all clients watching a given device of an event */ +{ + va_list ap; + char buf[BUFSIZ]; + struct subscriber_t *sub; + + va_start(ap, sentence); + (void)vsnprintf(buf, sizeof(buf), sentence, ap); + va_end(ap); + + for (sub = subscribers; sub < subscribers + MAXSUBSCRIBERS; sub++) + if (sub->active != 0 && subscribed(sub, device)) + (void)throttled_write(sub, buf, strlen(buf)); +} + +static void deactivate_device(struct gps_device_t *device) +/* deactivate device, but leave it in the pool (do not free it) */ +{ + notify_watchers(device, + "{\"class\":\"DEVICE\",\"path\":\"%s\",\"activated\":0}\r\n", + device->gpsdata.dev.path); + if (device->gpsdata.gps_fd != -1) { + FD_CLR(device->gpsdata.gps_fd, &all_fds); + adjust_max_fd(device->gpsdata.gps_fd, false); + gpsd_deactivate(device); + } +} + +/* *INDENT-OFF* */ +/*@ -globstate @*/ +/*@null@*//*@observer@*/ static struct gps_device_t *find_device(char + *device_name) +/* find the device block for an existing device name */ +{ + struct gps_device_t *devp; + + for (devp = devices; devp < devices + MAXDEVICES; devp++) + if (allocated_device(devp) + && strcmp(devp->gpsdata.dev.path, device_name) == 0) + return devp; + return NULL; +} +/* *INDENT-ON* */ + +/*@ -nullret @*/ +/*@ -statictrans @*/ +static bool open_device(char *device_name) +/* open and initialize a new device block */ +{ + struct gps_device_t *devp; + + for (devp = devices; devp < devices + MAXDEVICES; devp++) + if (!allocated_device(devp) + || (strcmp(devp->gpsdata.dev.path, device_name) == 0 + && !initialized_device(devp))) { + goto found; + } + return false; + found: + gpsd_init(devp, &context, device_name); + if (gpsd_activate(devp) < 0) + return false; + FD_SET(devp->gpsdata.gps_fd, &all_fds); + adjust_max_fd(devp->gpsdata.gps_fd, true); + return true; +} + +static bool add_device(char *device_name) +/* add a device to the pool; open it right away if in nowait mode */ +{ + if (nowait) + return open_device(device_name); + else { + struct gps_device_t *devp; + /* stash devicename away for probing when the first client connects */ + for (devp = devices; devp < devices + MAXDEVICES; devp++) + if (!allocated_device(devp)) { + gpsd_init(devp, &context, device_name); + gpsd_report(LOG_INF, "stashing device %s at slot %d\n", + device_name, (int)(devp - devices)); + devp->gpsdata.gps_fd = -1; + notify_watchers(devp, + "{\"class\":\"DEVICE\",\"path\":\"%s\",\"activated\":%ld}\r\n", + devp->gpsdata.dev.path, timestamp()); + return true; + } + return false; + } +} + +/*@ +nullret @*/ +/*@ +statictrans @*/ +/*@ +globstate @*/ + +static bool awaken(struct gps_device_t *device) +/* awaken a device and notify all watchers*/ +{ + /* open that device */ + if (!initialized_device(device)) { + if (!open_device(device->gpsdata.dev.path)) { + gpsd_report(LOG_PROG, "%s: open failed\n", + device->gpsdata.dev.path); + free_device(device); + return false; + } + } + + if (device->gpsdata.gps_fd != -1) { + gpsd_report(LOG_PROG, + "device %d (fd=%d, path %s) already active.\n", + (int)(device - devices), + device->gpsdata.gps_fd, device->gpsdata.dev.path); + return true; + } else { + if (gpsd_activate(device) < 0) { + gpsd_report(LOG_ERROR, "%s: device activation failed.\n", + device->gpsdata.dev.path); + return false; + } else { + gpsd_report(LOG_RAW, + "flagging descriptor %d in assign_channel()\n", + device->gpsdata.gps_fd); + FD_SET(device->gpsdata.gps_fd, &all_fds); + adjust_max_fd(device->gpsdata.gps_fd, true); + return true; + } + } +} + +/*@ observer @*/ static char *snarfline(char *p, /*@out@*/ char **out) +/* copy the rest of the command line, before CR-LF */ +{ + char *q; + static char stash[BUFSIZ]; + + /*@ -temptrans -mayaliasunique @*/ + for (q = p; isprint(*p) && !isspace(*p) && /*@i@*/ (p - q < BUFSIZ - 1); + p++) + continue; + (void)memcpy(stash, q, (size_t) (p - q)); + stash[p - q] = '\0'; + *out = stash; + return p; + /*@ +temptrans +mayaliasunique @*/ +} + +#ifdef ALLOW_RECONFIGURE +static bool privileged_user(struct gps_device_t *device) +/* is this channel privileged to change a device's behavior? */ +{ + /* grant user privilege if he's the only one listening to the device */ + struct subscriber_t *sub; + int subcount = 0; + for (sub = subscribers; sub < subscribers + MAXSUBSCRIBERS; sub++) { + if (sub->active == 0) + continue; + else if (subscribed(sub, device)) + subcount++; + } + return subcount == 1; +} +#endif /* ALLOW_CONFIGURE */ + +static void handle_control(int sfd, char *buf) +/* handle privileged commands coming through the control socket */ +{ + char *p, *stash, *eq; + struct gps_device_t *devp; + + /*@ -sefparams @*/ + if (buf[0] == '-') { + p = snarfline(buf + 1, &stash); + gpsd_report(LOG_INF, "<= control(%d): removing %s\n", sfd, stash); + if ((devp = find_device(stash))) { + deactivate_device(devp); + free_device(devp); + ignore_return(write(sfd, "OK\n", 3)); + } else + ignore_return(write(sfd, "ERROR\n", 6)); + } else if (buf[0] == '+') { + p = snarfline(buf + 1, &stash); + if (find_device(stash)) { + gpsd_report(LOG_INF, "<= control(%d): %s already active \n", sfd, + stash); + ignore_return(write(sfd, "ERROR\n", 6)); + } else { + gpsd_report(LOG_INF, "<= control(%d): adding %s\n", sfd, stash); + if (add_device(stash)) + ignore_return(write(sfd, "OK\n", 3)); + else + ignore_return(write(sfd, "ERROR\n", 6)); + } + } else if (buf[0] == '!') { + p = snarfline(buf + 1, &stash); + eq = strchr(stash, '='); + if (eq == NULL) { + gpsd_report(LOG_WARN, "<= control(%d): ill-formed command \n", + sfd); + ignore_return(write(sfd, "ERROR\n", 6)); + } else { + *eq++ = '\0'; + if ((devp = find_device(stash))) { + gpsd_report(LOG_INF, "<= control(%d): writing to %s \n", sfd, + stash); + ignore_return(write(devp->gpsdata.gps_fd, eq, strlen(eq))); + ignore_return(write(sfd, "OK\n", 3)); + } else { + gpsd_report(LOG_INF, "<= control(%d): %s not active \n", sfd, + stash); + ignore_return(write(sfd, "ERROR\n", 6)); + } + } + } else if (buf[0] == '&') { + p = snarfline(buf + 1, &stash); + eq = strchr(stash, '='); + if (eq == NULL) { + gpsd_report(LOG_WARN, "<= control(%d): ill-formed command\n", + sfd); + ignore_return(write(sfd, "ERROR\n", 6)); + } else { + size_t len; + int st; + *eq++ = '\0'; + len = strlen(eq) + 5; + if ((devp = find_device(stash)) != NULL) { + /* NOTE: this destroys the original buffer contents */ + st = gpsd_hexpack(eq, eq, len); + if (st <= 0) { + gpsd_report(LOG_INF, + "<= control(%d): invalid hex string (error %d).\n", + sfd, st); + ignore_return(write(sfd, "ERROR\n", 6)); + } else { + gpsd_report(LOG_INF, + "<= control(%d): writing %d bytes fromhex(%s) to %s\n", + sfd, st, eq, stash); + ignore_return(write + (devp->gpsdata.gps_fd, eq, (size_t) st)); + ignore_return(write(sfd, "OK\n", 3)); + } + } else { + gpsd_report(LOG_INF, "<= control(%d): %s not active\n", sfd, + stash); + ignore_return(write(sfd, "ERROR\n", 6)); + } + } + } + /*@ +sefparams @*/ +} + +#ifdef ALLOW_RECONFIGURE +static void set_serial(struct gps_device_t *device, + speed_t speed, char *modestring) +/* set serial parameters for a device from a speed and modestring */ +{ + unsigned int stopbits = device->gpsdata.dev.stopbits; + char parity = device->gpsdata.dev.parity; + int wordsize = 8; + + if (strchr("78", *modestring) != NULL) { + while (isspace(*modestring)) + modestring++; + wordsize = (int)(*modestring++ - '0'); + if (strchr("NOE", *modestring) != NULL) { + parity = *modestring++; + while (isspace(*modestring)) + modestring++; + if (strchr("12", *modestring) != NULL) + stopbits = (unsigned int)(*modestring - '0'); + } + } + + gpsd_report(LOG_PROG, "set_serial(,%d,%s) %c%d\n", speed, modestring, + parity, stopbits); + /* no support for other word sizes yet */ + /* *INDENT-OFF* */ + if (wordsize == (int)(9 - stopbits) + && device->device_type->speed_switcher != NULL) { + if (device->device_type->speed_switcher(device, speed, parity, (int)stopbits)) { + /* + * Deep black magic is required here. We have to + * allow the control string time to register at the + * GPS before we do the baud rate switch, which + * effectively trashes the UART's buffer. + * + * This definitely fails below 40 milliseconds on a + * BU-303b. 50ms is also verified by Chris Kuethe on + * Pharos iGPS360 + GSW 2.3.1ES + prolific + * Rayming TN-200 + GSW 2.3.1 + ftdi + * Rayming TN-200 + GSW 2.3.2 + ftdi + * so it looks pretty solid. + * + * The minimum delay time is probably constant + * across any given type of UART. + */ + (void)tcdrain(device->gpsdata.gps_fd); + (void)usleep(50000); + gpsd_set_speed(device, speed, parity, stopbits); + } + } + /* *INDENT-ON* */ +} +#endif /* ALLOW_RECONFIGURE */ + +static void json_devicelist_dump(char *reply, size_t replylen) +{ + struct gps_device_t *devp; + (void)strlcpy(reply, "{\"class\":\"DEVICES\",\"devices\":[", replylen); + for (devp = devices; devp < devices + MAXDEVICES; devp++) + if (allocated_device(devp) + && strlen(reply) + strlen(devp->gpsdata.dev.path) + 3 < + replylen - 1) { + char *cp; + json_device_dump(devp, + reply + strlen(reply), replylen - strlen(reply)); + cp = reply + strlen(reply); + *--cp = '\0'; + *--cp = '\0'; + (void)strlcat(reply, ",", replylen); + } + + if (reply[strlen(reply) - 1] == ',') + reply[strlen(reply) - 1] = '\0'; + (void)strlcat(reply, "]}\r\n", replylen); +} + +static void rstrip(char *str) +/* strip trailing \r\n\t\SP from a string */ +{ + char *strend; + strend = str + strlen(str) - 1; + while (isspace(*strend)) { + *strend = '\0'; + --strend; + } +} + +static void handle_request(struct subscriber_t *sub, + const char *buf, const char **after, + char *reply, size_t replylen) +{ + struct gps_device_t *devp; + const char *end = NULL; + + /* + * There's a splint limitation that parameters can be declared + * @out@ or @null@ but not, apparently, both. This collides with + * the (admittedly tricky) way we use endptr. The workaround is to + * declare it @null@ and use -compdef around the JSON reader calls. + */ + /*@-compdef@*/ + /* + * See above... + */ + /*@-nullderef -nullpass@*/ + + if (strncmp(buf, "DEVICES;", 8) == 0) { + buf += 8; + json_devicelist_dump(reply, replylen); + } else if (strncmp(buf, "WATCH", 5) == 0 + && (buf[5] == ';' || buf[5] == '=')) { + buf += 5; + if (*buf == ';') { + ++buf; + } else { + int status = json_watch_read(buf + 1, &sub->policy, &end); + if (end == NULL) + buf += strlen(buf); + else { + if (*end == ';') + ++end; + buf = end; + } + if (status != 0) { + (void)snprintf(reply, replylen, + "{\"class\":\"ERROR\",\"message\":\"Invalid WATCH: %s\"}\r\n", + json_error_string(status)); + gpsd_report(LOG_ERROR, "ERROR response: %s\n", reply); + } else if (sub->policy.watcher) { + if (sub->policy.devpath[0] == '\0') { + /* awaken all devices */ + for (devp = devices; devp < devices + MAXDEVICES; devp++) + if (allocated_device(devp)) + (void)awaken(devp); + } else { + devp = find_device(sub->policy.devpath); + if (devp == NULL) { + (void)snprintf(reply, replylen, + "{\"class\":\"ERROR\",\"message\":\"Do nuch device as %s\"}\r\n", + sub->policy.devpath); + gpsd_report(LOG_ERROR, "ERROR response: %s\n", reply); + goto bailout; + } else if (!awaken(devp)) + (void)snprintf(reply, replylen, + "{\"class\":\"ERROR\",\"message\":\"Can't assign %s\"}\r\n", + sub->policy.devpath); + gpsd_report(LOG_ERROR, "ERROR response: %s\n", reply); + goto bailout; + } + } + } + /* display a device list and the user's policy */ + json_devicelist_dump(reply + strlen(reply), replylen - strlen(reply)); + json_watch_dump(&sub->policy, + reply + strlen(reply), replylen - strlen(reply)); + } else if (strncmp(buf, "DEVICE", 6) == 0 + && (buf[6] == ';' || buf[6] == '=')) { + struct devconfig_t devconf; + struct gps_device_t *device; + buf += 6; + devconf.path[0] = '\0'; /* initially, no device selection */ + if (*buf == ';') { + ++buf; + } else { +#ifdef ALLOW_RECONFIGURE + /* first, select a device to operate on */ + int status = json_device_read(buf + 1, &devconf, &end); + if (end == NULL) + buf += strlen(buf); + else { + if (*end == ';') + ++end; + buf = end; + } + device = NULL; + /*@-branchstate@*/ + if (status != 0) { + (void)snprintf(reply, replylen, + "{\"class\":\"ERROR\",\"message\":\"Invalid DEVICE: %s\"}\r\n", + json_error_string(status)); + gpsd_report(LOG_ERROR, "ERROR response: %s\n", reply); + goto bailout; + } else { + if (devconf.path[0] != '\0') { + /* user specified a path, try to assign it */ + if (!awaken(find_device(devconf.path))) { + (void)snprintf(reply, replylen, + "{\"class\":\"ERROR\",\"message\":\"Can't open %s.\"}\r\n", + devconf.path); + gpsd_report(LOG_ERROR, "ERROR response: %s\n", reply); + goto bailout; + } + } else { + /* no path specified */ + int devcount = 0; + for (devp = devices; devp < devices + MAXDEVICES; devp++) + if (allocated_device(devp)) { + device = devp; + devcount++; + } + if (devcount == 0) { + (void)strlcat(reply, + "{\"class\":\"ERROR\",\"message\":\"Can't perform DEVICE configuration, no devices attached.\"}\r\n", + replylen); + gpsd_report(LOG_ERROR, "ERROR response: %s\n", reply); + goto bailout; + } else if (devcount > 1) { + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "{\"class\":\"ERROR\",\"message\":\"No path specified in DEVICE, but multiple devices are attached.\"}\r\n"); + gpsd_report(LOG_ERROR, "ERROR response: %s\n", reply); + goto bailout; + } + /* we should have exactly one device now */ + } + if (device == NULL) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "{\"class\":\"ERROR\",\"message\":\"Channel has no device (possible internal error).\"}\r\n"); + else if (!privileged_user(device)) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "{\"class\":\"ERROR\",\"message\":\"Multiple subscribers, cannot change control bits on %s.\"}\r\n", + device->gpsdata.dev.path); + else if (device->device_type == NULL) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "{\"class\":\"ERROR\",\"message\":\"Type of %s is unknown.\"}\r\n", + device->gpsdata.dev.path); + else { + char serialmode[3]; + const struct gps_type_t *dt = device->device_type; + /* interpret defaults */ + if (devconf.baudrate == DEVDEFAULT_BPS) + devconf.baudrate = + (uint) gpsd_get_speed(&device->ttyset); + if (devconf.parity == DEVDEFAULT_PARITY) + devconf.stopbits = device->gpsdata.dev.stopbits; + if (devconf.stopbits == DEVDEFAULT_STOPBITS) + devconf.stopbits = device->gpsdata.dev.stopbits; + if (isnan(devconf.cycle)) + devconf.cycle = device->gpsdata.dev.cycle; + + /* now that channel is selected, apply changes */ + if (devconf.driver_mode != device->gpsdata.dev.driver_mode + && devconf.driver_mode != DEVDEFAULT_NATIVE + && dt->mode_switcher != NULL) + dt->mode_switcher(device, devconf.driver_mode); + + serialmode[0] = devconf.parity; + serialmode[1] = '0' + devconf.stopbits; + serialmode[2] = '\0'; + set_serial(device, + (speed_t) devconf.baudrate, serialmode); + if (dt->rate_switcher != NULL + && isnan(devconf.cycle) == 0 + && devconf.cycle >= dt->min_cycle) + if (dt->rate_switcher(device, devconf.cycle)) + device->gpsdata.dev.cycle = devconf.cycle; + } + } + /*@+branchstate@*/ +#else /* ALLOW_RECONFIGURE */ + (void)snprintf(reply + strlen(reply), replylen - strlen(reply), + "{\"class\":\"ERROR\",\"message\":\"Device configuration support not compiled.\"}\r\n"); +#endif /* ALLOW_RECONFIGURE */ + } + /* dump a response for each selected channel */ + for (devp = devices; devp < devices + MAXDEVICES; devp++) + if (!allocated_device(devp)) + continue; + else if (devconf.path[0] != '\0' && devp != NULL + && strcmp(devp->gpsdata.dev.path, devconf.path) != 0) + continue; + else { + json_device_dump(devp, + reply + strlen(reply), + replylen - strlen(reply)); + } + } else if (strncmp(buf, "POLL;", 5) == 0) { + int active = 0; + buf += 5; + for (devp = devices; devp < devices + MAXDEVICES; devp++) + if (allocated_device(devp) && subscribed(sub, devp)) + if ((devp->observed & GPS_TYPEMASK) != 0) + active++; + (void)snprintf(reply, replylen, + "{\"class\":\"POLL\",\"timestamp\":%.3f,\"active\":%d,\"fixes\":[", + timestamp(), active); + for (devp = devices; devp < devices + MAXDEVICES; devp++) { + if (allocated_device(devp) && subscribed(sub, devp)) { + if ((devp->observed & GPS_TYPEMASK) != 0) { + json_tpv_dump(&devp->gpsdata, + reply + strlen(reply), + replylen - strlen(reply)); + rstrip(reply); + (void)strlcat(reply, ",", replylen); + } + } + } + if (reply[strlen(reply) - 1] == ',') + reply[strlen(reply) - 1] = '\0'; /* trim trailing comma */ + (void)strlcat(reply, "],\"skyviews\":[", replylen); + for (devp = devices; devp < devices + MAXDEVICES; devp++) { + if (allocated_device(devp) && subscribed(sub, devp)) { + if ((devp->observed & GPS_TYPEMASK) != 0) { + json_sky_dump(&devp->gpsdata, + reply + strlen(reply), + replylen - strlen(reply)); + rstrip(reply); + (void)strlcat(reply, ",", replylen); + } + } + } + if (reply[strlen(reply) - 1] == ',') + reply[strlen(reply) - 1] = '\0'; /* trim trailing comma */ + (void)strlcat(reply, "]}]}\r\n", replylen); + } else if (strncmp(buf, "VERSION;", 8) == 0) { + buf += 8; + json_version_dump(reply, replylen); + } else { + const char *errend; + errend = buf + strlen(buf) - 1; + while (isspace(*errend) && errend > buf) + --errend; + (void)snprintf(reply, replylen, + "{\"class\":\"ERROR\",\"message\":\"Unrecognized request '%.*s'\"}\r\n", + (int)(errend - buf), buf); + gpsd_report(LOG_ERROR, "ERROR response: %s\n", reply); + buf += strlen(buf); + } + bailout: + *after = buf; + /*@+nullderef +nullpass@*/ + /*@+compdef@*/ +} + +static void raw_report(struct subscriber_t *sub, struct gps_device_t *device) +/* report a raw packet to a subscriber */ +{ + /* *INDENT-OFF* */ + /* + * NMEA and other textual sentences are simply + * copied to all clients that are in raw or nmea + * mode. + */ + if (TEXTUAL_PACKET_TYPE(device->packet.type) + && (sub->policy.raw > 0 || sub->policy.nmea)) { + (void)throttled_write(sub, + (char *)device->packet. + outbuffer, + device->packet.outbuflen); + return; + } + + /* + * Also, simply copy if user has specified + * super-raw mode. + */ + if (sub->policy.raw > 1) { + (void)throttled_write(sub, + (char *)device->packet. + outbuffer, + device->packet.outbuflen); + return; + } +#ifdef BINARY_ENABLE + /* + * Maybe the user wants a binary packet hexdumped. + */ + if (sub->policy.raw == 1) { + char *hd = + gpsd_hexdump((char *)device->packet.outbuffer, + device->packet.outbuflen); + /* + * Ugh...depends on knowing the length of gpsd_hexdump's + * buffer. + */ + (void)strlcat(hd, "\r\n", MAX_PACKET_LENGTH * 2 + 1); + (void)throttled_write(sub, hd, strlen(hd)); + } +#endif /* BINARY_ENABLE */ +} + +static void pseudonmea_report(struct subscriber_t *sub, + gps_mask_t changed, + struct gps_device_t *device) +/* report pseodo-NMEA in appropriate circumstances */ +{ + if (GPS_PACKET_TYPE(device->packet.type) + && !TEXTUAL_PACKET_TYPE(device->packet.type)) { + char buf[MAX_PACKET_LENGTH * 3 + 2]; + + gpsd_report(LOG_PROG, "data mask is %s\n", + gpsd_maskdump(device->gpsdata.set)); + if ((changed & REPORT_IS) != 0) { + nmea_tpv_dump(device, buf, sizeof(buf)); + gpsd_report(LOG_IO, "<= GPS (binary1) %s: %s\n", + device->gpsdata.dev.path, buf); + (void)throttled_write(sub, buf, strlen(buf)); + } else if ((changed & SATELLITE_IS) != 0) { + nmea_sky_dump(device, buf, sizeof(buf)); + gpsd_report(LOG_IO, "<= GPS (binary2) %s: %s\n", + device->gpsdata.dev.path, buf); + (void)throttled_write(sub, buf, strlen(buf)); + } + } +} + +static void json_report(struct subscriber_t *sub, + gps_mask_t changed, + struct gps_device_t *device) +/* report in JSON format to a subscriber */ +{ + char buf[GPS_JSON_RESPONSE_MAX * 4]; + + buf[0] = '\0'; + if ((changed & REPORT_IS) != 0) { + json_tpv_dump(&device->gpsdata, + buf, sizeof(buf)); + (void)throttled_write(sub, buf, strlen(buf)); + } + + if ((changed & SATELLITE_IS) != 0) { + json_sky_dump(&device->gpsdata, + buf, sizeof(buf)); + (void)throttled_write(sub, buf, strlen(buf)); + } +#ifdef COMPASS_ENABLE + if ((changed & ATT_IS) != 0) { + json_att_dump(&device->gpsdata, + buf, sizeof(buf)); + (void)throttled_write(sub, buf, strlen(buf)); + } +#endif /* COMPASS_ENABLE */ +#ifdef RTCM104V2_ENABLE + if ((changed & RTCM2_IS) != 0) { + rtcm2_json_dump(&device->gpsdata.rtcm2, buf, + sizeof(buf)); + (void)throttled_write(sub, buf, strlen(buf)); + } +#endif /* RTCM104V2_ENABLE */ +#ifdef AIVDM_ENABLE + if ((changed & AIS_IS) != 0) { + aivdm_json_dump(&device->gpsdata.ais, + sub->policy.scaled, + buf, sizeof(buf)); + (void)throttled_write(sub, buf, strlen(buf)); + } +#endif /* AIVDM_ENABLE */ + +#ifdef TIMING_ENABLE + if (buf[0] != '\0' && sub->policy.timing) { + (void)snprintf(buf, sizeof(buf), + "{\"class\":\"TIMING\"," + "\"tag\":\"%s\",\"len\":%d," + "\"xmit\":%lf,\"recv\":%lf," + "\"decode\":%lf," + "\"emit\":%lf}\r\n", + device->gpsdata.tag, + (int)device->packet.outbuflen, + device->d_xmit_time, + device->d_recv_time, + device->d_decode_time, + timestamp()); + (void)throttled_write(sub, buf, strlen(buf)); + } +#endif /* TIMING_ENABLE */ +} + +static void consume_packets(struct gps_device_t *device) +/* consume and report packets from a specified device */ +{ + gps_mask_t changed; + int fragments; + struct subscriber_t *sub; + + gpsd_report(LOG_RAW + 1, "polling %d\n", + device->gpsdata.gps_fd); + + for (fragments = 0; ; fragments++) { + changed = gpsd_poll(device); + + if (changed == ERROR_IS) { + gpsd_report(LOG_WARN, + "device read of %s returned error or packet sniffer failed sync (flags %s)\n", + device->gpsdata.dev.path, + gpsd_maskdump(changed)); + deactivate_device(device); + break; + } else if (changed == NODATA_IS) { + /* + * No data on the first fragment read means the device + * fd may have been in an end-of-file condition on select. + */ + if (fragments == 0) { + gpsd_report(LOG_DATA, + "%s returned zero bytes\n", + device->gpsdata.dev.path); + if (device->zerokill) + /* failed timeout-and-reawake, kill it */ + deactivate_device(device); + else { + /* + * Disable listening to this fd for long enough + * that the buffer can fill up again. + */ + gpsd_report(LOG_DATA, + "%s will be repolled in %f seconds\n", + device->gpsdata.dev.path, DEVICE_REAWAKE); + device->reawake = timestamp() + DEVICE_REAWAKE; + FD_CLR(device->gpsdata.gps_fd, &all_fds); + adjust_max_fd(device->gpsdata.gps_fd, false); + } + } + /* + * No data on later fragment reads just means the + * input buffer is empty. In this case break out + * of the packet-processing loop but don't drop + * the device. + */ + break; + } + + /* we got actual data, head off the reawake special case */ + device->zerokill = false; + device->reawake = 0; + + /* must have a full packet to continue */ + if ((changed & PACKET_IS) == 0) + break; + + gpsd_report(LOG_DATA, + "packet from %s with %s\n", + device->gpsdata.dev.path, + gpsd_maskdump(device->gpsdata.set)); + + /* add any just-identified device to watcher lists */ + if ((changed & DRIVER_IS) != 0) { + bool listeners = false; + for (sub = subscribers; + sub < subscribers + MAXSUBSCRIBERS; sub++) + if (sub->active != 0 + && sub->policy.watcher + && (sub->policy.devpath[0] == '\0' + || strcmp(sub->policy.devpath, + device->gpsdata.dev.path) == 0)) + listeners = true; + if (listeners) + (void)awaken(device); + } + + /* handle laggy response to a firmware version query */ + if ((changed & (DEVICEID_IS | DRIVER_IS)) != 0) { + assert(device->device_type != NULL); + { + char id2[GPS_JSON_RESPONSE_MAX]; + json_device_dump(device, id2, sizeof(id2)); + notify_watchers(device, id2); + } + } + + /* + * If the device provided an RTCM packet, stash it + * in the context structure for use as a future correction. + */ + if ((changed & RTCM2_IS) != 0 || (changed & RTCM3_IS) != 0) { + if (device->packet.outbuflen > RTCM_MAX) { + gpsd_report(LOG_ERROR, + "overlong RTCM packet (%zd bytes)\n", + device->packet.outbuflen); + } else { + context.rtcmbytes = device->packet.outbuflen; + memcpy(context.rtcmbuf, + device->packet.outbuffer, + context.rtcmbytes); + } + } + + /* + * If no reliable end of cycle, must report every time + * a sentence changes position or mode. Likely to + * cause display jitter. + */ + if (!device->cycle_end_reliable && (changed & (LATLON_IS | MODE_IS))!=0) + changed |= REPORT_IS; + + /* a few things are not per-subscriber reports */ + if ((changed & REPORT_IS) != 0) { + if (device->gpsdata.fix.mode == MODE_3D) + netgnss_report(device); +#ifdef DBUS_ENABLE + send_dbus_fix(device); +#endif /* DBUS_ENABLE */ + } + + /* update all subscribers associated with this device */ + for (sub = subscribers; sub < subscribers + MAXSUBSCRIBERS; sub++) { + /*@-nullderef@*/ + if (sub == NULL || sub->active == 0) + continue; + + /* report raw packets to users subscribed to those */ + raw_report(sub, device); + + /* some listeners may be in watcher mode */ + if (sub->policy.watcher) { + if (changed & DATA_IS) { + gpsd_report(LOG_PROG, + "Changed mask: %s with %sreliable cycle detection\n", + gpsd_maskdump(changed), + device->cycle_end_reliable ? "" : "un"); + if ((changed & REPORT_IS) != 0) + gpsd_report(LOG_PROG, "time to report a fix\n"); + + if (sub->policy.nmea) + pseudonmea_report(sub, changed, device); + + if (sub->policy.json) + json_report(sub, changed, device); + } + } + /*@+nullderef@*/ + } /* subscribers */ + + /* + * Trying to read a nonexistent datagram hangs, + * so only go through the poll loop once after + * select in this case. + */ + if (device->sourcetype == source_udp) + break; + } +} + +static int handle_gpsd_request(struct subscriber_t *sub, const char *buf) +/* execute GPSD requests from a buffer */ +{ + char reply[GPS_JSON_RESPONSE_MAX + 1]; + + reply[0] = '\0'; + if (buf[0] == '?') { + const char *end; + for (end = ++buf; *buf != '\0'; buf = end) + if (isspace(*buf)) + end = buf + 1; + else + handle_request(sub, buf, &end, + reply + strlen(reply), + sizeof(reply) - strlen(reply)); + } + return (int)throttled_write(sub, reply, strlen(reply)); +} + +/*@ -mustfreefresh @*/ +int main(int argc, char *argv[]) +{ + char *pid_file = NULL; + int st, csock = -1; + static char *gpsd_service = NULL; /* static pacifies splint */ + char *control_socket = NULL; + struct gps_device_t *device; + sockaddr_t fsin; + fd_set rfds, control_fds; + int i, option, msocks[2], cfd, dfd; + bool go_background = true; + struct timeval tv; + struct subscriber_t *sub; + const struct gps_type_t **dp; + +#ifdef PPS_ENABLE + pthread_mutex_init(&report_mutex, NULL); +#endif /* PPS_ENABLE */ + +#ifdef HAVE_SETLOCALE + (void)setlocale(LC_NUMERIC, "C"); +#endif + debuglevel = 0; + gpsd_hexdump_level = 0; + while ((option = getopt(argc, argv, "F:D:S:bGhlNnP:V")) != -1) { + switch (option) { + case 'D': + debuglevel = (int)strtol(optarg, 0, 0); + gpsd_hexdump_level = debuglevel; +#ifdef CLIENTDEBUG_ENABLE + gps_enable_debug(debuglevel, stderr); +#endif /* CLIENTDEBUG_ENABLE */ + break; + case 'F': + control_socket = optarg; + break; + case 'N': + go_background = false; + break; + case 'b': + context.readonly = true; + break; + case 'G': + listen_global = true; + break; + case 'l': /* list known device types and exit */ + for (dp = gpsd_drivers; *dp; dp++) { +#ifdef ALLOW_RECONFIGURE + if ((*dp)->mode_switcher != NULL) + (void)fputs("n\t", stdout); + else + (void)fputc('\t', stdout); + if ((*dp)->speed_switcher != NULL) + (void)fputs("b\t", stdout); + else + (void)fputc('\t', stdout); + if ((*dp)->rate_switcher != NULL) + (void)fputs("c\t", stdout); + else + (void)fputc('\t', stdout); +#endif /* ALLOW_RECONFIGURE */ + (void)puts((*dp)->type_name); + } + exit(0); + case 'S': + gpsd_service = optarg; + break; + case 'n': + nowait = true; + break; + case 'P': + pid_file = optarg; + break; + case 'V': + (void)printf("gpsd: %s (revision %s)\n", VERSION, REVISION); + exit(0); + case 'h': + case '?': + default: + usage(); + exit(0); + } + } + +#ifdef FIXED_PORT_SPEED + /* Assume that if we're running with FIXED_PORT_SPEED we're some sort + * of embedded configuration where we don't want to wait for connect */ + nowait = true; +#endif + + if (!control_socket && optind >= argc) { + gpsd_report(LOG_ERROR, + "can't run with neither control socket nor devices\n"); + exit(1); + } + + /* + * Control socket has to be created before we go background in order to + * avoid a race condition in which hotplug scripts can try opening + * the socket before it's created. + */ + if (control_socket) { + (void)unlink(control_socket); + if ((csock = filesock(control_socket)) == -1) { + gpsd_report(LOG_ERROR, + "control socket create failed, netlib error %d\n", + csock); + exit(2); + } else + gpsd_report(LOG_SPIN, "control socket %s is fd %d\n", + control_socket, csock); + FD_SET(csock, &all_fds); + adjust_max_fd(csock, true); + gpsd_report(LOG_PROG, "control socket opened at %s\n", + control_socket); + } + + if (go_background) + (void)daemonize(); + + if (pid_file) { + FILE *fp; + + if ((fp = fopen(pid_file, "w")) != NULL) { + (void)fprintf(fp, "%u\n", (unsigned int)getpid()); + (void)fclose(fp); + } else { + gpsd_report(LOG_ERROR, "Cannot create PID file: %s.\n", pid_file); + } + } + + openlog("gpsd", LOG_PID, LOG_USER); + gpsd_report(LOG_INF, "launching (Version %s)\n", VERSION); + /*@ -observertrans @*/ + if (!gpsd_service) + gpsd_service = + getservbyname("gpsd", "tcp") ? "gpsd" : DEFAULT_GPSD_PORT; + /*@ +observertrans @*/ + if (passivesocks(gpsd_service, "tcp", QLEN, msocks) < 1) { + gpsd_report(LOG_ERR, + "command sockets creation failed, netlib errors %d, %d\n", + msocks[0], msocks[1]); + exit(2); + } + gpsd_report(LOG_INF, "listening on port %s\n", gpsd_service); + +#ifdef NTPSHM_ENABLE + if (getuid() == 0) { + errno = 0; + // nice() can ONLY succeed when run as root! + // do not even bother as non-root + if (nice(NICEVAL) == -1 && errno != 0) + gpsd_report(LOG_INF, "NTPD Priority setting failed.\n"); + } + (void)ntpshm_init(&context, nowait); +#endif /* NTPSHM_ENABLE */ + +#ifdef DBUS_ENABLE + /* we need to connect to dbus as root */ + if (initialize_dbus_connection()) { + /* the connection could not be started */ + gpsd_report(LOG_ERROR, "unable to connect to the DBUS system bus\n"); + } else + gpsd_report(LOG_PROG, + "successfully connected to the DBUS system bus\n"); +#endif /* DBUS_ENABLE */ + + if (getuid() == 0 && go_background) { + struct passwd *pw; + struct stat stb; + + /* make default devices accessible even after we drop privileges */ + for (i = optind; i < argc; i++) + if (stat(argv[i], &stb) == 0) + (void)chmod(argv[i], stb.st_mode | S_IRGRP | S_IWGRP); + /* + * Drop privileges. Up to now we've been running as root. Instead, + * set the user ID to 'nobody' (or whatever the --enable-gpsd-user + * is) and the group ID to the owning group of a prototypical TTY + * device. This limits the scope of any compromises in the code. + * It requires that all GPS devices have their group read/write + * permissions set. + */ + /*@-type@*/ + if ((optind < argc && stat(argv[optind], &stb) == 0) + || stat(PROTO_TTY, &stb) == 0) { + gpsd_report(LOG_PROG, "changing to group %d\n", stb.st_gid); + if (setgid(stb.st_gid) != 0) + gpsd_report(LOG_ERROR, "setgid() failed, errno %s\n", + strerror(errno)); + } +#ifdef GPSD_GROUP + else { + struct group *grp = getgrnam(GPSD_GROUP); + if (grp) + (void)setgid(grp->gr_gid); + } +#endif + pw = getpwnam(GPSD_USER); + if (pw) + (void)setuid(pw->pw_uid); + /*@+type@*/ + } + gpsd_report(LOG_INF, "running with effective group ID %d\n", getegid()); + gpsd_report(LOG_INF, "running with effective user ID %d\n", geteuid()); + + for (i = 0; i < NITEMS(subscribers); i++) + subscribers[i].fd = UNALLOCATED_FD; + + /* daemon got termination or interrupt signal */ + if ((st = setjmp(restartbuf)) > 0) { + /* try to undo all device configurations */ + for (dfd = 0; dfd < MAXDEVICES; dfd++) { + if (allocated_device(&devices[dfd])) + (void)gpsd_wrap(&devices[dfd]); + } + gpsd_report(LOG_WARN, "gpsd restarted by SIGHUP\n"); + } + + /* Handle some signals */ + signalled = 0; + (void)signal(SIGHUP, onsig); + (void)signal(SIGINT, onsig); + (void)signal(SIGTERM, onsig); + (void)signal(SIGQUIT, onsig); + (void)signal(SIGPIPE, SIG_IGN); + + for (i = 0; i < AFCOUNT; i++) + if (msocks[i] >= 0) { + FD_SET(msocks[i], &all_fds); + adjust_max_fd(msocks[i], true); + } + FD_ZERO(&control_fds); + + /* optimization hack to defer having to read subframe data */ + if (time(NULL) < START_SUBFRAME) + context.valid |= LEAP_SECOND_VALID; + + for (i = optind; i < argc; i++) { + if (!add_device(argv[i])) { + gpsd_report(LOG_ERROR, + "GPS device %s nonexistent or can't be read\n", + argv[i]); + } + } + + while (0 == signalled) { + (void)memcpy((char *)&rfds, (char *)&all_fds, sizeof(rfds)); + + gpsd_report(LOG_RAW + 2, "select waits\n"); + /* + * Poll for user commands or GPS data. The timeout doesn't + * actually matter here since select returns whenever one of + * the file descriptors in the set goes ready. The point + * of tracking maxfd is to keep the set of descriptors that + * select(2) has to poll here as small as possible (for + * low-clock-rate SBCs and the like). + */ + /*@ -usedef @*/ + tv.tv_sec = 1; + tv.tv_usec = 0; + errno = 0; + if (select(maxfd + 1, &rfds, NULL, NULL, &tv) == -1) { + if (errno == EINTR) + continue; + gpsd_report(LOG_ERROR, "select: %s\n", strerror(errno)); + exit(2); + } + /*@ +usedef @*/ + + if (debuglevel >= LOG_SPIN) { + char dbuf[BUFSIZ]; + dbuf[0] = '\0'; + for (i = 0; i < FD_SETSIZE; i++) + if (FD_ISSET(i, &all_fds)) + (void)snprintf(dbuf + strlen(dbuf), + sizeof(dbuf) - strlen(dbuf), "%d ", i); + if (strlen(dbuf) > 0) + dbuf[strlen(dbuf) - 1] = '\0'; + (void)strlcat(dbuf, "} -> {", BUFSIZ); + for (i = 0; i < FD_SETSIZE; i++) + if (FD_ISSET(i, &rfds)) + (void)snprintf(dbuf + strlen(dbuf), + sizeof(dbuf) - strlen(dbuf), " %d ", i); + gpsd_report(LOG_SPIN, "select() {%s} at %f (errno %d)\n", + dbuf, timestamp(), errno); + } + + /* always be open to new client connections */ + for (i = 0; i < AFCOUNT; i++) { + if (msocks[i] >= 0 && FD_ISSET(msocks[i], &rfds)) { + socklen_t alen = (socklen_t) sizeof(fsin); + char *c_ip; + /*@+matchanyintegral@*/ + int ssock = + accept(msocks[i], (struct sockaddr *)&fsin, &alen); + /*@+matchanyintegral@*/ + + if (ssock == -1) + gpsd_report(LOG_ERROR, "accept: %s\n", strerror(errno)); + else { + struct subscriber_t *client = NULL; + int opts = fcntl(ssock, F_GETFL); + static struct linger linger = { 1, RELEASE_TIMEOUT }; + + if (opts >= 0) + (void)fcntl(ssock, F_SETFL, opts | O_NONBLOCK); + + c_ip = netlib_sock2ip(ssock); + client = allocate_client(); + if (client == NULL) { + gpsd_report(LOG_ERROR, "Client %s connect on fd %d -" + "no subscriber slots available\n", c_ip, + ssock); + (void)close(ssock); + } else + if (setsockopt + (ssock, SOL_SOCKET, SO_LINGER, (char *)&linger, + (int)sizeof(struct linger)) == -1) { + gpsd_report(LOG_ERROR, + "Error: SETSOCKOPT SO_LINGER\n"); + (void)close(ssock); + } else { + char announce[GPS_JSON_RESPONSE_MAX]; + FD_SET(ssock, &all_fds); + adjust_max_fd(ssock, true); + client->fd = ssock; + client->active = timestamp(); + gpsd_report(LOG_SPIN, + "client %s (%d) connect on fd %d\n", c_ip, + sub_index(client), ssock); + json_version_dump(announce, sizeof(announce)); + (void)throttled_write(client, announce, + strlen(announce)); + } + } + FD_CLR(msocks[i], &rfds); + } + } + + /* also be open to new control-socket connections */ + if (csock > -1 && FD_ISSET(csock, &rfds)) { + socklen_t alen = (socklen_t) sizeof(fsin); + /*@+matchanyintegral@*/ + int ssock = accept(csock, (struct sockaddr *)&fsin, &alen); + /*@-matchanyintegral@*/ + + if (ssock == -1) + gpsd_report(LOG_ERROR, "accept: %s\n", strerror(errno)); + else { + gpsd_report(LOG_INF, "control socket connect on fd %d\n", + ssock); + FD_SET(ssock, &all_fds); + FD_SET(ssock, &control_fds); + adjust_max_fd(ssock, true); + } + FD_CLR(csock, &rfds); + } + + if (context.dsock >= 0 && FD_ISSET(context.dsock, &rfds)) { + /* be ready for DGPS reports */ + if (netgnss_poll(&context) == -1) { + FD_CLR(context.dsock, &all_fds); + FD_CLR(context.dsock, &rfds); + context.dsock = -1; + } + } + + /* read any commands that came in over control sockets */ + for (cfd = 0; cfd < FD_SETSIZE; cfd++) + if (FD_ISSET(cfd, &control_fds)) { + char buf[BUFSIZ]; + + while (read(cfd, buf, sizeof(buf) - 1) > 0) { + gpsd_report(LOG_IO, "<= control(%d): %s\n", cfd, buf); + handle_control(cfd, buf); + } + gpsd_report(LOG_SPIN, "close(%d) of control socket\n", cfd); + (void)close(cfd); + FD_CLR(cfd, &all_fds); + FD_CLR(cfd, &control_fds); + adjust_max_fd(cfd, false); + } + + /* poll all active devices */ + for (device = devices; device < devices + MAXDEVICES; device++) { + if (!allocated_device(device)) + continue; + + /* pass the current RTCM correction to the GPS if new */ + if (device->device_type != NULL) + rtcm_relay(device); + + if (device->gpsdata.gps_fd >= 0) { + if (FD_ISSET(device->gpsdata.gps_fd, &rfds)) + /* get data from the device */ + consume_packets(device); + else if (device->reawake>0 && timestamp()>device->reawake) { + /* device may have had a zero-length read */ + gpsd_report(LOG_DATA, + "%s reawakened after zero-length read\n", + device->gpsdata.dev.path); + device->reawake = 0; + device->zerokill = true; + FD_SET(device->gpsdata.gps_fd, &all_fds); + adjust_max_fd(device->gpsdata.gps_fd, true); + } + } + } /* devices */ + +#ifdef NOT_FIXED + if (context.fixcnt > 0 && context.dsock == -1) { + for (device = devices; device < devices + MAXDEVICES; device++) { + if (device->gpsdata.fix.mode > MODE_NO_FIX) { + netgnss_autoconnect(&context, + device->gpsdata.fix.latitude, + device->gpsdata.fix.longitude); + break; + } + } + } +#endif + + /* accept and execute commands for all clients */ + for (sub = subscribers; sub < subscribers + MAXSUBSCRIBERS; sub++) { + if (sub->active == 0) + continue; + + if (FD_ISSET(sub->fd, &rfds)) { + char buf[BUFSIZ]; + int buflen; + + gpsd_report(LOG_PROG, "checking client(%d)\n", + sub_index(sub)); + if ((buflen = + (int)recv(sub->fd, buf, sizeof(buf) - 1, 0)) <= 0) { + detach_client(sub); + } else { + if (buf[buflen - 1] != '\n') + buf[buflen++] = '\n'; + buf[buflen] = '\0'; + gpsd_report(LOG_IO, + "<= client(%d): %s\n", sub_index(sub), buf); + + /* + * When a command comes in, update subscriber.active to + * timestamp() so we don't close the connection + * after COMMAND_TIMEOUT seconds. This makes + * COMMAND_TIMEOUT useful. + */ + sub->active = timestamp(); + if (handle_gpsd_request(sub, buf) < 0) + detach_client(sub); + } + } else { + if (!sub->policy.watcher + && timestamp() - sub->active > COMMAND_TIMEOUT) { + gpsd_report(LOG_WARN, + "client(%d) timed out on command wait.\n", + cfd); + detach_client(sub); + } + } + } + + /* + * Mark devices with an identified packet type but no + * remaining subscribers to be closed in RELEASE_TIME seconds. + * See the explanation of RELEASE_TIME for the reasoning. + */ + if (!nowait) { + for (device = devices; device < devices + MAXDEVICES; device++) { + if (allocated_device(device)) { + if (device->packet.type != BAD_PACKET) { + bool device_needed = false; + + for (sub = subscribers; + sub < subscribers + MAXSUBSCRIBERS; sub++) { + if (sub->active == 0) + continue; + else if (subscribed(sub, device)) { + device_needed = true; + break; + } + } + + if (!device_needed && device->gpsdata.gps_fd > -1) { + if (device->releasetime == 0) { + device->releasetime = timestamp(); + gpsd_report(LOG_PROG, + "device %d (fd %d) released\n", + (int)(device - devices), + device->gpsdata.gps_fd); + } else if (timestamp() - device->releasetime > + RELEASE_TIMEOUT) { + gpsd_report(LOG_PROG, "device %d closed\n", + (int)(device - devices)); + gpsd_report(LOG_RAW, + "unflagging descriptor %d\n", + device->gpsdata.gps_fd); + deactivate_device(device); + } + } + } + } + } + } + + /* nowait */ + } + + /* if we make it here, we got a signal... deal with it */ + /* restart on SIGHUP, clean up and exit otherwise */ + if (SIGHUP == (int)signalled) + longjmp(restartbuf, 1); + + gpsd_report(LOG_WARN, "received terminating signal %d.\n", signalled); + + /* try to undo all device configurations */ + for (dfd = 0; dfd < MAXDEVICES; dfd++) { + if (allocated_device(&devices[dfd])) + (void)gpsd_wrap(&devices[dfd]); + } + + gpsd_report(LOG_WARN, "exiting.\n"); + /* + * A linger option was set on each client socket when it was + * created. Now, shut them down gracefully, letting I/O drain. + * This is an attempt to avoid the sporadic race errors at the ends + * of our regression tests. + */ + for (sub = subscribers; sub < subscribers + MAXSUBSCRIBERS; sub++) { + if (sub->active != 0) + detach_client(sub); + } + + if (control_socket) + (void)unlink(control_socket); + if (pid_file) + (void)unlink(pid_file); + return 0; +} + +/*@ +mustfreefresh @*/ diff --git a/gpsd.h-head b/gpsd.h-head new file mode 100644 index 0000000..8cd0220 --- /dev/null +++ b/gpsd.h-head @@ -0,0 +1,14 @@ +/* gpsd.h -- fundamental types and structures for the gpsd library + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#ifndef _GPSD_H_ +#define _GPSD_H_ + +#include +#include + +#ifndef GPSD_CONFIG_H +/* Feature configuration switches begin here */ diff --git a/gpsd.h-tail b/gpsd.h-tail new file mode 100644 index 0000000..290d03b --- /dev/null +++ b/gpsd.h-tail @@ -0,0 +1,665 @@ +/* Feature configuration switches end here + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#endif /* GPSD_CONFIG_H */ + +#ifdef HAVE_TERMIOS_H +#include +#endif +#ifdef HAVE_SYS_TERMIOS_H +#include +#endif +#include "gps.h" + +#ifdef _WIN32 +typedef unsigned int speed_t; +#endif + +/* + * Constants for the VERSION response + * 3.1: Base JSON version + * 3.2: Added POLL command and response + * 3.3: AIS app_id split into DAC and FID + */ +#define GPSD_PROTO_MAJOR_VERSION 3 /* bump on incompatible changes */ +#define GPSD_PROTO_MINOR_VERSION 3 /* bump on compatible changes */ + +/* Some internal capabilities depend on which drivers we're compiling. */ +#ifdef EARTHMATE_ENABLE +#define ZODIAC_ENABLE +#endif +#if defined(ZODIAC_ENABLE) || defined(SIRF_ENABLE) || defined(GARMIN_ENABLE) || defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(ITRAX_ENABLE) || defined(UBX_ENABLE) || defined(SUPERSTAR2_ENABLE) || defined(ONCORE_ENABLE) +#define BINARY_ENABLE +#endif +#if defined(TRIPMATE_ENABLE) || defined(BINARY_ENABLE) +#define NON_NMEA_ENABLE +#endif +#if defined(TNT_ENABLE) || defined(OCEANSERVER_ENABLE) +#define COMPASS_ENABLE +#endif + +/* First, declarations for the packet layer... */ + +/* + * For NMEA-conforming receivers this is supposed to be 82, but + * some receivers (TN-200, GSW 2.3.2) emit oversized sentences. + * The current hog champion is the Trimble BX-960 receiver, which + * emits a 91-character GGA message. + */ +#define NMEA_MAX 91 /* max length of NMEA sentence */ +#define NMEA_BIG_BUF (2*NMEA_MAX+1) /* longer than longest NMEA sentence */ + +/* a few bits of ISGPS magic */ +enum isgpsstat_t { + ISGPS_NO_SYNC, ISGPS_SYNC, ISGPS_SKIP, ISGPS_MESSAGE, +}; +#define ISGPS_ERRLEVEL_BASE 5 + +#define RTCM_MAX (RTCM2_WORDS_MAX * sizeof(isgps30bits_t)) + +/* + * The packet buffers need to be as long than the longest packet we + * expect to see in any protocol, because we have to be able to hold + * an entire packet for checksumming... + * First we thought it had to be big enough for a SiRF Measured Tracker + * Data packet (188 bytes). Then it had to be big enough for a UBX SVINFO + * packet (206 bytes). Now it turns out that a couple of ITALK messages are + * over 512 bytes. I know we like verbose output, but this is ridiculous. + */ +#define MAX_PACKET_LENGTH 516 /* 7 + 506 + 3 */ + +struct gps_packet_t { + /* packet-getter internals */ + int type; +#define BAD_PACKET -1 +#define COMMENT_PACKET 0 +#define NMEA_PACKET 1 +#define AIVDM_PACKET 2 +#define GARMINTXT_PACKET 3 +#define MAX_TEXTUAL_TYPE 3 /* increment this as necessary */ +#define SIRF_PACKET 4 +#define ZODIAC_PACKET 5 +#define TSIP_PACKET 6 +#define EVERMORE_PACKET 7 +#define ITALK_PACKET 8 +#define GARMIN_PACKET 9 +#define NAVCOM_PACKET 10 +#define UBX_PACKET 11 +#define SUPERSTAR2_PACKET 12 +#define ONCORE_PACKET 13 +#define MAX_PACKET_TYPE 13 /* increment this as necessary */ +#define RTCM2_PACKET 14 +#define RTCM3_PACKET 15 +#define TEXTUAL_PACKET_TYPE(n) (((n)>=NMEA_PACKET) && ((n)<=MAX_TEXTUAL_TYPE)) +#define GPS_PACKET_TYPE(n) (((n)>=NMEA_PACKET) && ((n)<=MAX_PACKET_TYPE)) +#define LOSSLESS_PACKET_TYPE(n) (((n)>=RTCM2_PACKET) && ((n)<=RTCM3_PACKET)) +#define PACKET_TYPEMASK(n) (1 << (n)) +#define GPS_TYPEMASK (((2<<(MAX_PACKET_TYPE+1))-1) &~ PACKET_TYPEMASK(COMMENT_PACKET)) + unsigned int state; + size_t length; + unsigned char inbuffer[MAX_PACKET_LENGTH*2+1]; + size_t inbuflen; + unsigned /*@observer@*/char *inbufptr; + /* outbuffer needs to be able to hold 4 GPGSV records at once */ + unsigned char outbuffer[MAX_PACKET_LENGTH*2+1]; + size_t outbuflen; + unsigned long char_counter; /* count characters processed */ + unsigned long retry_counter; /* count sniff retries */ + unsigned counter; /* packets since last driver switch */ + /* + * This is not conditionalized on RTCM104_ENABLE because we need to + * be able to build gpsdecode even when RTCM support is not + * configured in the daemon. + */ + struct { + /* ISGPS200 decoding */ + bool locked; + int curr_offset; + isgps30bits_t curr_word; + isgps30bits_t buf[RTCM2_WORDS_MAX]; + unsigned int bufindex; + } isgps; +}; + +extern void packet_init(/*@out@*/struct gps_packet_t *); +extern void packet_reset(/*@out@*/struct gps_packet_t *); +extern void packet_pushback(struct gps_packet_t *); +extern void packet_parse(struct gps_packet_t *); +extern ssize_t packet_get(int, struct gps_packet_t *); +extern int packet_sniff(struct gps_packet_t *); +#define packet_buffered_input(lexer) ((lexer)->inbuffer + (lexer)->inbuflen - (lexer)->inbufptr) + +extern void isgps_init(/*@out@*/struct gps_packet_t *); +enum isgpsstat_t isgps_decode(struct gps_packet_t *, + bool (*preamble_match)(isgps30bits_t *), + bool (*length_check)(struct gps_packet_t *), + size_t, + unsigned int); +extern unsigned int isgps_parity(isgps30bits_t); +extern void isgps_output_magnavox(const isgps30bits_t *, unsigned int, FILE *); + +extern enum isgpsstat_t rtcm2_decode(struct gps_packet_t *, unsigned int); +extern void rtcm2_sager_dump(const struct rtcm2_t *, /*@out@*/char[], size_t); +extern void rtcm2_json_dump(const struct rtcm2_t *, /*@out@*/char[], size_t); +extern int rtcm2_undump(/*@out@*/struct rtcm2_t *, char *); +extern void rtcm2_unpack(/*@out@*/struct rtcm2_t *, char *); +extern void rtcm3_unpack(/*@out@*/struct rtcm3_t *, char *); +extern void rtcm3_dump(struct rtcm3_t *rtcm, FILE *); + +extern size_t oncore_payload_cksum_length(unsigned char id1,unsigned char id2); + +/* Next, declarations for the core library... */ + +/* factors for converting among confidence interval units */ +#define CEP50_SIGMA 1.18 +#define DRMS_SIGMA 1.414 +#define CEP95_SIGMA 2.45 + +/* this is where we choose the confidence level to use in reports */ +#define GPSD_CONFIDENCE CEP95_SIGMA + +#define NTPSHMSEGS 4 /* number of NTP SHM segments */ + +#define AIVDM_CHANNELS 2 /* A, B */ + +struct gps_context_t { + int valid; /* member validity flags */ + bool readonly; /* if true, never write to device */ +#define LEAP_SECOND_VALID 0x01 /* we have or don't need correction */ + /* DGPSIP status */ + bool sentdgps; /* have we sent a DGPS report? */ + enum { netgnss_none, netgnss_dgpsip, netgnss_ntrip} netgnss_service; /* type of GNSS service */ + int fixcnt; /* count of good fixes seen */ + socket_t dsock; /* socket to DGPSIP server/Ntrip caster */ + void *netgnss_privdata; /* DGNSS service specific data */ + size_t rtcmbytes; /* byte count of last RTCM104 report */ + char rtcmbuf[RTCM_MAX]; /* last RTCM104 report */ + double rtcmtime; /* timestamp of last RTCM104 report */ + /* timekeeping */ + int leap_seconds; /* Unix seconds to UTC */ + unsigned short gps_week; /* GPS week, actually 10 bits */ + double gps_tow; /* GPS time of week, actually 19 bits */ + int century; /* for NMEA-only devices without ZDA */ +#ifdef NTPSHM_ENABLE + bool enable_ntpshm; + /*@reldef@*/struct shmTime *shmTime[NTPSHMSEGS]; + bool shmTimeInuse[NTPSHMSEGS]; +# ifdef PPS_ENABLE + bool shmTimePPS; +# endif /* PPS_ENABLE */ +#endif /* NTPSHM_ENABLE */ +}; + +struct aivdm_context_t { + /* hold context for decoding AIDVM packet sequences */ + int decoded_frags; /* for tracking AIDVM parts in a multipart sequence */ + unsigned char bits[2048]; + size_t bitlen; /* how many valid bits */ + unsigned int mmsi24; /* type 24 specific */ + char shipname24[AIS_SHIPNAME_MAXLEN+1]; /* type 24 specific */ +}; + +struct gps_device_t; + +#if defined (HAVE_SYS_TERMIOS_H) +#include +#else +#if defined (HAVE_TERMIOS_H) +#include +#endif +#endif + +#define MODE_NMEA 0 +#define MODE_BINARY 1 + +typedef enum {ANY, GPS, RTCM2, RTCM3, AIS} gnss_type; +typedef enum { + event_wakeup, + event_triggermatch, + event_identified, + event_configure, + event_driver_switch, + event_deactivate, + event_reactivate, +} event_t; + +#define ONLINE_IS 0x00000001u +#define TIME_IS 0x00000002u +#define TIMERR_IS 0x00000004u +#define LATLON_IS 0x00000008u +#define ALTITUDE_IS 0x00000010u +#define SPEED_IS 0x00000020u +#define TRACK_IS 0x00000040u +#define CLIMB_IS 0x00000080u +#define STATUS_IS 0x00000100u +#define MODE_IS 0x00000200u +#define DOP_IS 0x00000400u +#define HERR_IS 0x00000800u +#define VERR_IS 0x00001000u +#define PERR_IS 0x00002000u +#define SATELLITE_IS 0x00004000u +#define RAW_IS 0x00008000u +#define USED_IS 0x00010000u +#define SPEEDERR_IS 0x00020000u +#define DRIVER_IS 0x00040000u +#define DEVICEID_IS 0x00100000u +#define ERROR_IS 0x00200000u +#define RTCM2_IS 0x00400000u +#define RTCM3_IS 0x00800000u +#define AIS_IS 0x01000000u +#define ATT_IS 0x02000000u +#define PACKET_IS 0x04000000u +#define CLEAR_IS 0x08000000u /* sentence starts a reporting cycle */ +#define REPORT_IS 0x10000000u /* sentence ends a reporting cycle */ +#define NODATA_IS 0x20000000u /* no data read from fd */ +#define DATA_IS ~(ONLINE_IS|PACKET_IS|CLEAR_IS|REPORT_IS) + +struct gps_type_t { +/* GPS method table, describes how to talk to a particular GPS type */ + /*@observer@*/char *type_name; + int packet_type; + /*@observer@*//*@null@*/char *trigger; + int channels; + /*@null@*/bool (*probe_detect)(struct gps_device_t *session); + /*@null@*/ssize_t (*get_packet)(struct gps_device_t *session); + /*@null@*/gps_mask_t (*parse_packet)(struct gps_device_t *session); + /*@null@*/ssize_t (*rtcm_writer)(struct gps_device_t *session, char *rtcmbuf, size_t rtcmbytes); + /*@null@*/void (*event_hook)(struct gps_device_t *session, event_t event); +#ifdef ALLOW_RECONFIGURE + /*@null@*/bool (*speed_switcher)(struct gps_device_t *session, + speed_t speed, char parity, int stopbits); + /*@null@*/void (*mode_switcher)(struct gps_device_t *session, int mode); + /*@null@*/bool (*rate_switcher)(struct gps_device_t *session, double rate); + double min_cycle; +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + /*@null@*/ssize_t (*control_send)(struct gps_device_t *session, char *buf, size_t buflen); +#endif /* ALLOW_CONTROLSEND */ +#ifdef NTPSHM_ENABLE + /*@null@*/double (*ntp_offset)(struct gps_device_t *session); +#endif /* NTPSHM_ENABLE */ +}; + +typedef enum {source_unknown, + source_blockdev, + source_rs232, + source_usb, + source_bluetooth, + source_pty, + source_tcp, + source_udp} + sourcetype_t; + +struct gps_device_t { +/* session object, encapsulates all global state */ + struct gps_data_t gpsdata; + /*@relnull@*/const struct gps_type_t *device_type; + struct gps_context_t *context; + bool is_serial; + sourcetype_t sourcetype; + double rtcmtime; /* timestamp of last RTCM104 correction to GPS */ +#ifndef _WIN32 + struct termios ttyset, ttyset_old; +#endif + unsigned int baudindex; + int saved_baud; + struct gps_packet_t packet; + int getcount; + char subtype[64]; /* firmware version or subtype ID */ + double opentime; + double releasetime; + bool zerokill; + double reawake; +#ifdef NTPSHM_ENABLE + int shmindex; + double last_fixtime; /* so updates happen once */ +# ifdef PPS_ENABLE + int shmTimeP; +# endif /* PPS_ENABLE */ +#endif /* NTPSHM_ENABLE */ + double mag_var; /* magnetic variation in degrees */ + bool back_to_nmea; /* back to NMEA on revert? */ + char msgbuf[MAX_PACKET_LENGTH*2+1]; /* command message buffer for sends */ + size_t msgbuflen; + int observed; /* which packet type`s have we seen? */ + bool cycle_end_reliable; /* does driver signal REPORT_MASK */ + bool notify_clients; /* ship DEVICE notification on poll? */ + struct gps_fix_t newdata; /* where clients put their data */ + struct gps_fix_t oldfix; /* previous fix for error modeling */ + /* + * The rest of this structure is driver-specific private storage. + * Because the Garmin driver uses a long buffer, you can have + * up to 4096+12 bytes of private storage in your own union member + * without making this structure larger or changing the API at all. + */ + union { +#ifdef NMEA_ENABLE + struct { + int part, await; /* for tracking GSV parts */ + struct tm date; /* date part of last sentence time */ + double subseconds; /* subsec part of last sentence time */ + char *field[NMEA_MAX]; + unsigned char fieldcopy[NMEA_MAX+1]; + /* + * State for the cycle-tracking machinery. + * The reason these timestamps are separate from the + * general sentence timestamps is that we can + * use the minutes and seconds part of a sentence + * with an incomplete timestasmp (like GGA) for + * end-cycle recognition, even if we don't have a previous + * RMC or ZDA that lets us get full time from it. + */ + double this_frac_time, last_frac_time; + bool latch_frac_time; + unsigned int lasttag; + unsigned int cycle_enders; +#ifdef GPSCLOCK_ENABLE + bool ignore_trailing_edge; +#endif /* GPSCLOCK_ENABLE */ + } nmea; +#endif /* NMEA_ENABLE */ +#ifdef GARMINTXT_ENABLE + struct { + struct tm date; /* date part of last sentence time */ + double subseconds; /* subsec part of last sentence time */ + } garmintxt; +#endif /* NMEA_ENABLE */ +#ifdef BINARY_ENABLE +#ifdef SIRF_ENABLE + struct { + unsigned int driverstate; /* for private use */ +#define SIRF_LT_231 0x01 /* SiRF at firmware rev < 231 */ +#define SIRF_EQ_231 0x02 /* SiRF at firmware rev == 231 */ +#define SIRF_GE_232 0x04 /* SiRF at firmware rev >= 232 */ +#define UBLOX 0x08 /* uBlox firmware with packet 0x62 */ + unsigned long satcounter; + unsigned int time_seen; +#define TIME_SEEN_GPS_1 0x01 /* Seen GPS time variant 1? */ +#define TIME_SEEN_GPS_2 0x02 /* Seen GPS time variant 2? */ +#define TIME_SEEN_UTC_1 0x04 /* Seen UTC time variant 1? */ +#define TIME_SEEN_UTC_2 0x08 /* Seen UTC time variant 2? */ + /* fields from Navigation Parameters message */ + bool nav_parameters_seen; /* have we seen one? */ + unsigned char altitude_hold_mode; + unsigned char altitude_hold_source; + int16_t altitude_source_input; + unsigned char degraded_mode; + unsigned char degraded_timeout; + unsigned char dr_timeout; + unsigned char track_smooth_mode; + } sirf; +#endif /* SIRF_ENABLE */ +#ifdef SUPERSTAR2_ENABLE + struct { + time_t last_iono; + } superstar2; +#endif /* SUPERSTAR2_ENABLE */ +#ifdef TSIP_ENABLE + struct { + bool superpkt; /* Super Packet mode requested */ + time_t last_41; /* Timestamps for packet requests */ + time_t last_48; + time_t last_5c; + time_t last_6d; + time_t last_46; + time_t req_compact; + unsigned int stopbits; /* saved RS232 link parameter */ + char parity; + } tsip; +#endif /* TSIP_ENABLE */ +#ifdef GARMIN_ENABLE /* private housekeeping stuff for the Garmin driver */ + struct { + unsigned char Buffer[4096+12]; /* Garmin packet buffer */ + size_t BufferLen; /* current GarminBuffer Length */ + } garmin; +#endif /* GARMIN_ENABLE */ +#ifdef ZODIAC_ENABLE /* private housekeeping stuff for the Zodiac driver */ + struct { + unsigned short sn; /* packet sequence number */ + /* + * Zodiac chipset channel status from PRWIZCH. Keep it so + * raw-mode translation of Zodiac binary protocol can send + * it up to the client. + */ +#define ZODIAC_CHANNELS 12 + unsigned int Zs[ZODIAC_CHANNELS]; /* satellite PRNs */ + unsigned int Zv[ZODIAC_CHANNELS]; /* signal values (0-7) */ + } zodiac; +#endif /* ZODIAC_ENABLE */ +#ifdef UBX_ENABLE + struct { + bool have_port_configuration; + unsigned char original_port_settings[20]; + unsigned char sbas_in_use; + } ubx; +#endif /* UBX_ENABLE */ +#ifdef NAVCOM_ENABLE + struct { + uint8_t physical_port; + bool warned; + } navcom; +#endif /* NAVCOM_ENABLE */ +#ifdef ONCORE_ENABLE + struct { +#define ONCORE_VISIBLE_CH 12 + int visible; + int PRN[ONCORE_VISIBLE_CH]; /* PRNs of satellite */ + int elevation[ONCORE_VISIBLE_CH]; /* elevation of satellite */ + int azimuth[ONCORE_VISIBLE_CH]; /* azimuth */ + double pps_delay; + } oncore; +#endif /* ONCORE_ENABLE */ + + /* + * This is not conditionalized on RTCM104_ENABLE because we need to + * be able to build gpsdecode even when RTCM support is not + * configured in the daemon. It doesn't take up extra space. + */ + struct { + /* ISGPS200 decoding */ + bool locked; + int curr_offset; + isgps30bits_t curr_word; + isgps30bits_t buf[RTCM2_WORDS_MAX]; + unsigned int bufindex; + } isgps; +#endif /* BINARY_ENABLE */ + } driver; + /* + * Auxiliary structures for parsing data that can be interleaved with + * GPS sentences. Can't be in the driver union or it will get stepped on. + * So far the only case of this is AIS reports, which in marine navigation + * systems may come over the same wire with GPS NMEA sentences. + */ +#ifdef AIVDM_ENABLE + struct aivdm_context_t aivdm[AIVDM_CHANNELS]; +#endif /* AIVDM_ENABLE */ + +#ifdef TIMING_ENABLE + /* profiling data for last sentence */ + char tag[MAXTAGLEN+1]; /* tag of last sentence processed */ + double d_xmit_time; /* beginning of sentence transmission */ + double d_recv_time; /* daemon receipt time (-> E1+T1) */ + double d_decode_time; /* daemon end-of-decode time (-> D1) */ + double emit_time; /* emission time (-> E2) */ +#endif /* TIMING_ENABLE */ +}; + +/* logging levels */ +#define LOG_ERROR 0 /* errors, display always */ +#define LOG_SHOUT 0 /* not an error but we should always see it */ +#define LOG_WARN 1 /* not errors but may indicate a problem */ +#define LOG_INF 2 /* key informative messages */ +#define LOG_DATA 3 /* log data management messages */ +#define LOG_PROG 4 /* progress messages */ +#define LOG_IO 5 /* IO to and from devices */ +#define LOG_SPIN 6 /* logging for catching spin bugs */ +#define LOG_RAW 7 /* raw low-level I/O */ + +#define IS_HIGHEST_BIT(v,m) (v & ~((m<<1)-1))==0 + +/* here are the available GPS drivers */ +extern const struct gps_type_t **gpsd_drivers; + +/* gpsd library internal prototypes */ +extern gps_mask_t nmea_parse_input(struct gps_device_t *); +extern gps_mask_t nmea_parse(char *, struct gps_device_t *); +extern ssize_t nmea_write(struct gps_device_t *session, char *buf, size_t len); +extern ssize_t nmea_send(struct gps_device_t *session, const char *, ... ); +extern void nmea_add_checksum(char *); + +ssize_t generic_get(struct gps_device_t *); +ssize_t pass_rtcm(struct gps_device_t *, char *, size_t); + +extern gps_mask_t sirf_parse(struct gps_device_t *, unsigned char *, size_t); +extern gps_mask_t evermore_parse(struct gps_device_t *, unsigned char *, size_t); +extern gps_mask_t navcom_parse(struct gps_device_t *, unsigned char *, size_t); +extern gps_mask_t garmin_ser_parse(struct gps_device_t *); +extern gps_mask_t garmintxt_parse(struct gps_device_t *); +extern gps_mask_t aivdm_parse(struct gps_device_t *); + +extern bool netgnss_uri_check(char *); +extern int netgnss_uri_open(struct gps_context_t *, char *); +extern int netgnss_poll(struct gps_context_t *); +extern void netgnss_report(struct gps_device_t *); +extern void netgnss_autoconnect(struct gps_context_t *, double, double); + +extern void rtcm_relay(struct gps_device_t *); +extern void rtcm2_output_mag(isgps30bits_t *, FILE *); + +extern int dgpsip_open(struct gps_context_t *, const char *); +extern void dgpsip_report(struct gps_device_t *); +extern void dgpsip_autoconnect(struct gps_context_t *, + double, double, const char *); +extern int ntrip_open(struct gps_context_t *, char *); +extern void ntrip_report(struct gps_device_t *); + +extern void gpsd_tty_init(struct gps_device_t *); +extern int gpsd_open(struct gps_device_t *); +extern bool gpsd_set_raw(struct gps_device_t *); +extern ssize_t gpsd_write(struct gps_device_t *, void const *, size_t); +extern bool gpsd_next_hunt_setting(struct gps_device_t *); +extern int gpsd_switch_driver(struct gps_device_t *, char *); +extern void gpsd_set_speed(struct gps_device_t *, speed_t, char, unsigned int); +extern speed_t gpsd_get_speed(const struct termios *); +extern void gpsd_assert_sync(struct gps_device_t *); +extern void gpsd_close(struct gps_device_t *); + +extern void gpsd_zero_satellites(/*@out@*/struct gps_data_t *sp)/*@modifies sp@*/; +extern void gpsd_interpret_subframe(struct gps_device_t *, unsigned int[]); +extern int gpsd_interpret_subframe_raw(struct gps_device_t *, unsigned int[]); +extern int gpsd_hexdump_level; +extern /*@ observer @*/ char *gpsd_hexdump(/*@null@*/const void *, size_t); +extern /*@ observer @*/ char *gpsd_hexdump_wrapper(/*@null@*/const void *, size_t, int); +extern int gpsd_hexpack(/*@in@*/const char *, /*@out@*/char *, size_t); +extern int hex2bin(const char *); +extern ssize_t hex_escapes(/*@out@*/char *cooked, const char *raw); +extern void ntpd_link_activate(struct gps_device_t *session); +extern char /*@observer@*/ *gpsd_id(/*@in@*/struct gps_device_t *); +extern void gpsd_position_fix_dump(struct gps_device_t *, /*@out@*/char[], size_t); +extern void gpsd_clear_data(struct gps_device_t *); +extern socket_t netlib_connectsock(int, const char *, const char *, const char *); +extern char /*@observer@*/ *netlib_errstr(const int); +extern char /*@observer@*/ *netlib_sock2ip(int); + +extern void nmea_tpv_dump(struct gps_device_t *, /*@out@*/char[], size_t); +extern void nmea_sky_dump(struct gps_device_t *, /*@out@*/char[], size_t); + +extern void ntpshm_init(struct gps_context_t *, bool); +extern int ntpshm_alloc(struct gps_context_t *); +extern bool ntpshm_free(struct gps_context_t *, int); +extern int ntpshm_put(struct gps_device_t *, double, double); +extern int ntpshm_pps(struct gps_device_t *,struct timeval *); + +extern void ecef_to_wgs84fix(/*@out@*/struct gps_fix_t *, + /*@out@*/double *, + double, double, double, + double, double, double); +extern void clear_dop(/*@out@*/struct dop_t *); +extern gps_mask_t fill_dop(/*@in@*/const struct gps_data_t *gpsdata, + struct dop_t *dop); + +/* srecord.c */ +extern void hexdump(size_t, unsigned char *, unsigned char *); +extern unsigned char sr_sum(unsigned int, unsigned int, unsigned char *); +extern int bin2srec(unsigned int, unsigned int, unsigned int, unsigned char *, unsigned char *); +extern int srec_hdr(unsigned int, unsigned char *, unsigned char *); +extern int srec_fin(unsigned int, unsigned char *); +extern unsigned char hc(unsigned char); + +/* application interface */ +extern void gpsd_init(struct gps_device_t *, + struct gps_context_t *, + /*@null@*/char *); +extern int gpsd_activate(struct gps_device_t *); +extern void gpsd_deactivate(struct gps_device_t *); +extern gps_mask_t gpsd_poll(struct gps_device_t *); +extern void gpsd_wrap(struct gps_device_t *); + +/* exceptional driver methods */ +#ifdef UBX_ENABLE +extern bool ubx_write(struct gps_device_t *, unsigned int, unsigned int, + /*@null@*/unsigned char *, unsigned short); +#endif /* UBX_ENABLE */ +#ifdef AIVDM_ENABLE +extern bool aivdm_decode(const char *, size_t, + struct aivdm_context_t [], + struct ais_t *); +extern void aivdm_json_dump(const struct ais_t *, bool, /*@out@*/char *, size_t); +#endif /* AIVDM_ENABLE */ +#ifdef MTK3301_ENABLE +extern gps_mask_t processMTK3301(int c UNUSED, char *field[], struct gps_device_t *session); +#endif /* MTK3301_ENABLE */ + +/* caller should supply this */ +# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +__attribute__((__format__(__printf__, 2, 3))) void gpsd_report(int, const char *, ...); +# else /* not a new enough GCC, use the unprotected prototype */ +void gpsd_report(int, const char *, ...); +#endif +extern /*@observer@*/const char *gpsd_maskdump(gps_mask_t); + + +#ifdef S_SPLINT_S +extern bool finite(double); +extern struct protoent *getprotobyname(const char *); +extern /*@observer@*/char *strptime(const char *,const char *tp,/*@out@*/struct tm *)/*@modifies tp@*/; +extern struct tm *gmtime_r(const time_t *,/*@out@*/struct tm *tp)/*@modifies tp@*/; +extern struct tm *localtime_r(const time_t *,/*@out@*/struct tm *tp)/*@modifies tp@*/; +extern float roundf(float x); +#endif /* S_SPLINT_S */ + +/* + * How to mix together epx and epy to get a horizontal circular error + * eph when reporting requires it. Most devices don't report these; + * NMEA 3.x devices reporting $GPGBS are the exception. + */ +#define EMIX(x, y) (((x) > (y)) ? (x) : (y)) + +/* some OSes don't have round(). fake it if need be */ +#ifndef HAVE_ROUND +#define round(x) ((double)rint(x)) +#define roundf(x) ((float)rintf((double)x)) +#endif /* !HAVE_ROUND */ + +#define NITEMS(x) (int)(sizeof(x)/sizeof(x[0])) + +/* OpenBSD and FreeBSD and Cygwin don't seem to have NAN, NetBSD does, others? */ +/* FIX-ME: test for this in configure? */ +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__CYGWIN__) +#ifndef NAN +#define NAN (0.0/0.0) +#endif /* !NAN */ +#endif /* list of Operating Systems */ + +/* Cygwin, in addition to NAN, doesn't have cfmakeraw */ +#if defined(__CYGWIN__) +void cfmakeraw(struct termios *); +#endif /* defined(__CYGWIN__) */ + +#endif /* _GPSD_H_ */ +// Local variables: +// mode: c +// end: diff --git a/gpsd.hotplug b/gpsd.hotplug new file mode 100755 index 0000000..afa74f2 --- /dev/null +++ b/gpsd.hotplug @@ -0,0 +1,123 @@ +#!/usr/bin/python +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# Hotplug script for gpsd by Eric S. Raymond, March 2005 +# This script is part of the gpsd distribution: see http://gpsd.berlios.de +# Can be called like "gpsd.hotplug [add|remove] /dev/ttyUSB0" for test +# purposes. +import sys, time, os, syslog, glob, socket, stat + +CONTROL_SOCKET = os.getenv('GPSD_SOCKET') or "/var/run/gpsd.sock" +GPSD_OPTIONS = os.getenv('GPSD_OPTIONS') or "" + +WHEREAMI = __file__ + +def gpsd_control_connect(): + "Acquire a connection to the GPSD control socket." + if not os.path.exists(CONTROL_SOCKET): + syslog.syslog("socket %s doesn't exist" % CONTROL_SOCKET) + return None + try: + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0) + sock.connect(CONTROL_SOCKET) + except socket.error, msg: + syslog.syslog("socket %s creation failure: %s" % (CONTROL_SOCKET, msg)) + if sock: + sock.close() + sock = None + #else: + # syslog.syslog("socket %s created OK" % CONTROL_SOCKET) + return sock + +def gpsd_control(action, argument): + "Pass a command to gpsd; start the daemon if not already running." + syslog.syslog("gpsd_control(action=%s, arg=%s)" % (action, argument)) + connect = gpsd_control_connect() + if connect: + syslog.syslog("reached a running gpsd") + elif action == 'add': + gpsdcmd = "gpsd %s -F %s" % (GPSD_OPTIONS, CONTROL_SOCKET) + syslog.syslog("launching %s" % gpsdcmd) + os.system(gpsdcmd) + connect = gpsd_control_connect() + if not connect: + syslog.syslog("can't reach gpsd") + return None + # We've got a live connection to the gpsd control socket. No + # need to parse the response, because gpsd will lock on to the + # device if it's really a GPS and ignore it if it's not. + if action == 'add': + # Force the group-read & group-write bits on, so gpsd will still be + # able to use this device after dropping root privileges. + os.chmod(argument, stat.S_IMODE(os.stat(argument)[stat.ST_MODE])|0660) + connect.sendall("+%s\r\n" % argument) + connect.recv(12) + elif action == 'remove': + connect.sendall("-%s\r\n" % argument) + connect.recv(12) + elif action == 'send': + connect.sendall("%s\r\n" % argument) + connect.recv(12) + connect.close() + #syslog.syslog("gpsd_control ends") + return action + +def hotplug(action, devpath): + #syslog.syslog("ACTION=%s DEVPATH=%s" % (action,devpath)) + if not devpath: + syslog.syslog("No device") + else: + subnodes = glob.glob("/sys" + devpath + "/*") + subnodes = map(os.path.basename, subnodes) + subnodes = filter(lambda s: s.startswith("ttyUSB"), subnodes) + if len(subnodes) == 0: + syslog.syslog("no ttyUSB device under " + devpath) + return + elif len(subnodes) > 1: + syslog.syslog("too many ttyUSB devices under " + devpath) + return + else: + tty = "/dev/" + subnodes[0] + + syslog.syslog("waiting for " + tty) + while not os.path.exists(tty): + time.sleep(1) + syslog.syslog(tty + " has gone active") + + gpsd_control(action, tty) + + remover = os.getenv("REMOVER") + #syslog.syslog("REMOVER=%s" % remover) + fp = open(remover, "w") + fp.write(WHEREAMI + " remove " + tty) + fp.close() + os.chmod(remover, stat.S_IRUSR|stat.S_IXUSR|stat.S_IRGRP|stat.S_IXGRP) + return + +if __name__ == '__main__': + # In recent versions of udev, the gpsd script runs in series with + # the task that creates the real /dev/ttyUSB0 device + # node. Unfortunately, the gpsd script runs BEFORE the creation of + # the node, and the node is not created until after you kill the + # gpsd script, because the gpsd script waits forever for the node + # to appear. + # + # This is a race condition, and is best fixed by running the + # actual wait/hotplug portion in the background. + pid = os.fork() + if not pid: + syslog.openlog('gpsd.hotplug', 0, syslog.LOG_DAEMON) + try: + if len(sys.argv) == 1: # Called as hotplug script + hotplug(os.getenv("ACTION"), os.getenv("DEVPATH")) + else: # Called by hand for testing + gpsd_control(sys.argv[1], sys.argv[2]) + except: + (exc_type, exc_value, exc_traceback) = sys.exc_info() + syslog.syslog("gpsd.hotplug: exception %s yields %s" % (exc_type, exc_value)) + raise exc_type, exc_value, exc_traceback + #syslog.syslog("gpsd.hotplug ends") + syslog.closelog() + diff --git a/gpsd.hotplug.wrapper b/gpsd.hotplug.wrapper new file mode 100644 index 0000000..8aee7e7 --- /dev/null +++ b/gpsd.hotplug.wrapper @@ -0,0 +1,47 @@ +#!/bin/sh +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. + +if [ -r /etc/default/gpsd ]; then + . /etc/default/gpsd +elif [ -r /etc/sysconfig/gpsd ]; then + . /etc/sysconfig/gpsd +fi + +if [ -n $GPSD_OPTIONS ]; then + export GPSD_OPTIONS +fi +if [ -n $GPSD_SOCKET ]; then + export GPSD_SOCKET +fi + +if [ -n $USBAUTO ]; then + [ "$USBAUTO" = "true" ] || exit 0 +fi + +if [ "$ACTION" = "remove" ] ; then + if echo $DEVLINKS | grep -q /dev/gps; then + exec /lib/udev/gpsd.hotplug "$ACTION" "$DEVNAME" + fi + exit 0 +fi + +# This was formerly in /lib/udev/hotplug.functions +wait_for_file() { + [ -e "$1" ] && return 0 + local count=0 + while sleep 1; do + count=$(( $count + 1 )) + [ -e "$1" ] && return 0 + if [ $count -gt 60 ]; then + return 1 + fi + done +} + +# wait for /usr & /var to be mounted +wait_for_file /usr/bin/python && \ +wait_for_file /var/run && \ + exec /lib/udev/gpsd.hotplug "$ACTION" "$DEVNAME" + diff --git a/gpsd.php b/gpsd.php new file mode 100644 index 0000000..21bb9b9 --- /dev/null +++ b/gpsd.php @@ -0,0 +1,582 @@ + +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +global $head, $blurb, $title, $googlemap, $autorefresh, $footer, $gmap_key; +global $server, $advertise, $port, $open, $swap_ew, $testmode; +$testmode = 1; # leave this set to 1 + +# Public script parameters: +# host: host name or address where GPSd runs. Default: from config file +# port: port of GPSd. Default: from config file +# op=view: show just the skyview image instead of the whole HTML page +# sz=small: used with op=view, display a small (240x240px) skyview +# op=json: respond with the GPSd POLL JSON structure +# jsonp=prefix: used with op=json, wrap the POLL JSON in parentheses +# and prepend prefix + +# If you're running PHP with the Suhosin patch (like the Debian PHP5 package), +# it may be necessary to increase the value of the +# suhosin.get.max_value_length parameter to 2048. The imgdata parameter used +# for displaying the skyview is longer than the default 512 allowed by Suhosin. +# Debian has the config file at /etc/php5/conf.d/suhosin.ini. + +# this script shouldn't take more than a few seconds to run +set_time_limit(3); +ini_set('max_execution_time', 3); + +if (!file_exists("gpsd_config.inc")) + write_config(); + +require_once("gpsd_config.inc"); + +# sample data +$resp = <<0) && ($port<65536)) + $port = $_GET['port']; + + if ($testmode){ + $sock = @fsockopen($server, $port, $errno, $errstr, 2); + @fwrite($sock, "?POLL;\n"); + for($tries = 0; $tries < 10; $tries++){ + $resp = @fread($sock, 1536); # SKY can be pretty big + if (preg_match('/{"class":"POLL".+}/i', $resp, $m)){ + $resp = $m[0]; + break; + } + } + @fclose($sock); + if (!$resp) + $resp = '{"class":"ERROR","message":"no response from GPS daemon"}'; + } +} + +if ($op == 'view') + gen_image($resp); +else if ($op == 'json') + write_json($resp); +else + write_html($resp); + +exit(0); + +########################################################################### +function colorsetup($im){ + $C['white'] = imageColorAllocate($im, 255, 255, 255); + $C['ltgray'] = imageColorAllocate($im, 191, 191, 191); + $C['mdgray'] = imageColorAllocate($im, 127, 127, 127); + $C['dkgray'] = imageColorAllocate($im, 63, 63, 63); + $C['black'] = imageColorAllocate($im, 0, 0, 0); + $C['red'] = imageColorAllocate($im, 255, 0, 0); + $C['brightgreen'] = imageColorAllocate($im, 0, 255, 0); + $C['darkgreen'] = imageColorAllocate($im, 0, 192, 0); + $C['blue'] = imageColorAllocate($im, 0, 0, 255); + $C['cyan'] = imageColorAllocate($im, 0, 255, 255); + $C['magenta'] = imageColorAllocate($im, 255, 0, 255); + $C['yellow'] = imageColorAllocate($im, 255, 255, 0); + $C['orange'] = imageColorAllocate($im, 255, 128, 0); + + return $C; +} + +function legend($im, $sz, $C){ + $r = 30; + $fn = 5; + $x = $sz - (4*$r+7) - 2; + $y = $sz - $r - 3; + + imageFilledRectangle($im, $x, $y, $x + 4*$r + 7, $y + $r +1, $C['dkgray']); + imageRectangle($im, $x+0*$r+1, $y+1, $x + 1*$r + 0, $y + $r, $C['red']); + imageRectangle($im, $x+1*$r+2, $y+1, $x + 2*$r + 2, $y + $r, $C['yellow']); + imageRectangle($im, $x+2*$r+4, $y+1, $x + 3*$r + 4, $y + $r, $C['darkgreen']); + imageRectangle($im, $x+4*$r+6, $y+1, $x + 3*$r + 6, $y + $r, $C['brightgreen']); + imageString($im, $fn, $x+3+0*$r, $y+$r/3, "<30", $C['red']); + imageString($im, $fn, $x+5+1*$r, $y+$r/3, "30+", $C['yellow']); + imageString($im, $fn, $x+7+2*$r, $y+$r/3, "35+", $C['darkgreen']); + imageString($im, $fn, $x+9+3*$r, $y+$r/3, "40+", $C['brightgreen']); +} + +function radial($angle, $sz){ + #turn into radians + $angle = deg2rad($angle); + + # determine length of radius + $r = $sz * 0.5 * 0.95; + + # and convert length/azimuth to cartesian + $x0 = sprintf("%d", (($sz * 0.5) - ($r * cos($angle)))); + $y0 = sprintf("%d", (($sz * 0.5) - ($r * sin($angle)))); + $x1 = sprintf("%d", (($sz * 0.5) + ($r * cos($angle)))); + $y1 = sprintf("%d", (($sz * 0.5) + ($r * sin($angle)))); + + return array($x0, $y0, $x1, $y1); +} + +function azel2xy($az, $el, $sz){ + global $swap_ew; + #rotate coords... 90deg W = 180deg trig + $az += 270; + + #turn into radians + $az = deg2rad($az); + + # determine length of radius + $r = $sz * 0.5 * 0.95; + $r -= ($r * ($el/90)); + + # and convert length/azimuth to cartesian + $x = sprintf("%d", (($sz * 0.5) + ($r * cos($az)))); + $y = sprintf("%d", (($sz * 0.5) + ($r * sin($az)))); + if ($swap_ew == 0) + $x = $sz - $x; + + return array($x, $y); +} + +function splot($im, $sz, $C, $e){ + if ((0 == $e['PRN']) || (0 == $e['az'] + $e['el'] + $e['ss']) || + ($e['az'] < 0) || ($e['el'] < 0)) + return; + + $color = $C['brightgreen']; + if ($e['ss'] < 40) + $color = $C['darkgreen']; + if ($e['ss'] < 35) + $color = $C['yellow']; + if ($e['ss'] < 30) + $color = $C['red']; + if ($e['el']<10) + $color = $C['blue']; + if ($e['ss'] < 10) + $color = $C['black']; + + list($x, $y) = azel2xy($e['az'], $e['el'], $sz); + + $r = 12; + if (isset($_GET['sz']) && ($_GET['sz'] == 'small')) + $r = 8; + + imageString($im, 3, $x+4, $y+4, $e['PRN'], $C['black']); + if ($e['used'] == true) + if ($e['PRN'] > 32) + imageFilledDiamond($im, $x, $y, $r, $color); + else + imageFilledArc($im, $x, $y, $r, $r, 0, 360, $color, 0); + else + if ($e['PRN'] > 32) + imageDiamond($im, $x, $y, $r, $color); + else + imageArc($im, $x, $y, $r, $r, 0, 360, $color); +} + +function imageDiamond($im, $x, $y, $r, $color){ + $t = $r/2; + # this lunacy is because imagesetthickness doesn't seem to work + $vx = array ( $x+$t, $y, $x, $y+$t, $x-$t, $y, $x, $y-$t ); + imagepolygon($im, $vx, 4, $color); + $t--; + $vx = array ( $x+$t, $y, $x, $y+$t, $x-$t, $y, $x, $y-$t ); + imagepolygon($im, $vx, 4, $color); + $t--; + $vx = array ( $x+$t, $y, $x, $y+$t, $x-$t, $y, $x, $y-$t ); + imagepolygon($im, $vx, 4, $color); +} + +function imageFilledDiamond($im, $x, $y, $r, $color){ + $t = $r/2; + while($t){ + $vx = array ( $x+$t, $y, $x, $y+$t, $x-$t, $y, $x, $y-$t ); + imagepolygon($im, $vx, 4, $color); + $t -= 0.5; + } +} + +function elevation($im, $sz, $C, $a){ + $b = 90 - $a; + $a = $sz * 0.95 * ($a/180); + imageArc($im, $sz/2, $sz/2, $a*2, $a*2, 0, 360, $C['ltgray']); + $x = $sz/2 - 16; + $y = $sz/2 - $a; + imageString($im, 2, $x, $y, $b, $C['ltgray']); +} + +function skyview($im, $sz, $C){ + global $swap_ew; + $a = 90; $a = $sz * 0.95 * ($a/180); + imageFilledArc($im, $sz/2, $sz/2, $a*2, $a*2, 0, 360, $C['mdgray'], 0); + imageArc($im, $sz/2, $sz/2, $a*2, $a*2, 0, 360, $C['black']); + $x = $sz/2 - 16; $y = $sz/2 - $a; + imageString($im, 2, $x, $y, "0", $C['ltgray']); + + $a = 85; $a = $sz * 0.95 * ($a/180); + imageFilledArc($im, $sz/2, $sz/2, $a*2, $a*2, 0, 360, $C['white'], 0); + imageArc($im, $sz/2, $sz/2, $a*2, $a*2, 0, 360, $C['ltgray']); + imageString($im, 1, $sz/2 - 6, $sz+$a, '5', $C['black']); + $x = $sz/2 - 16; $y = $sz/2 - $a; + imageString($im, 2, $x, $y, "5", $C['ltgray']); + + for($i = 0; $i < 180; $i += 15){ + list($x0, $y0, $x1, $y1) = radial($i, $sz); + imageLine($im, $x0, $y0, $x1, $y1, $C['ltgray']); + } + + for($i = 15; $i < 90; $i += 15) + elevation($im, $sz, $C, $i); + + $x = $sz/2 - 16; $y = $sz/2 - 8; + /* imageString($im, 2, $x, $y, "90", $C['ltgray']); */ + + imageString($im, 4, $sz/2 + 4, 2 , 'N', $C['black']); + imageString($im, 4, $sz/2 + 4, $sz - 16 , 'S', $C['black']); + if ($swap_ew == 0){ + imageString($im, 4, 4 , $sz/2 + 4, 'E', $C['black']); + imageString($im, 4, $sz - 10 , $sz/2 + 4, 'W', $C['black']); + } else { + imageString($im, 4, 4 , $sz/2 + 4, 'W', $C['black']); + imageString($im, 4, $sz - 10 , $sz/2 + 4, 'E', $C['black']); + } +} + +function gen_image($resp){ + $sz = 600; + if (isset($_GET['sz']) && ($_GET['sz'] == 'small')) + $sz = 240; + + $GPS = json_decode($resp, true); + if ($GPS['class'] != "POLL"){ + die("json_decode error: $resp"); + } + + $im = imageCreate($sz, $sz); + $C = colorsetup($im); + skyview($im, $sz, $C); + if ($sz > 240) + legend($im, $sz, $C); + + for($i = 0; $i < count($GPS['skyviews'][0]['satellites']); $i++){ + splot($im, $sz, $C, $GPS['skyviews'][0]['satellites'][$i]); + } + + header("Content-type: image/png"); + imagePNG($im); + imageDestroy($im); +} + +function dfix($x, $y, $z){ + if ($x < 0){ + $x = sprintf("%f %s", -1 * $x, $z); + } else { + $x = sprintf("%f %s", $x, $y); + } + return $x; +} + +function write_html($resp){ + global $sock, $errstr, $errno, $server, $port, $head, $body, $open; + global $blurb, $title, $autorefresh, $googlemap, $gmap_key, $footer; + global $testmode, $advertise; + + $GPS = json_decode($resp, true); + if ($GPS['class'] != 'POLL'){ + die("json_decode error: $resp"); + } + + header("Content-type: text/html; charset=UTF-8"); + + global $lat, $lon; + $lat = (float)$GPS['fixes'][0]['lat']; + $lon = (float)$GPS['fixes'][0]['lon']; + $x = $server; $y = $port; + $imgdata = base64_encode($resp); + $server = $x; $port = $y; + + if ($autorefresh > 0) + $autorefresh = ""; + else + $autorefresh = ''; + + $gmap_head = $gmap_body = $gmap_code = ''; + if ($googlemap){ + $gmap_head = gen_gmap_head(); + $gmap_body = 'onload="Load()" onunload="GUnload()"'; + $gmap_code = gen_gmap_code(); + } + $part1 = << + + + +{$head} +{$gmap_head} + + +{$title} - GPSD Test Station {$lat}, {$lon} +{$autorefresh} + + + + +
+ + +EOF; + + if (!strlen($advertise)) + $advertise = $server; + + if ($testmode && !$sock) + $part2 = ""; + else + $part2 = << + + + +EOF; + + if (!$open) + $part3 = ''; + else + $part3 = << + + + +EOF; + + if ($testmode && !$sock) + $part4 = ""; + else { + $nsv = count($GPS['skyviews'][0]['satellites']); + $ts = gmdate("r", $GPS['fixes'][0]['time']); + $part4 = << + + +EOF; + } + + $part5 = << + + +{$footer} + +
+This script is distributed by the GPSD project.
+ + + +EOF; + +print $part1 . $part2 . $part3 . $part4 . $part5; + +} + +function write_json($resp){ + header('Content-Type: text/javascript'); + if (isset($_GET['jsonp'])) + print "{$_GET['jsonp']}({$resp})"; + else + print $resp; +} + +function write_config(){ + $f = fopen("gpsd_config.inc", "a"); + if (!$f) + die("can't generate prototype config file. try running this script as root in DOCUMENT_ROOT"); + + $buf = <<gpsd +server located someplace. + +The hardware is a +hardware description and link. + +This machine is maintained by +Your Name Goes Here.
+EOT; + +?> + +EOB; + fwrite($f, $buf); + fclose($f); +} + +function gen_gmap_head() { +global $gmap_key; +return << + +EOT; + +} +function gen_gmap_code() { +return << +
+ Loading... + +
+ + +EOT; +} + +?> diff --git a/gpsd.rules b/gpsd.rules new file mode 100644 index 0000000..cfae281 --- /dev/null +++ b/gpsd.rules @@ -0,0 +1,44 @@ +# udev rules for gpsd +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# GPSes don't have their own USB device class. They're serial-over-USB +# devices, so what you see is actually the ID of the serial-over-USB chip. +# Fortunately, just two of these account for over 80% of consumer-grade +# GPS sensors. The gpsd.hotplug.wrapper script will tell a running gpsd +# that it should look at the device that just went active, because it +# might be a GPS. +# +# The following setup works on Debian - something similar will apply on +# other distributions: +# +# /lib/udev/rules.d/025_gpsd.rules +# /lib/udev/gpsd.hotplug.wrapper +# /lib/udev/gpsd.hotplug +# +# Setting the link in /lib/udev/rules.d activates the rule and determines +# when to run it on boot (similar to init.d processing). + +SUBSYSTEM!="tty", GOTO="gpsd_rules_end" + +# Prolific Technology, Inc. PL2303 Serial Port +ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug.wrapper" +# ATEN International Co., Ltd UC-232A Serial Port [pl2303] +ATTRS{idVendor}=="0557", ATTRS{idProduct}=="2008", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug.wrapper" +# FTDI 8U232AM / FT232 +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug.wrapper" +# Cypress M8/CY7C64013 (DeLorme uses these) +ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0100", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug.wrapper" +# PS-360 OEM (Microsoft GPS sold with Street and Trips 2005) +ATTRS{idVendor}=="067b", ATTRS{idProduct}=="aaa0", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug.wrapper" +# Garmin International GPSmap, various models (tested with Garmin GPS 18 USB) +ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug.wrapper" +# Cygnal Integrated Products, Inc. CP210x Composite Device (Used by Holux m241 and Wintec grays2 wbt-201) +ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug.wrapper" +# u-blox AG, u-blox 5 (tested with Navilock NL-402U) +ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a5", SYMLINK="gps%n", RUN+="/lib/udev/gpsd.hotplug.wrapper" + +ACTION=="remove", RUN+="/lib/udev/gpsd.hotplug.wrapper" + +LABEL="gpsd_rules_end" diff --git a/gpsd.usermap b/gpsd.usermap new file mode 100644 index 0000000..1049814 --- /dev/null +++ b/gpsd.usermap @@ -0,0 +1,19 @@ +# Hotplug device map for GPSD +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# GPSes don't have their own USB device class. They're serial-over-USB +# devices, so what you see is actually the ID of the serial-over-USB chip. +# Fortunately, just two of these account for over 80% of consumer-grade +# GPS sensors. The gpsdplug script will tell a running gpsd that it should +# look at the device that just went active, because it might be a GPS. +# +# The Prolific Technology 2303 (commonly in tandem with SiRF chips) +gpsd.hotplug 0x0003 0x067b 0x2303 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# FTDI 8U232AM +gpsd.hotplug 0x0003 0x0403 0x6001 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Cypress M8/CY7C64013 (DeLorme uses these) +gpsd.hotplug 0x0003 0x1163 0x0100 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# PS-360 OEM (Microsoft GPS sold with Street and Trips 2005) +gpsd.hotplug 0x0003 0x067b 0xaaa0 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 diff --git a/gpsd.xml b/gpsd.xml new file mode 100644 index 0000000..c02343f --- /dev/null +++ b/gpsd.xml @@ -0,0 +1,1923 @@ + + + +]> + +9 Aug 2004 + +gpsd +8 +The GPSD Project +GPSD Documentation + + +gpsd +interface daemon for GPS receivers + + + + + + gpsd + -F control-socket + + -S listener-port + -b + -l + -G + -n + -N + -h + -P pidfile + -D debuglevel + -V + + source-name + + + + +QUICK START + +If you have a GPS attached on the lowest-numbered USB port of a +Linux system, and want to read reports from it on TCP/IP port 2947, it +will normally suffice to do this: + + +gpsd /dev/ttyUSB0 + + +For the lowest-numbered serial port: + + +gpsd /dev/ttyS0 + + +Change the device number as appropriate if you need to use a +different port. Command-line flags enable verbose logging, a control +port, and other optional extras but should not be needed for basic +operation; the one exception, on very badly designed hardware, might +be (which see). + +On Linux systems supporting udev, gpsd +is normally started automatically when a USB plugin event fires (if it +is not already running) and is handed the name of the newly active +device. In that case no invocation is required at all. + +For your initial tests set your GPS hardware to speak NMEA, as +gpsd is guaranteed to be able to process +that. If your GPS has a native or binary mode with better perfornance +that gpsd knows how to speak, +gpsd will autoconfigure that mode. + +You can verify correct operation by first starting +gpsd and then +xgps, the X windows test client. + +If you have problems, the GPSD project maintains a FAQ to assist +troubleshooting. + + +DESCRIPTION + +gpsd is a monitor daemon that collects +information from GPSes, differential-GPS radios, or AIS receivers +attached to the host machine. Each GPS, DGPS radio, or AIS receiver +is expected to be direct-connected to the host via a USB or RS232C +serial device. The serial device may be specified to +gpsd at startup, or it may be set via a +command shipped down a local control socket (e.g. by a USB hotplug +script). Given a GPS device by either means, +gpsd discovers the correct port speed and +protocol for it. + +gpsd should be able to query any GPS +that speaks either the standard textual NMEA 0183 protocol, or the +(differing) extended NMEA dialects used by MKT-3301, iTrax, Motorola +OnCore, Sony CXD2951, and Ashtech/Thales devices. It can also +interpret the binary protocols used by EverMore, Garmin, Navcom, +Rockwell/Zodiac, SiRF, Trimble, and uBlox ANTARIS devices. It can read +heading and attitude information from the Oceanserver 5000 orv TNT +Revolution digital compasses. + +The GPS reporting formats supported by your instance of +gpsd may differ depending on how it was +compiled; general-purpose versions support many, but it can be built +with protocol subsets down to a singleton for use in constrained +environments. For a list of the GPS protocols supported by your +instance, see the output of gpsd -l + +gpsd effectively hides the +differences among the GPS types it supports. It also knows about and +uses commands that tune these GPSes for lower latency. By using +gpsd as an intermediary applications +avoid contention for serial devices. + +gpsd can use differential-GPS +corrections from a DGPS radio or over the net, from a ground station +running a DGPSIP server or a Ntrip broadcaster that reports RTCM-104 +data; this will shrink position errors by roughly a factor of four. +When gpsd opens a serial device emitting +RTCM-104, it automatically recognizes this and uses the device as a +correction source for all connected GPSes that accept RTCM corrections +(this is dependent on the type of the GPS; not all GPSes have the +firmware capability to accept RTCM correction packets). See + and for discussion. + +Client applications will communicate with gpsd +via a TCP/IP port, 2947 by default). Both IPv4 and IPv6 connections +are supported and a client may connect via either. + +The program accepts the following options: + + +-F + +Create a control socket for device addition and removal +commands. You must specify a valid pathname on your local filesystem; +this will be created as a Unix-domain socket to which you can write +commands that edit the daemon's internal device list. + + + +-S +Set TCP/IP port on which to listen for GPSD clients +(default is 2947). + + +-b +Broken-device-safety mode, otherwise known as read-only +mode. Some popular bluetooth and USB receivers lock up or become +totally inaccessible when probed or reconfigured. This switch prevents +gpsd from writing to a receiver. This means that +gpsd cannot configure the receiver for +optimal performance, but it also means that +gpsd cannot break the receiver. A better +solution would be for Bluetooth to not be so fragile. A platform +independent method to identify serial-over-Bluetooth devices would +also be nice. + + +-G +This flag causes gpsd to +listen on all addresses (INADDR_ANY) rather than just the loopback +(INADDR_LOOPBACK) address. For the sake of privacy and security, TPV +information is now private to the local machine until the user makes +an effort to expose this to the world. + + +-l +List all drivers compiled into this +gpsd instance. The letters to the left of +each driver name are the gpsd +control commands supported by that driver. + + + +-n + +Don't wait for a client to connect before polling +whatever GPS is associated with it. Many GPSes go to a standby mode +(drawing less power) before the host machine asserts DTR, so waiting +for the first actual request saves battery power. + + + +-N +Don't daemonize; run in foreground. Also suppresses +privilege-dropping. This switch is mainly useful for debugging. + + + +-h +Display help message and terminate. + + +-P + +Specify the name and path to record the daemon's process ID. + + + +-D + +Set debug level. At debug levels 2 and above, +gpsd reports incoming sentence and actions +to standard error if gpsd is in the foreground +(-N) or to syslog if in the background. + + + +-V + +Dump version and exit. + + + + +Arguments are interpreted as the names of data sources. +Normally, a data source is the device pathname of a local device from +which the daemon may expect GPS data. But there are three other +special source types recognized, for a total of four: + + + +Local serial or USB device + +A normal Unix device name of a serial or USB device to which a +sensor is attached. Example: +/dev/ttyUSB0. + + + +TCP feed + +A URI with the prefix "tcp://", followed by a hostname, a +colon, and a port number. The daemon will open a socket to the +indicated address and port and read data packets from it, which will +be interpreted as though they had been issued by a serial device. Example: +tcp://data.aishub.net:4006. + + + +UDP feed + +A URI with the prefix "udp://", followed by a hostname, a +colon, and a port number. The daemon will open a socket listening for +UDP datagrams arriving on the indicated address and port, which will +be interpreted as though they had been issued by a serial device. Example: +udp://127.0.0.1:5000. + + + +Ntrip caster + +A URI with the prefix "ntrip://" followed by the name of an +Ntrip caster (Ntrip is a protocol for broadcasting differential-GPS +fixes over the net). For Ntrip services that require authentication, a +prefix of the form "username:password@" can be added before the name +of the Ntrip broadcaster. For Ntrip service, you must specify which +stream to use; the stream is given in the form "/streamname". An +example DGPSIP URI could be "dgpsip://dgpsip.example.com" and a Ntrip +URI could be +"ntrip://foo:bar@ntrip.example.com:80/example-stream". Corrections +from the caster will be send to each attached GPS with the capability +to accept them. + + + +DGPSIP server + +A URI with the prefix "dgpsip://" followed by a hostname, a +colon, and an optional colon-separated port number (defaulting to +2101). The daemon will handshake with the DGPSIP server and +read RTCM2 correction data from it. Corrections +from the server will be set to each attached GPS with the capability +to accept them.Example: +dgpsip://dgps.wsrcc.com:2101. + + + + +(The "ais:://" source type supported in some older versions of +the daemon has been retired in favor of the more general +"tcp://".) + +Internally, the daemon maintains a device pool holding the +pathnames of devices and remote servers known to the +daemon. Initially, this list is the list of device-name arguments +specified on the command line. That list may be empty, in which case +the daemon will have no devices on its search list until they are +added by a control-socket command (see for +details on this). Daemon startup will abort with an error if neither +any devices nor a control socket are specified. + +Clients communicate with the daemon via textual request and +responses. It is a bad idea for applications to speak the protocol +directly: rather, they should use the +libgps client library and take appropriate +care to conditionalize their code on the major and minor protocol +version symbols. + + +REQUEST/RESPONSE PROTOCOL + +The GPSD protocol is built on top of JSON, JaveScript +Object Notation. Use of this metaprotocol to pass structured +data between daemon and client avoids the non-extensibility +problems of the old protocol, and permits a richer set of record types +to be passed up to clients. + +A request line is introduced by "?" and may include multiple +commands. Commands begin with a command identifier, followed either +by a terminating ';' or by an equal sign "=" and a JSON object treated +as an argument. Any ';' or newline indication (either LF or CR-LF) +after the end of a command is ignored. All request lines must be +composed of US-ASCII characters and may be no more than 80 characters +in length, exclusive of the trailing newline. + +Responses are JSON objects all of which have a "class" attribute +the value of which is either the name of the invoking command +or one of the strings "DEVICE" or "ERROR". Their length +limit is 1024 characters, including trailing newline. + +The remainder of this section documents the core GPSD protocol. +Extensions are docomented in the following sections. The extensions +may not be supported in your gpsd instance +if it has been compiled with a restricted feature set. + +Here are the core-protocol responses: + + + +TPV + +A TPV object is a time-position-velocity report. The "class" and "mode" +fields will reliably be present. Others may be reported or not +depending on the fix quality. + +
+{$blurb} + + +
+

A filled circle means the satellite was used in +the last fix. Green-yellow-red colors indicate signal strength in dB, + green=most and red=least. Diamonds indicate SBAS satellites.

+{$gmap_code}
To get real-time information, connect to +telnet://{$advertise}:{$port}/ and type "?POLL;" +or "?WATCH={"enable":true,"raw":true}".
+Use a different server:
+
+: + +
+
+
The gpsd instance that this page monitors is not running.
+ + + + + + + + + +
Current Information
Time (UTC){$ts}
Latitude{$GPS['fixes'][0]['lat']}
Longitude{$GPS['fixes'][0]['lon']}
Altitude{$GPS['fixes'][0]['alt']}
Fix Type{$GPS['fixes'][0]['mode']}
Satellites{$nsv}
HDOP{$GPS['skyviews'][0]['hdop']}
+
TPV object + + + + Name + Always? + Type + Description + + + + + class + Yes + string + Fixed: "TPV" + + + tag + No + string + Type tag associated with this GPS sentence; from an NMEA + device this is just the NMEA sentence type.. + + + device + No + string + Name of originating device + + + time + No + numeric + Seconds since the Unix epoch, UTC. May have a + fractional part of up to .01sec precision. + + + ept + No + numeric + Estimated timestamp error (%f, seconds, 95% confidence). + + + lat + No + numeric + Latitude in degrees: +/- signifies West/East + + + lon + No + numeric + Longitude in degrees: +/- signifies North/South. + + + alt + No + numeric + Altitude in meters. + + + epx + No + numeric + Longitude error estimate in meters, 95% confidence. + + + epy + No + numeric + Latitude error estimate in meters, 95% confidence. + + + epv + No + numeric + Estimated vertical error in meters, 95% confidence. + + + track + No + numeric + Course over ground, degrees from true north. + + + speed + No + numeric + Speed over ground, meters per second. + + + climb + No + numeric + Climb (positive) or sink (negative) rate, meters per + second. + + + epd + No + numeric + Direction error estimate in degrees, 95% confifdence. + + + eps + No + numeric + Speed error estinmate in meters/sec, 95% confifdence. + + + epc + No + numeric + Climb/sink error estinmate in meters/sec, 95% confifdence. + + + mode + Yes + numeric + NMEA mode: %d, 0=no mode value yet seen, 1=no fix, 2=2D, 3=3D. + + + + +
+ +When the C client library parses a response of this kind, it +will assert validity bits in the top-level set member for each +field actually received; see gps.h for bitmask names and values. + +Here's an example: + + +{"class":"TPV","tag":"MID2","device":"/dev/pts/1", + "time":1118327688.280,"ept":0.005, + "lat":46.498293369,"lon":7.567411672,"alt":1343.127, + "eph":36.000,"epv":32.321, + "track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} + + + + + +SKY + +A SKY object reports a sky view of the GPS satellite positions. +If there is no GPS device available, or no skyview has been reported +yet, only the "class" field will reliably be present. + +SKY object + + + + Name + Always? + Type + Description + + + + + class + Yes + string + Fixed: "SKY" + + + tag + No + string + Type tag associated with this GPS sentence; from an NMEA + device this is just the NMEA sentence type.. + + + device + No + string + Name of originating device + + + time + No + numeric + Seconds since the Unix epoch, UTC. May have a + fractional part of up to .01sec precision. + + + xdop + No + numeric + Longitudinal dilution of precision, a dimensionsless + factor which should be multiplied by a base UERE to get an + error estimate. + + + ydop + No + numeric + Latitudinal dilution of precision, a dimensionsless + factor which should be multiplied by a base UERE to get an + error estimate. + + + vdop + No + numeric + Altitude dilution of precision, a dimensionsless + factor which should be multiplied by a base UERE to get an + error estimate. + + + tdop + No + numeric + Time dilution of precision, a dimensionsless + factor which should be multiplied by a base UERE to get an + error estimate. + + + hdop + No + numeric + Horizontal dilution of precision, a dimensionsless + factor which should be multiplied by a base UERE to get a + circular error estimate. + + + pdop + No + numeric + Spherical dilution of precision, a dimensionsless + factor which should be multiplied by a base UERE to get an + error estimate. + + + gdop + No + numeric + Hyperspherical dilution of precision, a dimensionsless + factor which should be multiplied by a base UERE to get an + error estimate. + + + xdop + No + numeric + Longitudinal dilution of precision, a dimensionsless + factor which should be multiplied by a base UERE to get an + error estimate. + + + satellites + Yes + list + List of satellite objects in skyview + + + + +
+ +Many devices compute dilution of precision factors but do nit +include them in their reports. Many that do report DOPs report only +HDOP, two-dimensial circular error. gpsd +always passes through whatever the device actually reports, then +attempts to fill in other DOPs by calculating the appropriate +determinants in a covariance matrix based on the satellite view. DOPs +may be missing if some of these determinants are singular. It can even +happen that the device reports an error estimate in meters when the +correspoding DOP is unavailable; some devices use more sophisticated +error modeling than the covariance calculation. + +The satellite list objects have the following elements: + +Satellite object + + + + Name + Always? + Type + Description + + + + + PRN + Yes + numeric + PRN ID of the satellite + + + az + Yes + numeric + Azimuth, degrees from true north. + + + el + Yes + numeric + Elevation in degrees. + + + ss + Yes + numeric + Signal strength in dB. + + + used + Yes + boolean + Used in current solution? + + + +
+ +Note that satellite objects do not have a "class" field.., as +they are never shipped outside of a SKY object. + +When the C client library parses a SKY response, it +will assert the SATELLITE_SET bit in the top-level set member. + +Here's an example: + + +{"class":"SKY","tag":"MID2","device":"/dev/pts/1","time":1118327688.280 + "xdop":1.55,"hdop":1.24,"pdop":1.99, + "satellites":[ + {"PRN":23,"el":6,"az":84,"ss":0,"used":false}, + {"PRN":28,"el":7,"az":160,"ss":0,"used":false}, + {"PRN":8,"el":66,"az":189,"ss":44,"used":true}, + {"PRN":29,"el":13,"az":273,"ss":0,"used":false}, + {"PRN":10,"el":51,"az":304,"ss":29,"used":true}, + {"PRN":4,"el":15,"az":199,"ss":36,"used":true}, + {"PRN":2,"el":34,"az":241,"ss":43,"used":true}, + {"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} + + +
+
+ + +ATT + +An ATT object is a vehicle-attitude report. It is returned by +digital-compass and gyroscope sensors; depending on device, it may +include: heading, pitch, roll, yaw, gyroscope, and magnetic-field +readings. Because such sensors are often bundled as part of +marine-navigation systems, the ATT response may also include +water depth. + +The "class", "mode", and "tag" fields will reliably be present. Others +may be reported or not depending on the specific device type. + +ATT object + + + + Name + Always? + Type + Description + + + + + class + Yes + string + Fixed: "ATT" + + + tag + Yes + string + Type tag associated with this GPS sentence; from an NMEA + device this is just the NMEA sentence type.. + + + device + Yes + string + Name of originating device + + + time + Yes + numeric + Seconds since the Unix epoch, UTC. May have a + fractional part of up to .01sec precision. + + + heading + No + numeric + Heading, degrees from true north. + + + mag_st + No + string + Magnetometer status. + + + pitch + No + numeric + Pitch in degrees. + + + pitch_st + No + string + Pitch sensor status. + + + yaw + No + numeric + Yaw in degrees + + + yaw_st + No + string + Yaw sensor status. + + + roll + No + numeric + Roll in degrees. + + + roll_st + No + string + Roll sensor status. + + + dip + No + numeric + Roll in degrees. + + + mag_len + No + numeric + Scalar magnetic field strength. + + + mag_x + No + numeric + X component of magnetic field strength. + + + mag_y + No + numeric + Y component of magnetic field strength.. + + + mag_z + No + numeric + Z component of magnetic field strength.. + + + mag_len + No + numeric + Scalar acceleration. + + + acc_x + No + numeric + X component of acceleration. + + + acc_y + No + numeric + Y component of acceleration. + + + acc_z + No + numeric + Z component of acceleration.. + + + gyro_x + No + numeric + X component of acceleration. + + + gyro_y + No + numeric + Y component of acceleration. + + + depth + No + numeric + Water depth in meters. + + + temperature + No + numeric + Temperature at sensir, degrees centigrade. + + + + + +
+ +The heading, pitch, and roll status codes (if present) vary by device. +For the TNT Revolution digital compasses, they are coded as follows: + +Device flags + + + + Code + Description + + + + + C + magnetometer calibration alarm + + + L + low alarm + + + M + low warning + + + N + normal + + + O + high warning + + + P + high alarm + + + V + magnetometer voltage level alarm + + + +
+ + +When the C client library parses a response of this kind, it +will assert ATT_IS. + +Here's an example: + + +{"class":"ATT","tag":"PTNTHTM","time":1270938096.843, + "heading":14223.00,"mag_st":"N", + "pitch":169.00,"pitch_st":"N", "roll":-43.00,"roll_st":"N", + "dip":13641.000,"mag_x":2454.000,"temperature":0.000,"depth":0.000} + +
+
+ + + +And here are the commands: + + + + +?VERSION; +Returns an object with the following attributes: + +VERSION object + + + + Name + Always? + Type + Description + + + + + class + Yes + string + Fixed: "VERSION" + + + release + Yes + string + Public release level + + + rev + Yes + string + Internal revision-control level. + + + proto_major + Yes + numeric + API major revision level.. + + + proto_minor + Yes + numeric + API minor revision level.. + + + +
+ +The daemon ships a VERSION response to each client when the +client first connects to it. + +When the C client library parses a response of this kind, it +will assert the VERSION_SET bit in the top-level set member. + +Here's an example: + + +{"class":"VERSION","version":"2.40dev","rev":"06f62e14eae9886cde907dae61c124c53eb1101f","proto_major":3,"proto_minor":1} + + + +
+
+ + +?DEVICES; +Returns a device list object with the +following elements: + +DEVICES object + + + + Name + Always? + Type + Description + + + + + class + Yes + string + Fixed: "DEVICES" + + + devices + Yes + list + List of device descriptions + + + +
+ +When the C client library parses a response of this kind, it +will assert the DEVICELIST_SET bit in the top-level set member. + +Here's an example: + + +{"class"="DEVICES","devices":[ + {"class":"DEVICE","path":"/dev/pts/1","flags":1,"driver":"SiRF binary"}, + {"class":"DEVICE","path":"/dev/pts/3","flags":4,"driver":"AIVDM"}]} + + +The daemon occasionally ships a bare DEVICE object to the client +(that is, one not inside a DEVICES wrapper). The data content of these +objects will be described later in the section covering +notifications. + +
+
+ + +?WATCH; + + +This command sets watcher mode. It also sets or elicits a report +of per-subscriber policy and the raw bit. An argument WATCH object +changes the subscriber's policy. The responce describes the +subscriber's policy. The response will also include a DEVICES +object. + +A WATCH object has the following elements: + +WATCH object + + + + Name + Always? + Type + Description + + + + + class + Yes + string + Fixed: "WATCH" + + + enable + No + boolean + Enable (true) or disable (false) watcher mode. Default + is true. + + + json + No + boolean + Enable (true) or disable (false) dumping of JSON reports. + Default is false. + + + nmea + No + boolean + Enable (true) or disable (false) dumping of binary + packets as pseudo-NMEA. Default + is false. + + + raw + No + integer + + Controls 'raw' mode. When this attribute is set to 1 + for a channel, gpsd reports the + unprocessed NMEA or AIVDM data stream from whatever device is attached. + Binary GPS packets are hex-dumped. RTCM2 and RTCM3 + packets are not dumped in raw mode. + + + scaled + No + boolean + If true, apply scaling divisors to output before + dumping; default is false. Applies only to AIS reports. + + + device + No + string + If present, enable watching only of the specified device + rather than all devices. Useful with raw and NMEA modes + in which device responses aren't tagged. Has no effect when + used with enable:false. + + + +
+ +There is an additional boolean "timing" attribute which is +undocumented because that portion of the interface is considered +unstable and for developer use only. + +In watcher mode, GPS reports are dumped as TPV and SKY +responses. AIS and RTCM reporting is described in the next section. + +When the C client library parses a response of this kind, it +will assert the POLICY_SET bit in the top-level set member. + +Here's an example: + + +{"class":"WATCH", "raw":1,"scaled":true} + + +
+
+ + +?POLL; + + +The POLL command requests data from the last-seen fixes on all +active GPS devices. Devices must previously have been activated by +?WATCH to be pollable, or have been specified on the GPSD command line +together with an option. + +Polling can lead to possibly surprising results when it is used +on a device such as an NMEA GPS for which a complete fix has to be +accumulated from several sentences. If you poll while those sentences +are being emitted, the response will contain the last complete fix +data and may be as much as one cycle time (typically 1 second) +stale. + +The POLL response will contain a timestamped list of TPV objects +describing cached data, and a timestamped list of SKY objects +describing satellite configuration. If a device has not seen fixes, it +will be reported with a mode field of zero. + +POLL object + + + + Name + Always? + Type + Description + + + + + class + Yes + string + Fixed: "POLL" + + + time + Yes + Numeric + Seconds since the Unix epoch, UTC. May have a + fractional part of up to .001sec precision. + + + active + Yes + Numeric + Count of active devices. + + + fixes + Yes + JSON array + Comma-separated list of TPV objects. + + + skyviews + Yes + JSON array + Comma-separated list of SKY objects. + + + +
+ +Here's an example of a POLL response: + + +{"class":"POLL","timestamp":1270517274.846,"active":1, + "fixes":[{"class":"TPV","tag":"MID41","device":"/dev/ttyUSB0", + "time":1270517264.240,"ept":0.005,"lat":40.035093060, + "lon":-75.519748733,"track":99.4319,"speed":0.123,"mode":2}], + "skyviews":[{"class":"SKY","tag":"MID41","device":"/dev/ttyUSB0", + "time":1270517264.240,"hdop":9.20, + "satellites":[{"PRN":16,"el":55,"az":42,"ss":36,"used":true}, + {"PRN":19,"el":25,"az":177,"ss":0,"used":false}, + {"PRN":7,"el":13,"az":295,"ss":0,"used":false}, + {"PRN":6,"el":56,"az":135,"ss":32,"used":true}, + {"PRN":13,"el":47,"az":304,"ss":0,"used":false}, + {"PRN":23,"el":66,"az":259,"ss":0,"used":false}, + {"PRN":20,"el":7,"az":226,"ss":0,"used":false}, + {"PRN":3,"el":52,"az":163,"ss":32,"used":true}, + {"PRN":31,"el":16,"az":102,"ss":0,"used":false} +]}]} + + + +Client software should not assime the field inventory of the +POLL response is fixed for all time. As +gpsd collects and caches more data from +more sensor types, those data are likely to find their way +into this response. + + +
+
+ + +?DEVICE + + +This command reports (when followed by ';') the state of a +device, or sets (when followed by '=' and a DEVICE object) +device-specific control bits, notably the device's speed and serial +mode and the native-mode bit. The parameter-setting form will be rejected if +more than one client is attached to the channel. + +Pay attention to the response, because it is +possible for this command to fail if the GPS does not support a +speed-switching command or only supports some combinations of +serial modes. In case of failure, the daemon and GPS will +continue to communicate at the old speed. + +Use the parameter-setting form with caution. On USB and +Bluetooth GPSes it is also possible for serial mode setting to fail +either because the serial adaptor chip does not support non-8N1 modes +or because the device firmware does not properly synchronize the +serial adaptor chip with the UART on the GPS chipset whjen the speed +changes. These failures can hang your device, possibly requiring a GPS +power cycle or (in extreme cases) physically disconnecting the NVRAM +backup battery. + +A DEVICE object has the following elements: + +CONFIGCHAN object + + + + Name + Always? + Type + Description + + + + + class + Yes + string + Fixed: "DEVICE" + + + path + No + string + Name the device for which the control bits are + being reported, or for which they are to be applied. This + attribute may be omitted only when there is exactly one + subscribed channel. + + + activated + At device activation and device close time. + numeric + Time the device was activated, + or 0 if it is being closed. + + + flags + No + integer + Bit vector of property flags. Currently defined flags are: + describe packet types seen so far (GPS, RTCM2, RTCM3, + AIS). Won't be reported if empty, e.g. before + gpsd has seen identifiable packets + from the device. + + + driver + No + string + GPSD's name for the device driver type. Won't be reported before + gpsd has seen identifiable packets + from the device. + + + subtype + When the daemon sees a delayed response to a probe for + subtype or firmware-version information. + string + Whatever version information the device returned. + + + bps + No + integer + Device speed in bits per second. + + + parity + Yes + string + N, O or E for no parity, odd, or even. + + + stopbits + Yes + string + Stop bits (1 or 2). + + + native + No + integer + 0 means NMEA mode and 1 means + alternate mode (binary if it has one, for SiRF and Evermore chipsets + in particular). Attempting to set this mode on a non-GPS + device will yield an error. + + + cycle + No + real + Device cycle time in seconds. + + + mincycle + No + real + Device minimum cycle time in seconds. Reported from + ?CONFIGDEV when (and only when) the rate is switchable. It is + read-only and not settable. + + + +
+ +The serial parameters will be omitted in a response describing a +TCP/IP source such as an Ntrip, DGPSIP, or AIS feed. + +The contents of the flags field should be interpreted as follows: + +Device flags + + + + C #define + Value + Description + + + + + SEEN_GPS + 0x01 + GPS data has been seen on this device + + + SEEN_RTCM2 + 0x02 + RTCM2 data has been seen on this device + + + SEEN_RTCM3 + 0x04 + RTCM3 data has been seen on this device + + + SEEN_AIS + 0x08 + AIS data has been seen on this device + + + +
+ + + +When the C client library parses a response of this kind, it +will assert the DEVICE_SET bit in the top-level set member. + +Here's an example: + + +{"class":"DEVICE", "speed":4800,"serialmode":"8N1","native":0} + + +
+
+ +
+ +When a client is in watcher mode, the daemon will ship it DEVICE +notifications when a device is added to the pool or +deactivated. + +When the C client library parses a response of this kind, it +will assert the DEVICE_SET bit in the top-level set member. + +Here's an example: + + +{"class":"DEVICE","path":"/dev/pts1","activated":0} + + +The daemon may ship an error object in response to a +syntactically invalid command line or unknown command. It has +the following elements: + +ERROR notification object + + + + Name + Always? + Type + Description + + + + + class + Yes + string + Fixed: "ERROR" + + + message + Yes + string + Textual error message + + + +
+ +Here's an example: + + +{"class":"ERROR","message":"Unrecognized request '?FOO'"} + + +When the C client library parses a response of this kind, it +will assert the ERR_SET bit in the top-level set member. + + +AIS AND RTCM DUMP FORMATS + +AIS support is an extension. It may not be present if your +instance of gpsd has been built with +a restricted feature set. + +AIS packets are dumped as JSON objects with class "AIS". Each +AIS report object contains a "type" field giving the AIS message type +and a "scaled" field telling whether the remainder of the fields are +dumped in scaled or unscaled form. Other fields have names and types +as specified in the AIVDM/AIVDO Protocol +Decoding document; each message field table may be directly +interpreted as a specification for the members of the corresponding +JSON object type. + +RTCM2 corrections are dumped in the JSON format described in +rtcm1045. + + +GPS DEVICE MANAGEMENT + +gpsd maintains an internal list of +GPS devices (the "device pool"). If you specify devices on the +command line, the list is initialized with those pathnames; otherwise +the list starts empty. Commands to add and remove GPS device paths +from the daemon's device list must be written to a local Unix-domain +socket which will be accessible only to programs running as root. +This control socket will be located wherever the -F option specifies +it. + +A device may will also be dropped from the pool if GPSD gets a zero +length read from it. This end-of-file condition indicates that the' +device has been disconnected. + +When gpsd is properly installed along +with hotplug notifier scripts feeding it device-add commands over the +control socket, gpsd should require no +configuration or user action to find devices. + +Sending SIGHUP to a running gpsd +forces it to close all GPSes and all client connections. It will then +attempt to reconnect to any GPSes on its device list and resume +listening for client connections. This may be useful if your GPS +enters a wedged or confused state but can be soft-reset by pulling +down DTR. + +To point gpsd at a device that may be +a GPS, write to the control socket a plus sign ('+') followed by the +device name followed by LF or CR-LF. Thus, to point the daemon at +/dev/foo. send "+/dev/foo\n". To tell the daemon +that a device has been disconnected and is no longer available, send a +minus sign ('-') followed by the device name followed by LF or +CR-LF. Thus, to remove /dev/foo from the search +list. send "-/dev/foo\n". + +To send a control string to a specified device, write to the +control socket a '!', followed by the device name, followed by '=', +followed by the control string. + +To send a binary control string to a specified device, write to the +control socket a '&', followed by the device name, followed by '=', +followed by the control string in paired hex digits. + +Your client may await a response, which will be a line beginning +with either "OK" or "ERROR". An ERROR reponse to an add command means +the device did not emit data recognizable as GPS packets; an ERROR +response to a remove command means the specified device was not in +gpsd's device pool. An ERROR response to a +! command means the daemon did not recognize the devicename +specified. + +The control socket is intended for use by hotplug scripts and +other device-discovery services. This control channel is separate +from the public gpsd service port, and only +locally accessible, in order to prevent remote denial-of-service and +spoofing attacks. + + +ACCURACY + +The base User Estimated Range Error (UERE) of GPSes is 8 meters +or less at 66% confidence, 15 meters or less at 95% confidence. Actual +horizontal error will be UERE times a dilution factor dependent on current +satellite position. Altitude determination is more sensitive to +variability in ionospheric signal lag than latitude/longitude is, and is +also subject to errors in the estimation of local mean sea level; base +error is 12 meters at 66% confidence, 23 meters at 95% confidence. +Again, this will be multiplied by a vertical dilution of precision +(VDOP) dependent on satellite geometry, and VDOP is typically larger +than HDOP. Users should not rely on GPS altitude for +life-critical tasks such as landing an airplane. + +These errors are intrinsic to the design and physics of the GPS +system. gpsd does its internal +computations at sufficient accuracy that it will add no measurable +position error of its own. + +DGPS correction will reduce UERE by a factor of 4, provided you +are within about 100mi (160km) of a DGPS ground station from which you +are receiving corrections. + +On a 4800bps connection, the time latency of fixes provided by +gpsd will be one second or less 95% of the +time. Most of this lag is due to the fact that GPSes normally emit +fixes once per second, thus expected latency is 0.5sec. On the +personal-computer hardware available in 2005, computation lag induced +by gpsd will be negligible, on the order of +a millisecond. Nevertheless, latency can introduce significant errors +for vehicles in motion; at 50km/h (31mi/h) of speed over ground, 1 +second of lag corresponds to 13.8 meters change in position between +updates. + +The time reporting of the GPS system itself has an intrinsic +accuracy limit of 0.000,000,340 = +3.4×10-7 seconds. A more important +limit is the GPS tick rate. While the one-per-second PPS pulses +emitted by serial GPS units are timed to the GPS system's intrinsic +accuracy limit,the satellites only emit navigation messages at +0.01-second intervals, and the timestamps in them only carry +0.01-second precision. Thus, the timestamps that +gpsd reports in time/position/velocity +messages are normally accurate only to 1/100th of a second. + + +USE WITH NTP + +gpsd can provide reference clock information to +ntpd, to keep the system clock synchronized +to the time provided by the GPS receiver. This facility is +only available when the daemon is started from root. If you're going +to use gpsd you probably want to run it + mode so the clock will be updated even when no +clients are active. + +Note that deriving time from messages received from the GPS is +not as accurate as you might expect. Messages are often delayed in +the receiver and on the link by several hundred milliseconds, and this +delay is not constant. On Linux, gpsd +includes support for interpreting the PPS pulses emitted at the start +of every clock second on the carrier-detect lines of some serial +GPSes; this pulse can be used to update NTP at much higher accuracy +than message time provides. You can determine whether your GPS emits +this pulse by running at -D 5 and watching for carrier-detect state +change messages in the logfile. + +When gpsd receives a sentence with a +timestamp, it packages the received timestamp with current local time +and sends it to a shared-memory segment with an ID known to +ntpd, the network time synchronization +daemon. If ntpd has been properly +configured to receive this message, it will be used to correct the +system clock. + +Here is a sample ntp.conf configuration +stanza telling ntpd how to read the GPS +notfications: + + +server 127.127.28.0 minpoll 4 maxpoll 4 +fudge 127.127.28.0 time1 0.420 refid GPS + +server 127.127.28.1 minpoll 4 maxpoll 4 prefer +fudge 127.127.28.1 refid GPS1 + + +The magic pseudo-IP address 127.127.28.0 identifies unit 0 of +the ntpd shared-memory driver; 127.127.28.1 +identifies unit 1. Unit 0 is used for message-decoded time and unit 1 +for the (more accurate, when available) time derived from the PPS +synchronization pulse. Splitting these notifications allows +ntpd to use its normal heuristics to weight +them. + +With this configuration, ntpd will +read the timestamp posted by gpsd every 16 +seconds and send it to unit 0. The number after the parameter time1 +is an offset in seconds. You can use it to adjust out some of the +fixed delays in the system. 0.035 is a good starting value for the +Garmin GPS-18/USB, 0.420 for the Garmin GPS-18/LVC. + +After restarting ntpd, a line similar to the one below should +appear in the output of the command "ntpq -p" (after allowing a couple +of minutes): + + +remote refid st t when poll reach delay offset jitter +========================================================================= ++SHM(0) .GPS. 0 l 13 16 377 0.000 0.885 0.882 + + +If you are running PPS then it will look like this: + + +remote refid st t when poll reach delay offset jitter +========================================================================= +-SHM(0) .GPS. 0 l 13 16 377 0.000 0.885 0.882 +*SHM(1) .GPS1. 0 l 11 16 377 0.000 -0.059 0.006 + + +When the value under "reach" remains zero, check that gpsd is +running; and some application is connected to it or the '-n' option was +used. Make sure the receiver is locked on to at least one satellite, +and the receiver is in SiRF binary, Garmin binary or NMEA/PPS mode. Plain +NMEA will also drive ntpd, but the accuracy as bad as one second. When +the SHM(0) line does not appear at all, check the system logs for error +messages from ntpd. + +When no other reference clocks appear in the NTP configuration, +the system clock will lock onto the GPS clock. When you have previously +used ntpd, and other reference clocks appear +in your configuration, there may be a fixed offset between the GPS clock +and other clocks. The gpsd developers would +like to receive information about the offsets observed by users for each +type of receiver. Please send us the output of the "ntpq -p" command +and the make and type of receiver. + + +USE WITH D-BUS + +On operating systems that support D-BUS, +gpsd can be built to broadcast GPS fixes to +D-BUS-aware applications. As D-BUS is still at a pre-1.0 stage, we +will not attempt to document this interface here. Read the +gpsd source code to learn more. + + +SECURITY AND PERMISSIONS ISSUES + +gpsd, if given the -G flag, will +listen for connections from any reachable host, and then disclose the +current position. Before using the -G flag, consider whether you +consider your computer's location to be sensitive data to be kept +private or something that you wish to publish. + +gpsd must start up as root in order +to open the NTPD shared-memory segment, open its logfile, and create +its local control socket. Before doing any processing of GPS data, it +tries to drop root privileges by setting its UID to "nobody" (or another +userid as set by configure) and its group ID to the group of the initial +GPS passed on the command line — or, if that device doesn't exist, +to the group of /dev/ttyS0. + +Privilege-dropping is a hedge against the possibility that +carefully crafted data, either presented from a client socket or from +a subverted serial device posing as a GPS, could be used to induce +misbehavior in the internals of gpsd. +It ensures that any such compromises cannot be used for privilege +elevation to root. + +The assumption behind gpsd's +particular behavior is that all the tty devices to which a GPS might +be connected are owned by the same non-root group and allow group +read/write, though the group may vary because of distribution-specific +or local administrative practice. If this assumption is false, +gpsd may not be able to open GPS devices in +order to read them (such failures will be logged). + +In order to fend off inadvertent denial-of-service attacks by +port scanners (not to mention deliberate ones), +gpsd will time out inactive client +connections. Before the client has issued a command that requests a +channel assignment, a short timeout (60 seconds) applies. There is no +timeout for clients in watcher or raw modes; rather, +gpsd drops these clients if they fail to +read data long enough for the outbound socket write buffer to fill. +Clients with an assigned device in polling mode are subject to a +longer timeout (15 minutes). + + +LIMITATIONS + +If multiple NMEA talkers are feeding RMC, GLL, and GGA sentences +to the same serial device (possible with an RS422 adapter hooked up to +some marine-navigation systems), a 'TPV' response may mix an altitude +from one device's GGA with latitude/longitude from another's RMC/GLL +after the second sentence has arrived. + +gpsd may change control settings on +your GPS (such as the emission frequency of various sentences or +packets) and not restore the original settings on exit. This is a +result of inadequacies in NMEA and the vendor binary GPS protocols, +which often do not give clients any way to query the values of control +settings in order to be able to restore them later. + +If your GPS uses a SiRF chipset at firmware level 231, reported +UTC time may be off by the difference between 13 seconds and whatever +leap-second correction is currently applicable, from startup until +complete subframe information is received (normally about six +seconds). Firmware levels 232 and up don't have this problem. You +may run gpsd at debug level 4 to see the +chipset type and firmware revision level. + +When using SiRF chips, the VDOP/TDOP/GDOP figures and associated +error estimates are computed by gpsd rather +than reported by the chip. The computation does not exactly match +what SiRF chips do internally, which includes some satellite weighting +using parameters gpsd cannot see. + +Autobauding on the Trimble GPSes can take as long as 5 seconds +if the device speed is not matched to the GPS speed. + +If you are using an NMEA-only GPS (that is, not using SiRF or +Garmin or Zodiac binary mode) and the GPS does not emit GPZDA at the +start of its update cycle (which most consumer-grade NMEA GPSes do +not) and it is after 2099, then the century part of the dates +gpsd delivers will be wrong. + +Generation of position error estimates (eph, epv, epd, eps, epc) +from the incomplete data handed back by GPS reporting protocols +involves both a lot of mathematical black art and fragile +device-dependent assumptions. This code has been bug-prone in tbe +past and problems may still lurk there. + + +FILES + + + +/dev/ttyS0 + +Prototype TTY device. After startup, +gpsd sets its group ID to the owner of this +device if no GPS device was specified on the command line does not +exist. + + + + + + +APPLICABLE STANDARDS + +The official NMEA protocol standard is available on paper from +the National Marine +Electronics Association, but is proprietary and expensive; the +maintainers of gpsd have made a point of +not looking at it. The GPSD +website links to several documents that collect publicly +disclosed information about the protocol. + +gpsd parses the following NMEA +sentences: RMC, GGA, GLL, GSA, GSV, VTG, ZDA. It recognizes these +with either the normal GP talker-ID prefix, or with the GN prefix used +by GLONASS, or with the II prefix emitted by Seahawk Autohelm marine +navigation systems, or with the IN prefix emitted by some Garmin +units. It recognizes some vendor extensions: the PGRME emitted by some +Garmin GPS models, the OHPR emitted by Oceanserver digital compasses, +the PTNTHTM emitted by True North digital compasses, and the PASHR +sentences emitted by some Ashtech GPSes. + +Note that gpsd JSON returns pure decimal +degrees, not the hybrid degree/minute format described in the NMEA +standard. + +Differential-GPS corrections are conveyed by the RTCM-104 +proocol. The applicable standard for RTCM-104 V2 is RTCM +Recommended Standards for Differential NAVSTAR GPS Service +RTCM Paper 194-93/SC 104-STD. The applicable standard for RTCM-104 V3 +is RTCM Standard 10403.1 for Differential GNSS Services - +Version 3 RTCM Paper 177-2006-SC104-STD. + +AIS is defined by ITU Recommendation M.1371, +Technical Characteristics for a Universal Shipborne +Automatic Identification System Using Time Division Multiple +Access. The AIVDM/AIVDO format understood by this progeam +is defined by IEC-PAS 61162-100, Maritime navigation and +radiocommunication equipment and systems + + +SEE ALSO + +gps1, +libgps3, +libgpsd3, +gpsprof1, +gpsfake1, +gpsctl1, +gpscat1, +rtcm-1045. + + + +AUTHORS + +Remco Treffcorn, Derrick Brashear, Russ Nelson, Eric S. Raymond, +Chris Kuethe. This manual page by Eric S. Raymond +esr@thyrsus.com. There is a project site. + + + diff --git a/gpsd_config.h b/gpsd_config.h new file mode 100644 index 0000000..af26ffa --- /dev/null +++ b/gpsd_config.h @@ -0,0 +1,396 @@ +/* gpsd_config.h. Generated from gpsd_config.h.in by configure. */ +/* gpsd_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* AIVDM protocol support) */ +#define AIVDM_ENABLE 1 + +/* Allow gpsd to controlsend device */ +#define ALLOW_CONTROLSEND 1 + +/* Allow gpsd to reconfigure device */ +#define ALLOW_RECONFIGURE 1 + +/* Ashtech chipset support */ +#define ASHTECH_ENABLE 1 + +/* client debugging support) */ +#define CLIENTDEBUG_ENABLE 1 + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* DBUS support */ +/* #undef DBUS_ENABLE */ + +/* DeLorme EarthMate Zodiac support */ +#define EARTHMATE_ENABLE 1 + +/* EverMore binary support */ +#define EVERMORE_ENABLE 1 + +/* Fixed port speed */ +/* #undef FIXED_PORT_SPEED */ + +/* San Jose Navigation FV-18 support */ +#define FV18_ENABLE 1 + +/* Garmin Simple Text support */ +#define GARMINTXT_ENABLE 1 + +/* Garmin support */ +#define GARMIN_ENABLE 1 + +/* GPSclock chipset support */ +#define GPSCLOCK_ENABLE 1 + +/* GPSD privilege revokation group */ +/* #undef GPSD_GROUP */ + +/* GPSD privilege revocation user */ +/* #undef GPSD_USER */ + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define if we have Bluez */ +/* #undef HAVE_BLUEZ */ + +/* Define if you have the external 'daylight' variable. */ +#define HAVE_DAYLIGHT 1 + +/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. + */ +/* #undef HAVE_DECL_TZNAME */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* pthread libraries are present */ +#define HAVE_LIBPTHREAD /**/ + +/* libusb support */ +/* #undef HAVE_LIBUSB */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NCURSES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NETINET_IP_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PYTHON_H */ + +/* Define to 1 if you have the `round' function. */ +/* #undef HAVE_ROUND */ + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcat' function. */ +/* #undef HAVE_STRLCAT */ + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef HAVE_STRLCPY */ + +/* Define to 1 if you have the `strtonum' function. */ +/* #undef HAVE_STRTONUM */ + +/* Define to 1 if `tm_zone' is a member of `struct tm'. */ +#define HAVE_STRUCT_TM_TM_ZONE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IPC_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MODEM_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SHM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Have timezone variable */ +#define HAVE_TIMEZONE /**/ + +/* struct tm has tm_gmtoff */ +/* #undef HAVE_TM_GMTOFF */ + +/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use + `HAVE_STRUCT_TM_TM_ZONE' instead. */ +#define HAVE_TM_ZONE 1 + +/* Define to 1 if you don't have `tm_zone' but do have the external array + `tzname'. */ +/* #undef HAVE_TZNAME */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 + +/* IPv6 support */ +#define IPV6_ENABLE 1 + +/* iTrax chipset support */ +#define ITRAX_ENABLE 1 + +/* C++ support */ +#define LIBGPSMM_ENABLE 1 + +/* Limited maximum clients */ +/* #undef LIMITED_MAX_CLIENTS */ + +/* Maximum gps devices */ +/* #undef LIMITED_MAX_DEVICES */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* MTK-3301 support */ +#define MTK3301_ENABLE 1 + +/* Navcom support */ +#define NAVCOM_ENABLE 1 + +/* MTK-3301 requires NMEA support */ +#define NMEA_ENABLE 1 + +/* NTP time hinting support */ +#define NTPSHM_ENABLE 1 + +/* NTRIP support */ +#define NTRIP_ENABLE 1 + +/* OceanServer support */ +#define OCEANSERVER_ENABLE 1 + +/* oldstyle (pre-JSON) protocol support */ +#define OLDSTYLE_ENABLE 1 + +/* Motorola OnCore chipset support */ +#define ONCORE_ENABLE 1 + +/* Name of package */ +#define PACKAGE "gpsd" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* PPS time syncing support */ +#define PPS_ENABLE 1 + +/* PPS on CTS rather than DCD */ +/* #undef PPS_ON_CTS */ + +/* profiling support */ +/* #undef PROFILING */ + +/* Raw Measurement support */ +#define RAW_ENABLE 1 + +/* rtcm104v2 binary support */ +#define RTCM104V2_ENABLE 1 + +/* rtcm104v3 binary support */ +#define RTCM104V3_ENABLE 1 + +/* SiRF chipset support */ +#define SIRF_ENABLE 1 + +/* The size of `char', as computed by sizeof. */ +#define SIZEOF_CHAR 1 + +/* The size of `double', as computed by sizeof. */ +#define SIZEOF_DOUBLE 8 + +/* The size of `float', as computed by sizeof. */ +#define SIZEOF_FLOAT 4 + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 4 + +/* The size of `long long', as computed by sizeof. */ +#define SIZEOF_LONG_LONG 8 + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* Squelch logging and hexdumps */ +/* #undef SQUELCH_ENABLE */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* SuperStarII chipset support */ +#define SUPERSTAR2_ENABLE 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* latency timing support) */ +#define TIMING_ENABLE 1 + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* True North Technologies support */ +#define TNT_ENABLE 1 + +/* DeLorme TripMate support */ +#define TRIPMATE_ENABLE 1 + +/* Trimble TSIP support */ +#define TSIP_ENABLE 1 + +/* UBX Protocol support */ +#define UBX_ENABLE 1 + +/* Version number of package */ +#define VERSION "2.95" + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Some libc's don't have strlcat/strlcpy. Local copies are provided */ +#ifndef HAVE_STRLCAT +# ifdef __cplusplus +extern "C" { +# endif +size_t strlcat(/*@out@*/char *dst, /*@in@*/const char *src, size_t size); +# ifdef __cplusplus +} +# endif +#endif +#ifndef HAVE_STRLCPY +# ifdef __cplusplus +extern "C" { +# endif +size_t strlcpy(/*@out@*/char *dst, /*@in@*/const char *src, size_t size); +# ifdef __cplusplus +} +# endif +#endif + +#define GPSD_CONFIG_H + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ diff --git a/gpsd_config.h.in b/gpsd_config.h.in new file mode 100644 index 0000000..f07d340 --- /dev/null +++ b/gpsd_config.h.in @@ -0,0 +1,395 @@ +/* gpsd_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* AIVDM protocol support) */ +#undef AIVDM_ENABLE + +/* Allow gpsd to controlsend device */ +#undef ALLOW_CONTROLSEND + +/* Allow gpsd to reconfigure device */ +#undef ALLOW_RECONFIGURE + +/* Ashtech chipset support */ +#undef ASHTECH_ENABLE + +/* client debugging support) */ +#undef CLIENTDEBUG_ENABLE + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* DBUS support */ +#undef DBUS_ENABLE + +/* DeLorme EarthMate Zodiac support */ +#undef EARTHMATE_ENABLE + +/* EverMore binary support */ +#undef EVERMORE_ENABLE + +/* Fixed port speed */ +#undef FIXED_PORT_SPEED + +/* San Jose Navigation FV-18 support */ +#undef FV18_ENABLE + +/* Garmin Simple Text support */ +#undef GARMINTXT_ENABLE + +/* Garmin support */ +#undef GARMIN_ENABLE + +/* GPSclock chipset support */ +#undef GPSCLOCK_ENABLE + +/* GPSD privilege revokation group */ +#undef GPSD_GROUP + +/* GPSD privilege revocation user */ +#undef GPSD_USER + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define if we have Bluez */ +#undef HAVE_BLUEZ + +/* Define if you have the external 'daylight' variable. */ +#undef HAVE_DAYLIGHT + +/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. + */ +#undef HAVE_DECL_TZNAME + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GRP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* pthread libraries are present */ +#undef HAVE_LIBPTHREAD + +/* libusb support */ +#undef HAVE_LIBUSB + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NCURSES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_SYSTM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_TCP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_PWD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_PYTHON_H + +/* Define to 1 if you have the `round' function. */ +#undef HAVE_ROUND + +/* Define to 1 if you have the `setlocale' function. */ +#undef HAVE_SETLOCALE + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcat' function. */ +#undef HAVE_STRLCAT + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strtonum' function. */ +#undef HAVE_STRTONUM + +/* Define to 1 if `tm_zone' is a member of `struct tm'. */ +#undef HAVE_STRUCT_TM_TM_ZONE + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IPC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MODEM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SHM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TERMIOS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TERMIOS_H + +/* Have timezone variable */ +#undef HAVE_TIMEZONE + +/* struct tm has tm_gmtoff */ +#undef HAVE_TM_GMTOFF + +/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use + `HAVE_STRUCT_TM_TM_ZONE' instead. */ +#undef HAVE_TM_ZONE + +/* Define to 1 if you don't have `tm_zone' but do have the external array + `tzname'. */ +#undef HAVE_TZNAME + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* IPv6 support */ +#undef IPV6_ENABLE + +/* iTrax chipset support */ +#undef ITRAX_ENABLE + +/* C++ support */ +#undef LIBGPSMM_ENABLE + +/* Limited maximum clients */ +#undef LIMITED_MAX_CLIENTS + +/* Maximum gps devices */ +#undef LIMITED_MAX_DEVICES + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* MTK-3301 support */ +#undef MTK3301_ENABLE + +/* Navcom support */ +#undef NAVCOM_ENABLE + +/* MTK-3301 requires NMEA support */ +#undef NMEA_ENABLE + +/* NTP time hinting support */ +#undef NTPSHM_ENABLE + +/* NTRIP support */ +#undef NTRIP_ENABLE + +/* OceanServer support */ +#undef OCEANSERVER_ENABLE + +/* oldstyle (pre-JSON) protocol support */ +#undef OLDSTYLE_ENABLE + +/* Motorola OnCore chipset support */ +#undef ONCORE_ENABLE + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* PPS time syncing support */ +#undef PPS_ENABLE + +/* PPS on CTS rather than DCD */ +#undef PPS_ON_CTS + +/* profiling support */ +#undef PROFILING + +/* Raw Measurement support */ +#undef RAW_ENABLE + +/* rtcm104v2 binary support */ +#undef RTCM104V2_ENABLE + +/* rtcm104v3 binary support */ +#undef RTCM104V3_ENABLE + +/* SiRF chipset support */ +#undef SIRF_ENABLE + +/* The size of `char', as computed by sizeof. */ +#undef SIZEOF_CHAR + +/* The size of `double', as computed by sizeof. */ +#undef SIZEOF_DOUBLE + +/* The size of `float', as computed by sizeof. */ +#undef SIZEOF_FLOAT + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* Squelch logging and hexdumps */ +#undef SQUELCH_ENABLE + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* SuperStarII chipset support */ +#undef SUPERSTAR2_ENABLE + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* latency timing support) */ +#undef TIMING_ENABLE + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* True North Technologies support */ +#undef TNT_ENABLE + +/* DeLorme TripMate support */ +#undef TRIPMATE_ENABLE + +/* Trimble TSIP support */ +#undef TSIP_ENABLE + +/* UBX Protocol support */ +#undef UBX_ENABLE + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Some libc's don't have strlcat/strlcpy. Local copies are provided */ +#ifndef HAVE_STRLCAT +# ifdef __cplusplus +extern "C" { +# endif +size_t strlcat(/*@out@*/char *dst, /*@in@*/const char *src, size_t size); +# ifdef __cplusplus +} +# endif +#endif +#ifndef HAVE_STRLCPY +# ifdef __cplusplus +extern "C" { +# endif +size_t strlcpy(/*@out@*/char *dst, /*@in@*/const char *src, size_t size); +# ifdef __cplusplus +} +# endif +#endif + +#define GPSD_CONFIG_H + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const diff --git a/gpsd_dbus.c b/gpsd_dbus.c new file mode 100644 index 0000000..21a2993 --- /dev/null +++ b/gpsd_dbus.c @@ -0,0 +1,77 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include "gpsd_config.h" +#ifdef DBUS_ENABLE +#include + +static DBusConnection *connection = NULL; + +/* + * Does what is required to initialize the dbus connection + * This is pretty basic at this point, as we don't receive commands via dbus. + * Returns 0 when everything is OK. + */ +int initialize_dbus_connection(void) +{ + DBusError error; + + dbus_error_init(&error); + connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + /* report error */ + return 1; + } + return 0; +} + +void send_dbus_fix(struct gps_device_t *channel) +{ +/* sends the current fix data for this channel via dbus */ + struct gps_data_t *gpsdata; + struct gps_fix_t *gpsfix; + DBusMessage *message; + /*DBusMessageIter iter; */ + dbus_uint32_t serial; /* collected, but not used */ + char *gpsd_devname; + /* this packet format was designed before we split eph */ + double eph; + + /* if the connection is non existent, return without doing anything */ + if (connection == NULL) + return; + + gpsdata = &(channel->gpsdata); + gpsfix = &(gpsdata->fix); + /* this packet format was designed before we split eph */ + eph = EMIX(gpsfix->epx, gpsfix->epy); + gpsd_devname = gpsdata->dev.path; + + /* Send the named signel. */ + message = dbus_message_new_signal("/org/gpsd", "org.gpsd", "fix"); + dbus_message_append_args(message, + DBUS_TYPE_DOUBLE, &(gpsfix->time), + DBUS_TYPE_INT32, &(gpsfix->mode), + DBUS_TYPE_DOUBLE, &(gpsfix->ept), + DBUS_TYPE_DOUBLE, &(gpsfix->latitude), + DBUS_TYPE_DOUBLE, &(gpsfix->longitude), + DBUS_TYPE_DOUBLE, &(eph), + DBUS_TYPE_DOUBLE, &(gpsfix->altitude), + DBUS_TYPE_DOUBLE, &(gpsfix->epv), + DBUS_TYPE_DOUBLE, &(gpsfix->track), + DBUS_TYPE_DOUBLE, &(gpsfix->epd), + DBUS_TYPE_DOUBLE, &(gpsfix->speed), + DBUS_TYPE_DOUBLE, &(gpsfix->eps), + DBUS_TYPE_DOUBLE, &(gpsfix->climb), + DBUS_TYPE_DOUBLE, &(gpsfix->epc), + DBUS_TYPE_STRING, &gpsd_devname, + DBUS_TYPE_INVALID); + dbus_message_set_no_reply(message, TRUE); + dbus_connection_send(connection, message, &serial); + dbus_message_unref(message); +} + +#endif /* DBUS_ENABLE */ diff --git a/gpsd_dbus.h b/gpsd_dbus.h new file mode 100644 index 0000000..e89fc94 --- /dev/null +++ b/gpsd_dbus.h @@ -0,0 +1,19 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#ifndef _GPSD_DBUS_H_ +#define _GPSD_DBUS_H_ + +#ifdef DBUS_ENABLE + +#include + +#include "gpsd.h" + +int initialize_dbus_connection (void); +void send_dbus_fix (struct gps_device_t* channel); + +#endif + +#endif /* _GPSD_DBUS_H_ */ diff --git a/gpsd_json.c b/gpsd_json.c new file mode 100644 index 0000000..42ead71 --- /dev/null +++ b/gpsd_json.c @@ -0,0 +1,1437 @@ +/**************************************************************************** + +NAME + gpsd_json.c - move data between in-core and JSON structures + +DESCRIPTION + These are functions (used only by the daemon) to dump the contents +of various core data structures in JSON. + +PERMISSIONS + Written by Eric S. Raymond, 2009 + This file is Copyright (c) 2010 by the GPSD project + BSD terms apply: see the file COPYING in the distribution root for details. + +***************************************************************************/ + +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "gps_json.h" +#include "revision.h" + +/* *INDENT-OFF* */ +/* + * Manifest names for the gnss_type enum - must be kept synced with it. + * Also, masks so we can tell what packet types correspond to each class. + */ +/* the map of device class names */ +struct classmap_t { + char *name; + int typemask; + int packetmask; +}; +#define CLASSMAP_NITEMS 5 + +struct classmap_t classmap[CLASSMAP_NITEMS] = { + /* name typemask packetmask */ + {"ANY", 0, 0}, + {"GPS", SEEN_GPS, GPS_TYPEMASK}, + {"RTCM2", SEEN_RTCM2, PACKET_TYPEMASK(RTCM2_PACKET)}, + {"RTCM3", SEEN_RTCM3, PACKET_TYPEMASK(RTCM3_PACKET)}, + {"AIS", SEEN_AIS, PACKET_TYPEMASK(AIVDM_PACKET)}, +}; +/* *INDENT-ON* */ + +char *json_stringify( /*@out@*/ char *to, + size_t len, + /*@in@*/ const char *from) +/* escape double quotes and control characters inside a JSON string */ +{ + /*@-temptrans@*/ + const char *sp; + char *tp; + + tp = to; + /* + * The limit is len-6 here because we need to be leave room for + * each character to generate an up to 6-character Java-style + * escape + */ + for (sp = from; *sp != '\0' && ((tp - to) < ((int)len - 5)); sp++) { + if (iscntrl(*sp)) { + *tp++ = '\\'; + switch (*sp) { + case '\b': + *tp++ = 'b'; + break; + case '\f': + *tp++ = 'f'; + break; + case '\n': + *tp++ = 'n'; + break; + case '\r': + *tp++ = 'r'; + break; + case '\t': + *tp++ = 't'; + break; + default: + /* ugh, we'd prefer a C-style escape here, but this is JSON */ + (void)snprintf(tp, 5, "%u04x", (unsigned int)*sp); + tp += strlen(tp); + } + } else { + if (*sp == '"' || *sp == '\\') + *tp++ = '\\'; + *tp++ = *sp; + } + } + *tp = '\0'; + + return to; + /*@+temptrans@*/ +} + +void json_version_dump( /*@out@*/ char *reply, size_t replylen) +{ + (void)snprintf(reply, replylen, + "{\"class\":\"VERSION\",\"release\":\"%s\",\"rev\":\"%s\",\"proto_major\":%d,\"proto_minor\":%d}\r\n", + VERSION, REVISION, + GPSD_PROTO_MAJOR_VERSION, GPSD_PROTO_MINOR_VERSION); +} + +void json_tpv_dump(const struct gps_data_t *gpsdata, + /*@out@*/ char *reply, size_t replylen) +{ + assert(replylen > 2); + (void)strlcpy(reply, "{\"class\":\"TPV\",", replylen); + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"tag\":\"%s\",", + gpsdata->tag[0] != '\0' ? gpsdata->tag : "-"); + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"device\":\"%s\",", gpsdata->dev.path); + if (isnan(gpsdata->fix.time) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"time\":%.3f,", gpsdata->fix.time); + if (isnan(gpsdata->fix.ept) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"ept\":%.3f,", gpsdata->fix.ept); + /* + * Suppressing TPV fields that would be invalid because the fix + * quality doesn't support them is nice for cutting down on the + * volume of meaningless output, but the real reason to do it is + * that we've observed that geodetic fix computation is unstable + * in a way that tends to change low-order digits in invalid + * fixes. Dumping these tends to cause cross-architecture failures + * in the regression tests. Rgus effect has been seen on SiRF-II + * chips, which are quite common. + */ + if (gpsdata->fix.mode >= MODE_2D) { + if (isnan(gpsdata->fix.latitude) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"lat\":%.9f,", gpsdata->fix.latitude); + if (isnan(gpsdata->fix.longitude) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"lon\":%.9f,", gpsdata->fix.longitude); + if (gpsdata->fix.mode >= MODE_3D && isnan(gpsdata->fix.altitude) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"alt\":%.3f,", gpsdata->fix.altitude); + if (isnan(gpsdata->fix.epx) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"epx\":%.3f,", gpsdata->fix.epx); + if (isnan(gpsdata->fix.epy) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"epy\":%.3f,", gpsdata->fix.epy); + if ((gpsdata->fix.mode >= MODE_3D) && isnan(gpsdata->fix.epv) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"epv\":%.3f,", gpsdata->fix.epv); + if (isnan(gpsdata->fix.track) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"track\":%.4f,", gpsdata->fix.track); + if (isnan(gpsdata->fix.speed) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"speed\":%.3f,", gpsdata->fix.speed); + if ((gpsdata->fix.mode >= MODE_3D) && isnan(gpsdata->fix.climb) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"climb\":%.3f,", gpsdata->fix.climb); + if (isnan(gpsdata->fix.epd) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"epd\":%.4f,", gpsdata->fix.epd); + if (isnan(gpsdata->fix.eps) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"eps\":%.2f,", gpsdata->fix.eps); + if ((gpsdata->fix.mode >= MODE_3D) && isnan(gpsdata->fix.epc) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"epc\":%.2f,", gpsdata->fix.epc); + } + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"mode\":%d,", gpsdata->fix.mode); + if (reply[strlen(reply) - 1] == ',') + reply[strlen(reply) - 1] = '\0'; /* trim trailing comma */ + (void)strlcat(reply, "}\r\n", sizeof(reply) - strlen(reply)); +} + +void json_sky_dump(const struct gps_data_t *datap, + /*@out@*/ char *reply, size_t replylen) +{ + int i, j, used, reported = 0; + assert(replylen > 2); + (void)strlcpy(reply, "{\"class\":\"SKY\",", replylen); + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"tag\":\"%s\",", + datap->tag[0] != '\0' ? datap->tag : "-"); + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"device\":\"%s\",", datap->dev.path); + if (isnan(datap->skyview_time) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"time\":%.3f,", datap->skyview_time); + if (isnan(datap->dop.xdop) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"xdop\":%.2f,", datap->dop.xdop); + if (isnan(datap->dop.ydop) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"ydop\":%.2f,", datap->dop.ydop); + if (isnan(datap->dop.vdop) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"vdop\":%.2f,", datap->dop.vdop); + if (isnan(datap->dop.tdop) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"tdop\":%.2f,", datap->dop.tdop); + if (isnan(datap->dop.hdop) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"hdop\":%.2f,", datap->dop.hdop); + if (isnan(datap->dop.gdop) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"gdop\":%.2f,", datap->dop.gdop); + if (isnan(datap->dop.pdop) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"pdop\":%.2f,", datap->dop.pdop); + /* insurance against flaky drivers */ + for (i = 0; i < datap->satellites_visible; i++) + if (datap->PRN[i]) + reported++; + if (reported) { + (void)strlcat(reply, "\"satellites\":[", replylen); + for (i = 0; i < reported; i++) { + used = 0; + for (j = 0; j < datap->satellites_used; j++) + if (datap->used[j] == datap->PRN[i]) { + used = 1; + break; + } + if (datap->PRN[i]) { + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "{\"PRN\":%d,\"el\":%d,\"az\":%d,\"ss\":%.0f,\"used\":%s},", + datap->PRN[i], + datap->elevation[i], datap->azimuth[i], + datap->ss[i], used ? "true" : "false"); + } + } + } + if (reported) { + if (reply[strlen(reply) - 1] == ',') + reply[strlen(reply) - 1] = '\0'; /* trim trailing comma */ + (void)strlcat(reply, "]", replylen - strlen(reply)); + } + if (reply[strlen(reply) - 1] == ',') + reply[strlen(reply) - 1] = '\0'; /* trim trailing comma */ + (void)strlcat(reply, "}\r\n", replylen - strlen(reply)); + if (datap->satellites_visible != reported) + gpsd_report(LOG_WARN, "Satellite count %d != PRN count %d\n", + datap->satellites_visible, reported); +} + +void json_device_dump(const struct gps_device_t *device, + /*@out@*/ char *reply, size_t replylen) +{ + char buf1[JSON_VAL_MAX * 2 + 1]; + struct classmap_t *cmp; + (void)strlcpy(reply, "{\"class\":\"DEVICE\",\"path\":\"", replylen); + (void)strlcat(reply, device->gpsdata.dev.path, replylen); + (void)strlcat(reply, "\",", replylen); + if (device->gpsdata.online > 0) { + (void)snprintf(reply + strlen(reply), replylen - strlen(reply), + "\"activated\":%2.2f,", device->gpsdata.online); + if (device->observed != 0) { + int mask = 0; + for (cmp = classmap; cmp < classmap + NITEMS(classmap); cmp++) + if ((device->observed & cmp->packetmask) != 0) + mask |= cmp->typemask; + if (mask != 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), "\"flags\":%d,", + mask); + } + if (device->device_type != NULL) { + (void)strlcat(reply, "\"driver\":\"", replylen); + (void)strlcat(reply, device->device_type->type_name, replylen); + (void)strlcat(reply, "\",", replylen); + } + /*@-mustfreefresh@*/ + if (device->subtype[0] != '\0') { + (void)strlcat(reply, "\"subtype\":\"", replylen); + (void)strlcat(reply, + json_stringify(buf1, sizeof(buf1), device->subtype), + replylen); + (void)strlcat(reply, "\",", replylen); + } + /*@+mustfreefresh@*/ + if (device->is_serial) { + (void)snprintf(reply + strlen(reply), replylen - strlen(reply), + "\"native\":%d,\"bps\":%d,\"parity\":\"%c\",\"stopbits\":%u,\"cycle\":%2.2f", + device->gpsdata.dev.driver_mode, + (int)gpsd_get_speed(&device->ttyset), + device->gpsdata.dev.parity, + device->gpsdata.dev.stopbits, + device->gpsdata.dev.cycle); +#ifdef ALLOW_RECONFIGURE + if (device->device_type != NULL + && device->device_type->rate_switcher != NULL) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + ",\"mincycle\":%2.2f", + device->device_type->min_cycle); +#endif /* ALLOW_RECONFIGURE */ + } + } + if (reply[strlen(reply) - 1] == ',') + reply[strlen(reply) - 1] = '\0'; /* trim trailing comma */ + (void)strlcat(reply, "}\r\n", replylen); +} + +void json_watch_dump(const struct policy_t *ccp, + /*@out@*/ char *reply, size_t replylen) +{ + /*@-compdef@*/ + (void)snprintf(reply, replylen, + "{\"class\":\"WATCH\",\"enable\":%s,\"json\":%s,\"nmea\":%s,\"raw\":%d,\"scaled\":%s,\"timing\":%s", + ccp->watcher ? "true" : "false", + ccp->json ? "true" : "false", + ccp->nmea ? "true" : "false", + ccp->raw, + ccp->scaled ? "true" : "false", + ccp->timing ? "true" : "false"); + if (ccp->devpath[0] != '\0') + (void)snprintf(reply + strlen(reply), replylen - strlen(reply), + "\"device\":%s,", ccp->devpath); + if (reply[strlen(reply) - 1] == ',') + reply[strlen(reply) - 1] = '\0'; + (void)strlcat(reply, "}\r\n", replylen - strlen(reply)); + /*@+compdef@*/ +} + +#if defined(RTCM104V2_ENABLE) +void rtcm2_json_dump(const struct rtcm2_t *rtcm, /*@out@*/ char buf[], + size_t buflen) +/* dump the contents of a parsed RTCM104 message as JSON */ +{ + /*@-mustfreefresh@*/ + char buf1[JSON_VAL_MAX * 2 + 1]; + /* + * Beware! Needs to stay synchronized with a JSON enumeration map in + * the parser. This interpretation of NAVSYSTEM_GALILEO is assumed + * from RTCM3, it's not actually documented in RTCM 2.1. + */ + static char *navsysnames[] = { "GPS", "GLONASS", "GALILEO" }; + + unsigned int n; + + (void)snprintf(buf, buflen, + "{\"class\":\"RTCM2\",\"type\":%u,\"station_id\":%u,\"zcount\":%0.1f,\"seqnum\":%u,\"length\":%u,\"station_health\":%u,", + rtcm->type, rtcm->refstaid, rtcm->zcount, rtcm->seqnum, + rtcm->length, rtcm->stathlth); + + switch (rtcm->type) { + case 1: + case 9: + (void)strlcat(buf, "\"satellites\":[", buflen); + for (n = 0; n < rtcm->ranges.nentries; n++) { + const struct rangesat_t *rsp = &rtcm->ranges.sat[n]; + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "{\"ident\":%u,\"udre\":%u,\"issuedata\":%u,\"rangerr\":%0.3f,\"rangerate\":%0.3f},", + rsp->ident, + rsp->udre, + rsp->issuedata, rsp->rangerr, rsp->rangerate); + } + if (buf[strlen(buf) - 1] == ',') + buf[strlen(buf) - 1] = '\0'; + (void)strlcat(buf, "]", buflen); + break; + + case 3: + if (rtcm->ecef.valid) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"x\":%.2f,\"y\":%.2f,\"z\":%.2f,", + rtcm->ecef.x, rtcm->ecef.y, rtcm->ecef.z); + break; + + case 4: + if (rtcm->reference.valid) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"system\":\"%s\",\"sense\":%1d,\"datum\":\"%s\",\"dx\":%.1f,\"dy\":%.1f,\"dz\":%.1f,", + rtcm->reference.system >= NITEMS(navsysnames) + ? "UNKNOWN" + : navsysnames[rtcm->reference.system], + rtcm->reference.sense, + rtcm->reference.datum, + rtcm->reference.dx, + rtcm->reference.dy, rtcm->reference.dz); + } + break; + + case 5: +#define JSON_BOOL(x) ((x)?"true":"false") + (void)strlcat(buf, "\"satellites\":[", buflen); + for (n = 0; n < rtcm->conhealth.nentries; n++) { + const struct consat_t *csp = &rtcm->conhealth.sat[n]; + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "{\"ident\":%u,\"iodl\":%s,\"health\":%1u,\"snr\":%d,\"health_en\":%s,\"new_data\":%s,\"los_warning\":%s,\"tou\":%u},", + csp->ident, + JSON_BOOL(csp->iodl), + (unsigned)csp->health, + csp->snr, + JSON_BOOL(csp->health_en), + JSON_BOOL(csp->new_data), + JSON_BOOL(csp->los_warning), csp->tou); + } +#undef JSON_BOOL + if (buf[strlen(buf) - 1] == ',') + buf[strlen(buf) - 1] = '\0'; + (void)strlcat(buf, "]", buflen); + break; + + case 6: /* NOP msg */ + break; + + case 7: + (void)strlcat(buf, "\"satellites\":[", buflen); + for (n = 0; n < rtcm->almanac.nentries; n++) { + const struct station_t *ssp = &rtcm->almanac.station[n]; + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "{\"lat\":%.4f,\"lon\":%.4f,\"range\":%u,\"frequency\":%.1f,\"health\":%u,\"station_id\":%u,\"bitrate\":%u},", + ssp->latitude, + ssp->longitude, + ssp->range, + ssp->frequency, + ssp->health, ssp->station_id, ssp->bitrate); + } + if (buf[strlen(buf) - 1] == ',') + buf[strlen(buf) - 1] = '\0'; + (void)strlcat(buf, "]", buflen); + break; + case 16: + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"message\":\"%s\"", json_stringify(buf1, + sizeof(buf1), + rtcm->message)); + break; + + default: + (void)strlcat(buf, "\"data\":[", buflen); + for (n = 0; n < rtcm->length; n++) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"0x%08x\",", rtcm->words[n]); + if (buf[strlen(buf) - 1] == ',') + buf[strlen(buf) - 1] = '\0'; + (void)strlcat(buf, "]", buflen); + break; + } + + if (buf[strlen(buf) - 1] == ',') + buf[strlen(buf) - 1] = '\0'; + (void)strlcat(buf, "}\r\n", buflen); + /*@+mustfreefresh@*/ +} +#endif /* defined(RTCM104V2_ENABLE) */ + +#if defined(AIVDM_ENABLE) + +void aivdm_json_dump(const struct ais_t *ais, bool scaled, + /*@out@*/ char *buf, size_t buflen) +{ + char buf1[JSON_VAL_MAX * 2 + 1]; + char buf2[JSON_VAL_MAX * 2 + 1]; + char buf3[JSON_VAL_MAX * 2 + 1]; + + static char *nav_legends[] = { + "Under way using engine", + "At anchor", + "Not under command", + "Restricted manoeuverability", + "Constrained by her draught", + "Moored", + "Aground", + "Engaged in fishing", + "Under way sailing", + "Reserved for HSC", + "Reserved for WIG", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Not defined", + }; + static char *epfd_legends[] = { + "Undefined", + "GPS", + "GLONASS", + "Combined GPS/GLONASS", + "Loran-C", + "Chayka", + "Integrated navigation system", + "Surveyed", + "Galileo", + }; + + static char *ship_type_legends[100] = { + "Not available", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Wing in ground (WIG) - all ships of this type", + "Wing in ground (WIG) - Hazardous category A", + "Wing in ground (WIG) - Hazardous category B", + "Wing in ground (WIG) - Hazardous category C", + "Wing in ground (WIG) - Hazardous category D", + "Wing in ground (WIG) - Reserved for future use", + "Wing in ground (WIG) - Reserved for future use", + "Wing in ground (WIG) - Reserved for future use", + "Wing in ground (WIG) - Reserved for future use", + "Wing in ground (WIG) - Reserved for future use", + "Fishing", + "Towing", + "Towing: length exceeds 200m or breadth exceeds 25m", + "Dredging or underwater ops", + "Diving ops", + "Military ops", + "Sailing", + "Pleasure Craft", + "Reserved", + "Reserved", + "High speed craft (HSC) - all ships of this type", + "High speed craft (HSC) - Hazardous category A", + "High speed craft (HSC) - Hazardous category B", + "High speed craft (HSC) - Hazardous category C", + "High speed craft (HSC) - Hazardous category D", + "High speed craft (HSC) - Reserved for future use", + "High speed craft (HSC) - Reserved for future use", + "High speed craft (HSC) - Reserved for future use", + "High speed craft (HSC) - Reserved for future use", + "High speed craft (HSC) - No additional information", + "Pilot Vessel", + "Search and Rescue vessel", + "Tug", + "Port Tender", + "Anti-pollution equipment", + "Law Enforcement", + "Spare - Local Vessel", + "Spare - Local Vessel", + "Medical Transport", + "Ship according to RR Resolution No. 18", + "Passenger - all ships of this type", + "Passenger - Hazardous category A", + "Passenger - Hazardous category B", + "Passenger - Hazardous category C", + "Passenger - Hazardous category D", + "Passenger - Reserved for future use", + "Passenger - Reserved for future use", + "Passenger - Reserved for future use", + "Passenger - Reserved for future use", + "Passenger - No additional information", + "Cargo - all ships of this type", + "Cargo - Hazardous category A", + "Cargo - Hazardous category B", + "Cargo - Hazardous category C", + "Cargo - Hazardous category D", + "Cargo - Reserved for future use", + "Cargo - Reserved for future use", + "Cargo - Reserved for future use", + "Cargo - Reserved for future use", + "Cargo - No additional information", + "Tanker - all ships of this type", + "Tanker - Hazardous category A", + "Tanker - Hazardous category B", + "Tanker - Hazardous category C", + "Tanker - Hazardous category D", + "Tanker - Reserved for future use", + "Tanker - Reserved for future use", + "Tanker - Reserved for future use", + "Tanker - Reserved for future use", + "Tanker - No additional information", + "Other Type - all ships of this type", + "Other Type - Hazardous category A", + "Other Type - Hazardous category B", + "Other Type - Hazardous category C", + "Other Type - Hazardous category D", + "Other Type - Reserved for future use", + "Other Type - Reserved for future use", + "Other Type - Reserved for future use", + "Other Type - Reserved for future use", + "Other Type - no additional information", + }; + +#define SHIPTYPE_DISPLAY(n) (((n) < (unsigned int)NITEMS(ship_type_legends)) ? ship_type_legends[n] : "INVALID SHIP TYPE") + + static char *station_type_legends[16] = { + "All types of mobiles", + "Reserved for future use", + "All types of Class B mobile stations", + "SAR airborne mobile station", + "Aid to Navigation station", + "Class B shipborne mobile station", + "Regional use and inland waterways", + "Regional use and inland waterways", + "Regional use and inland waterways", + "Regional use and inland waterways", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + "Reserved for future use", + }; + +#define STATIONTYPE_DISPLAY(n) (((n) < (unsigned int)NITEMS(ship_type_legends)) ? station_type_legends[n] : "INVALID STATION TYPE") + + static char *navaid_type_legends[] = { + "Unspcified", + "Reference point", + "RACON", + "Fixed offshore structure", + "Spare, Reserved for future use.", + "Light, without sectors", + "Light, with sectors", + "Leading Light Front", + "Leading Light Rear", + "Beacon, Cardinal N", + "Beacon, Cardinal E", + "Beacon, Cardinal S", + "Beacon, Cardinal W", + "Beacon, Port hand", + "Beacon, Starboard hand", + "Beacon, Preferred Channel port hand", + "Beacon, Preferred Channel starboard hand", + "Beacon, Isolated danger", + "Beacon, Safe water", + "Beacon, Special mark", + "Cardinal Mark N", + "Cardinal Mark E", + "Cardinal Mark S", + "Cardinal Mark W", + "Port hand Mark", + "Starboard hand Mark", + "Preferred Channel Port hand", + "Preferred Channel Starboard hand", + "Isolated danger", + "Safe Water", + "Special Mark", + "Light Vessel / LANBY / Rigs", + }; + +#define NAVAIDTYPE_DISPLAY(n) (((n) < (unsigned int)NITEMS(navaid_type_legends[0])) ? navaid_type_legends[n] : "INVALID NAVAID TYPE") + +#define JSON_BOOL(x) ((x)?"true":"false") + (void)snprintf(buf, buflen, + "{\"class\":\"AIS\",\"type\":%u,\"repeat\":%u," + "\"mmsi\":%u,\"scaled\":%s,", + ais->type, ais->repeat, ais->mmsi, JSON_BOOL(scaled)); + /*@ -formatcode -mustfreefresh @*/ + switch (ais->type) { + case 1: /* Position Report */ + case 2: + case 3: + if (scaled) { + char turnlegend[20]; + char speedlegend[20]; + + /* + * Express turn as nan if not available, + * "fastleft"/"fastright" for fast turns. + */ + if (ais->type1.turn == -128) + (void)strlcpy(turnlegend, "\"nan\"", sizeof(turnlegend)); + else if (ais->type1.turn == -127) + (void)strlcpy(turnlegend, "\"fastleft\"", sizeof(turnlegend)); + else if (ais->type1.turn == 127) + (void)strlcpy(turnlegend, "\"fastright\"", + sizeof(turnlegend)); + else { + double rot1 = ais->type1.turn / 4.733; + (void)snprintf(turnlegend, sizeof(turnlegend), + "%.0f", rot1 * rot1); + } + + /* + * Express speed as nan if not available, + * "fast" for fast movers. + */ + if (ais->type1.speed == AIS_SPEED_NOT_AVAILABLE) + (void)strlcpy(speedlegend, "\"nan\"", sizeof(speedlegend)); + else if (ais->type1.speed == AIS_SPEED_FAST_MOVER) + (void)strlcpy(speedlegend, "\"fast\"", sizeof(speedlegend)); + else + (void)snprintf(speedlegend, sizeof(speedlegend), + "%.1f", ais->type1.speed / 10.0); + + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"status\":\"%s\",\"turn\":%s,\"speed\":%s," + "\"accuracy\":%s,\"lon\":%.4f,\"lat\":%.4f," + "\"course\":%u,\"heading\":%u,\"second\":%u," + "\"maneuver\":%u,\"raim\":%s,\"radio\":%u}\r\n", + nav_legends[ais->type1.status], + turnlegend, + speedlegend, + JSON_BOOL(ais->type1.accuracy), + ais->type1.lon / AIS_LATLON_SCALE, + ais->type1.lat / AIS_LATLON_SCALE, + ais->type1.course, + ais->type1.heading, + ais->type1.second, + ais->type1.maneuver, + JSON_BOOL(ais->type1.raim), ais->type1.radio); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"status\":%u,\"turn\":%d,\"speed\":%u," + "\"accuracy\":%s,\"lon\":%d,\"lat\":%d," + "\"course\":%u,\"heading\":%u,\"second\":%u," + "\"maneuver\":%u,\"raim\":%s,\"radio\":%u}\r\n", + ais->type1.status, + ais->type1.turn, + ais->type1.speed, + JSON_BOOL(ais->type1.accuracy), + ais->type1.lon, + ais->type1.lat, + ais->type1.course, + ais->type1.heading, + ais->type1.second, + ais->type1.maneuver, + JSON_BOOL(ais->type1.raim), ais->type1.radio); + } + break; + case 4: /* Base Station Report */ + case 11: /* UTC/Date Response */ + if (scaled) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"timestamp\":\"%4u:%02u:%02uT%02u:%02u:%02uZ\"," + "\"accuracy\":%s,\"lon\":%.4f,\"lat\":%.4f," + "\"epfd\":\"%s\",\"raim\":%s,\"radio\":%u}\r\n", + ais->type4.year, + ais->type4.month, + ais->type4.day, + ais->type4.hour, + ais->type4.minute, + ais->type4.second, + JSON_BOOL(ais->type4.accuracy), + ais->type4.lon / AIS_LATLON_SCALE, + ais->type4.lat / AIS_LATLON_SCALE, + epfd_legends[ais->type4.epfd], + JSON_BOOL(ais->type4.raim), ais->type4.radio); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"timestamp\":\"%04u-%02u-%02uT%02u:%02u:%02uZ\"," + "\"accuracy\":%s,\"lon\":%d,\"lat\":%d," + "\"epfd\":%u,\"raim\":%s,\"radio\":%u}\r\n", + ais->type4.year, + ais->type4.month, + ais->type4.day, + ais->type4.hour, + ais->type4.minute, + ais->type4.second, + JSON_BOOL(ais->type4.accuracy), + ais->type4.lon, + ais->type4.lat, + ais->type4.epfd, + JSON_BOOL(ais->type4.raim), ais->type4.radio); + } + break; + case 5: /* Ship static and voyage related data */ + if (scaled) { + /* *INDENT-OFF* */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"imo\":%u,\"ais_version\":%u,\"callsign\":\"%s\"," + "\"shipname\":\"%s\",\"shiptype\":\"%s\"," + "\"to_bow\":%u,\"to_stern\":%u,\"to_port\":%u," + "\"to_starboard\":%u,\"epfd\":\"%s\"," + "\"eta\":\"%02u-%02uT%02u:%02uZ\"," + "\"draught\":%.1f,\"destination\":\"%s\"," + "\"dte\":%u}\r\n", + ais->type5.imo, + ais->type5.ais_version, + json_stringify(buf1, sizeof(buf1), + ais->type5.callsign), + json_stringify(buf2, sizeof(buf2), + ais->type5.shipname), + SHIPTYPE_DISPLAY(ais->type5.shiptype), + ais->type5.to_bow, ais->type5.to_stern, + ais->type5.to_port, ais->type5.to_starboard, + epfd_legends[ais->type5.epfd], ais->type5.month, + ais->type5.day, ais->type5.hour, ais->type5.minute, + ais->type5.draught / 10.0, + json_stringify(buf3, sizeof(buf3), + ais->type5.destination), + ais->type5.dte); + /* *INDENT-ON* */ + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"imo\":%u,\"ais_version\":%u,\"callsign\":\"%s\"," + "\"shipname\":\"%s\",\"shiptype\":%u," + "\"to_bow\":%u,\"to_stern\":%u,\"to_port\":%u," + "\"to_starboard\":%u,\"epfd\":%u," + "\"eta\":\"%02u-%02uT%02u:%02uZ\"," + "\"draught\":%u,\"destination\":\"%s\"," + "\"dte\":%u}\r\n", + ais->type5.imo, + ais->type5.ais_version, + json_stringify(buf1, sizeof(buf1), + ais->type5.callsign), + json_stringify(buf2, sizeof(buf2), + ais->type5.shipname), + ais->type5.shiptype, ais->type5.to_bow, + ais->type5.to_stern, ais->type5.to_port, + ais->type5.to_starboard, ais->type5.epfd, + ais->type5.month, ais->type5.day, ais->type5.hour, + ais->type5.minute, ais->type5.draught, + json_stringify(buf3, sizeof(buf3), + ais->type5.destination), + ais->type5.dte); + } + break; + case 6: /* Binary Message */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"seqno\":%u,\"dest_mmsi\":%u," + "\"retransmit\":%s,\"dac\":%u,\"fid\":%u," + "\"data\":\"%zd:%s\"}\r\n", + ais->type6.seqno, + ais->type6.dest_mmsi, + JSON_BOOL(ais->type6.retransmit), + ais->type6.dac, + ais->type6.fid, + ais->type6.bitcount, + gpsd_hexdump(ais->type6.bitdata, + (ais->type6.bitcount + 7) / 8)); + break; + case 7: /* Binary Acknowledge */ + case 13: /* Safety Related Acknowledge */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"mmsi1\":%u,\"mmsi2\":%u,\"mmsi3\":%u,\"mmsi4\":%u}\r\n", + ais->type7.mmsi1, + ais->type7.mmsi2, ais->type7.mmsi3, ais->type7.mmsi4); + break; + case 8: /* Binary Broadcast Message */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"dac\":%u,\"fid\":%u,\"data\":\"%zd:%s\"}\r\n", + ais->type8.dac, + ais->type8.fid, + ais->type8.bitcount, + gpsd_hexdump(ais->type8.bitdata, + (ais->type8.bitcount + 7) / 8)); + break; + case 9: /* Standard SAR Aircraft Position Report */ + if (scaled) { + char altlegend[20]; + char speedlegend[20]; + + /* + * Express altitude as nan if not available, + * "high" for above the reporting ceiling. + */ + if (ais->type9.alt == AIS_ALT_NOT_AVAILABLE) + (void)strlcpy(altlegend, "\"nan\"", sizeof(altlegend)); + else if (ais->type9.alt == AIS_ALT_HIGH) + (void)strlcpy(altlegend, "\"high\"", sizeof(altlegend)); + else + (void)snprintf(altlegend, sizeof(altlegend), + "%.1f", ais->type9.alt / 10.0); + + /* + * Express speed as nan if not available, + * "high" for above the reporting ceiling. + */ + if (ais->type9.speed == AIS_SAR_SPEED_NOT_AVAILABLE) + (void)strlcpy(speedlegend, "\"nan\"", sizeof(speedlegend)); + else if (ais->type9.speed == AIS_SAR_FAST_MOVER) + (void)strlcpy(speedlegend, "\"fast\"", sizeof(speedlegend)); + else + (void)snprintf(speedlegend, sizeof(speedlegend), + "%.1f", ais->type1.speed / 10.0); + + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"alt\":%s,\"speed\":%s,\"accuracy\":%s," + "\"lon\":%.4f,\"lat\":%.4f,\"course\":%.1f," + "\"second\":%u,\"regional\":%u,\"dte\":%u," + "\"raim\":%s,\"radio\":%u}\r\n", + altlegend, + speedlegend, + JSON_BOOL(ais->type9.accuracy), + ais->type9.lon / AIS_LATLON_SCALE, + ais->type9.lat / AIS_LATLON_SCALE, + ais->type9.course / 10.0, + ais->type9.second, + ais->type9.regional, + ais->type9.dte, + JSON_BOOL(ais->type9.raim), ais->type9.radio); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"alt\":%u,\"speed\":%u,\"accuracy\":%s," + "\"lon\":%d,\"lat\":%d,\"course\":%u," + "\"second\":%u,\"regional\":%u,\"dte\":%u," + "\"raim\":%s,\"radio\":%u}\r\n", + ais->type9.alt, + ais->type9.speed, + JSON_BOOL(ais->type9.accuracy), + ais->type9.lon, + ais->type9.lat, + ais->type9.course, + ais->type9.second, + ais->type9.regional, + ais->type9.dte, + JSON_BOOL(ais->type9.raim), ais->type9.radio); + } + break; + case 10: /* UTC/Date Inquiry */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"dest_mmsi\":%u}\r\n", ais->type10.dest_mmsi); + break; + case 12: /* Safety Related Message */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"seqno\":%u,\"dest_mmsi\":%u,\"retransmit\":%s,\"text\":\"%s\"}\r\n", + ais->type12.seqno, + ais->type12.dest_mmsi, + JSON_BOOL(ais->type12.retransmit), + json_stringify(buf1, sizeof(buf1), ais->type12.text)); + break; + case 14: /* Safety Related Broadcast Message */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"text\":\"%s\"}\r\n", + json_stringify(buf1, sizeof(buf1), ais->type14.text)); + break; + case 15: /* Interrogation */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"mmsi1\":%u,\"type1_1\":%u,\"offset1_1\":%u," + "\"type1_2\":%u,\"offset1_2\":%u,\"mmsi2\":%u," + "\"type2_1\":%u,\"offset2_1\":%u}\r\n", + ais->type15.mmsi1, + ais->type15.type1_1, + ais->type15.offset1_1, + ais->type15.type1_2, + ais->type15.offset1_2, + ais->type15.mmsi2, + ais->type15.type2_1, ais->type15.offset2_1); + break; + case 16: + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"mmsi1\":%u,\"offset1\":%u,\"increment1\":%u," + "\"mmsi2\":%u,\"offset2\":%u,\"increment2\":%u}\r\n", + ais->type16.mmsi1, + ais->type16.offset1, + ais->type16.increment1, + ais->type16.mmsi2, + ais->type16.offset2, ais->type16.increment2); + break; + case 17: + if (scaled) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"lon\":%.1f,\"lat\":%.1f,\"data\":\"%zd:%s\"}\r\n", + ais->type17.lon / AIS_GNSS_LATLON_SCALE, + ais->type17.lat / AIS_GNSS_LATLON_SCALE, + ais->type17.bitcount, + gpsd_hexdump(ais->type17.bitdata, + (ais->type17.bitcount + 7) / 8)); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"lon\":%d,\"lat\":%d,\"data\":\"%zd:%s\"}\r\n", + ais->type17.lon, + ais->type17.lat, + ais->type17.bitcount, + gpsd_hexdump(ais->type17.bitdata, + (ais->type17.bitcount + 7) / 8)); + } + break; + case 18: + if (scaled) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"reserved\":%u,\"speed\":%.1f,\"accuracy\":%s," + "\"lon\":%.4f,\"lat\":%.4f,\"course\":%.1f," + "\"heading\":%u,\"second\":%u,\"regional\":%u," + "\"cs\":%s,\"display\":%s,\"dsc\":%s,\"band\":%s," + "\"msg22\":%s,\"raim\":%s,\"radio\":%u}\r\n", + ais->type18.reserved, + ais->type18.speed / 10.0, + JSON_BOOL(ais->type18.accuracy), + ais->type18.lon / AIS_LATLON_SCALE, + ais->type18.lat / AIS_LATLON_SCALE, + ais->type18.course / 10.0, + ais->type18.heading, + ais->type18.second, + ais->type18.regional, + JSON_BOOL(ais->type18.cs), + JSON_BOOL(ais->type18.display), + JSON_BOOL(ais->type18.dsc), + JSON_BOOL(ais->type18.band), + JSON_BOOL(ais->type18.msg22), + JSON_BOOL(ais->type18.raim), ais->type18.radio); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"reserved\":%u,\"speed\":%u,\"accuracy\":%s," + "\"lon\":%d,\"lat\":%d,\"course\":%u," + "\"heading\":%u,\"second\":%u,\"regional\":%u," + "\"cs\":%s,\"display\":%s,\"dsc\":%s,\"band\":%s," + "\"msg22\":%s,\"raim\":%s,\"radio\":%u}\r\n", + ais->type18.reserved, + ais->type18.speed, + JSON_BOOL(ais->type18.accuracy), + ais->type18.lon, + ais->type18.lat, + ais->type18.course, + ais->type18.heading, + ais->type18.second, + ais->type18.regional, + JSON_BOOL(ais->type18.cs), + JSON_BOOL(ais->type18.display), + JSON_BOOL(ais->type18.dsc), + JSON_BOOL(ais->type18.band), + JSON_BOOL(ais->type18.msg22), + JSON_BOOL(ais->type18.raim), ais->type18.radio); + } + break; + case 19: + if (scaled) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"reserved\":%u,\"speed\":%.1f,\"accuracy\":%s," + "\"lon\":%.4f,\"lat\":%.4f,\"course\":%.1f," + "\"heading\":%u,\"second\":%u,\"regional\":%u," + "\"shipname\":\"%s\",\"shiptype\":\"%s\"," + "\"to_bow\":%u,\"to_stern\":%u,\"to_port\":%u," + "\"to_starboard\":%u,\"epfd\":\"%s\",\"raim\":%s," + "\"dte\":%u,\"assigned\":%s}\r\n", + ais->type19.reserved, + ais->type19.speed / 10.0, + JSON_BOOL(ais->type19.accuracy), + ais->type19.lon / AIS_LATLON_SCALE, + ais->type19.lat / AIS_LATLON_SCALE, + ais->type19.course / 10.0, + ais->type19.heading, + ais->type19.second, + ais->type19.regional, + ais->type19.shipname, + SHIPTYPE_DISPLAY(ais->type19.shiptype), + ais->type19.to_bow, + ais->type19.to_stern, + ais->type19.to_port, + ais->type19.to_starboard, + epfd_legends[ais->type19.epfd], + JSON_BOOL(ais->type19.raim), + ais->type19.dte, JSON_BOOL(ais->type19.assigned)); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"reserved\":%u,\"speed\":%u,\"accuracy\":%s," + "\"lon\":%d,\"lat\":%d,\"course\":%u," + "\"heading\":%u,\"second\":%u,\"regional\":%u," + "\"shipname\":\"%s\",\"shiptype\":%u," + "\"to_bow\":%u,\"to_stern\":%u,\"to_port\":%u," + "\"to_starboard\":%u,\"epfd\":%u,\"raim\":%s," + "\"dte\":%u,\"assigned\":%s}\r\n", + ais->type19.reserved, + ais->type19.speed, + JSON_BOOL(ais->type19.accuracy), + ais->type19.lon, + ais->type19.lat, + ais->type19.course, + ais->type19.heading, + ais->type19.second, + ais->type19.regional, + ais->type19.shipname, + ais->type19.shiptype, + ais->type19.to_bow, + ais->type19.to_stern, + ais->type19.to_port, + ais->type19.to_starboard, + ais->type19.epfd, + JSON_BOOL(ais->type19.raim), + ais->type19.dte, JSON_BOOL(ais->type19.assigned)); + } + break; + case 20: /* Data Link Management Message */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"offset1\":%u,\"number1\":%u," + "\"timeout1\":%u,\"increment1\":%u," + "\"offset2\":%u,\"number2\":%u," + "\"timeout2\":%u,\"increment2\":%u," + "\"offset3\":%u,\"number3\":%u," + "\"timeout3\":%u,\"increment3\":%u," + "\"offset4\":%u,\"number4\":%u," + "\"timeout4\":%u,\"increment4\":%u}\r\n", + ais->type20.offset1, + ais->type20.number1, + ais->type20.timeout1, + ais->type20.increment1, + ais->type20.offset2, + ais->type20.number2, + ais->type20.timeout2, + ais->type20.increment2, + ais->type20.offset3, + ais->type20.number3, + ais->type20.timeout3, + ais->type20.increment3, + ais->type20.offset4, + ais->type20.number4, + ais->type20.timeout4, ais->type20.increment4); + break; + case 21: /* Aid to Navigation */ + if (scaled) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"aid_type\":\"%s\",\"name\":\"%s\",\"lon\":%.4f," + "\"lat\":%.4f,\"accuracy\":%s,\"to_bow\":%u," + "\"to_stern\":%u,\"to_port\":%u," + "\"to_starboard\":%u,\"epfd\":\"%s\"," + "\"second\":%u,\"regional\":%u," + "\"off_position\":%s,\"raim\":%s," + "\"virtual_aid\":%s}\r\n", + NAVAIDTYPE_DISPLAY(ais->type21.aid_type), + json_stringify(buf1, sizeof(buf1), + ais->type21.name), + ais->type21.lon / AIS_LATLON_SCALE, + ais->type21.lat / AIS_LATLON_SCALE, + JSON_BOOL(ais->type21.accuracy), + ais->type21.to_bow, ais->type21.to_stern, + ais->type21.to_port, ais->type21.to_starboard, + epfd_legends[ais->type21.epfd], ais->type21.second, + ais->type21.regional, + JSON_BOOL(ais->type21.off_position), + JSON_BOOL(ais->type21.raim), + JSON_BOOL(ais->type21.virtual_aid)); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"aid_type\":%u,\"name\":\"%s\",\"accuracy\":%s," + "\"lon\":%d,\"lat\":%d,\"to_bow\":%u," + "\"to_stern\":%u,\"to_port\":%u,\"to_starboard\":%u," + "\"epfd\":%u,\"second\":%u,\"regional\":%u," + "\"off_position\":%s,\"raim\":%s," + "\"virtual_aid\":%s}\r\n", + ais->type21.aid_type, + ais->type21.name, + JSON_BOOL(ais->type21.accuracy), + ais->type21.lon, + ais->type21.lat, + ais->type21.to_bow, + ais->type21.to_stern, + ais->type21.to_port, + ais->type21.to_starboard, + ais->type21.epfd, + ais->type21.second, + ais->type21.regional, + JSON_BOOL(ais->type21.off_position), + JSON_BOOL(ais->type21.raim), + JSON_BOOL(ais->type21.virtual_aid)); + } + break; + case 22: /* Channel Management */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"channel_a\":%u,\"channel_b\":%u," + "\"txrx\":%u,\"power\":%s,", + ais->type22.channel_a, + ais->type22.channel_b, + ais->type22.txrx, JSON_BOOL(ais->type22.power)); + if (ais->type22.addressed) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"dest1\":%u,\"dest2\":%u", + ais->type22.mmsi.dest1, ais->type22.mmsi.dest2); + } else if (scaled) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"ne_lon\":\"%f\",\"ne_lat\":\"%f\"," + "\"sw_lon\":\"%f\",\"sw_lat\":\"%f\",", + ais->type22.area.ne_lon / AIS_CHANNEL_LATLON_SCALE, + ais->type22.area.ne_lat / AIS_CHANNEL_LATLON_SCALE, + ais->type22.area.sw_lon / AIS_CHANNEL_LATLON_SCALE, + ais->type22.area.sw_lat / + AIS_CHANNEL_LATLON_SCALE); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"ne_lon\":%d,\"ne_lat\":%d," + "\"sw_lon\":%d,\"sw_lat\":%d,", + ais->type22.area.ne_lon, + ais->type22.area.ne_lat, + ais->type22.area.sw_lon, ais->type22.area.sw_lat); + } + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"addressed\":%s,\"band_a\":%s," + "\"band_b\":%s,\"zonesize\":%u}\r\n", + JSON_BOOL(ais->type22.addressed), + JSON_BOOL(ais->type22.band_a), + JSON_BOOL(ais->type22.band_b), ais->type22.zonesize); + break; + case 23: /* Group Assignment Command */ + if (scaled) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"ne_lon\":\"%f\",\"ne_lat\":\"%f\"," + "\"sw_lon\":\"%f\",\"sw_lat\":\"%f\"," + "\"stationtype\":\"%s\",\"shiptype\":\"%s\"," + "\"interval\":%u,\"quiet\":%u}\r\n", + ais->type23.ne_lon / AIS_CHANNEL_LATLON_SCALE, + ais->type23.ne_lat / AIS_CHANNEL_LATLON_SCALE, + ais->type23.sw_lon / AIS_CHANNEL_LATLON_SCALE, + ais->type23.sw_lat / AIS_CHANNEL_LATLON_SCALE, + STATIONTYPE_DISPLAY(ais->type23.stationtype), + SHIPTYPE_DISPLAY(ais->type23.shiptype), + ais->type23.interval, ais->type23.quiet); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"ne_lon\":%d,\"ne_lat\":%d," + "\"sw_lon\":%d,\"sw_lat\":%d," + "\"stationtype\":%u,\"shiptype\":%u," + "\"interval\":%u,\"quiet\":%u}\r\n", + ais->type23.ne_lon, + ais->type23.ne_lat, + ais->type23.sw_lon, + ais->type23.sw_lat, + ais->type23.stationtype, + ais->type23.shiptype, + ais->type23.interval, ais->type23.quiet); + } + break; + case 24: /* Class B CS Static Data Report */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"shipname\":\"%s\",", + json_stringify(buf1, sizeof(buf1), + ais->type24.shipname)); + if (scaled) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"shiptype\":\"%s\",", + SHIPTYPE_DISPLAY(ais->type24.shiptype)); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"shiptype\":%u,", ais->type24.shiptype); + } + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"vendorid\":\"%s\",\"callsign\":\"%s\",", + ais->type24.vendorid, ais->type24.callsign); + if (AIS_AUXILIARY_MMSI(ais->mmsi)) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "mothership_\"mmsi\":%u}\r\n", + ais->type24.mothership_mmsi); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"to_bow\":%u,\"to_stern\":%u," + "\"to_port\":%u,\"to_starboard\":%u}\r\n", + ais->type24.dim.to_bow, + ais->type24.dim.to_stern, + ais->type24.dim.to_port, + ais->type24.dim.to_starboard); + } + break; + case 25: /* Binary Message, Single Slot */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"addressed\":%s,\"structured\":%s,\"dest_mmsi\":%u," + "\"app_id\":%u,\"data\":\"%zd:%s\"}\r\n", + JSON_BOOL(ais->type25.addressed), + JSON_BOOL(ais->type25.structured), + ais->type25.dest_mmsi, + ais->type25.app_id, + ais->type25.bitcount, + gpsd_hexdump(ais->type25.bitdata, + (ais->type25.bitcount + 7) / 8)); + break; + case 26: /* Binary Message, Multiple Slot */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"addressed\":%s,\"structured\":%s,\"dest_mmsi\":%u," + "\"app_id\":%u,\"data\":\"%zd:%s\"\"radio\":%u}\r\n", + JSON_BOOL(ais->type26.addressed), + JSON_BOOL(ais->type26.structured), + ais->type26.dest_mmsi, + ais->type26.app_id, + ais->type26.bitcount, + gpsd_hexdump(ais->type26.bitdata, + (ais->type26.bitcount + 7) / 8), + ais->type26.radio); + break; + default: + if (buf[strlen(buf) - 1] == ',') + buf[strlen(buf) - 1] = '\0'; + (void)strlcat(buf, "}\r\n", buflen); + break; + } + /*@ +formatcode +mustfreefresh @*/ +#undef SHOW_BOOL +} +#endif /* defined(AIVDM_ENABLE) */ + +#ifdef COMPASS_ENABLE +void json_att_dump(const struct gps_data_t *gpsdata, + /*@out@*/ char *reply, size_t replylen) +/* dump the contents of an attitude_t structure as JSON */ +{ + assert(replylen > 2); + (void)strlcpy(reply, "{\"class\":\"ATT\",", replylen); + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"tag\":\"%s\",", + gpsdata->tag[0] != '\0' ? gpsdata->tag : "-"); + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"device\":\"%s\",", gpsdata->dev.path); + if (isnan(gpsdata->attitude.heading) == 0) { + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"heading\":%.2f,", gpsdata->attitude.heading); + if (gpsdata->attitude.mag_st != '\0') + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"mag_st\":\"%c\",", gpsdata->attitude.mag_st); + + } + if (isnan(gpsdata->attitude.pitch) == 0) { + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"pitch\":%.2f,", gpsdata->attitude.pitch); + if (gpsdata->attitude.pitch_st != '\0') + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"pitch_st\":\"%c\",", + gpsdata->attitude.pitch_st); + + } + if (isnan(gpsdata->attitude.yaw) == 0) { + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"yaw\":%.2f,", gpsdata->attitude.yaw); + if (gpsdata->attitude.yaw_st != '\0') + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"yaw_st\":\"%c\",", gpsdata->attitude.yaw_st); + + } + if (isnan(gpsdata->attitude.roll) == 0) { + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"roll\":%.2f,", gpsdata->attitude.roll); + if (gpsdata->attitude.roll_st != '\0') + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"roll_st\":\"%c\",", gpsdata->attitude.roll_st); + + } + if (isnan(gpsdata->attitude.yaw) == 0) { + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"yaw\":%.2f,", gpsdata->attitude.yaw); + if (gpsdata->attitude.yaw_st != '\0') + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"yaw_st\":\"%c\",", gpsdata->attitude.yaw_st); + + } + if (isnan(gpsdata->attitude.dip) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"dip\":%.3f,", gpsdata->attitude.dip); + + if (isnan(gpsdata->attitude.mag_len) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"mag_len\":%.3f,", gpsdata->attitude.mag_len); + if (isnan(gpsdata->attitude.mag_x) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"mag_x\":%.3f,", gpsdata->attitude.mag_x); + if (isnan(gpsdata->attitude.mag_y) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"mag_y\":%.3f,", gpsdata->attitude.mag_y); + if (isnan(gpsdata->attitude.mag_z) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"mag_z\":%.3f,", gpsdata->attitude.mag_z); + + if (isnan(gpsdata->attitude.acc_len) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"acc_len\":%.3f,", gpsdata->attitude.acc_len); + if (isnan(gpsdata->attitude.acc_x) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"acc_x\":%.3f,", gpsdata->attitude.acc_x); + if (isnan(gpsdata->attitude.acc_y) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"acc_y\":%.3f,", gpsdata->attitude.acc_y); + if (isnan(gpsdata->attitude.acc_z) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"acc_z\":%.3f,", gpsdata->attitude.acc_z); + + if (isnan(gpsdata->attitude.gyro_x) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"gyro_x\":%.3f,", gpsdata->attitude.gyro_x); + if (isnan(gpsdata->attitude.gyro_y) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"gyro_y\":%.3f,", gpsdata->attitude.gyro_y); + + if (isnan(gpsdata->attitude.temp) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"temp\":%.3f,", gpsdata->attitude.temp); + if (isnan(gpsdata->attitude.depth) == 0) + (void)snprintf(reply + strlen(reply), + replylen - strlen(reply), + "\"depth\":%.3f,", gpsdata->attitude.depth); + + if (reply[strlen(reply) - 1] == ',') + reply[strlen(reply) - 1] = '\0'; /* trim trailing comma */ + (void)strlcat(reply, "}\r\n", replylen); +} +#endif /* COMPASS_ENABLE */ + + +/* gpsd_json.c ends here */ diff --git a/gpsd_report.c b/gpsd_report.c new file mode 100644 index 0000000..956b5f0 --- /dev/null +++ b/gpsd_report.c @@ -0,0 +1,24 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include "gpsd.h" + + +# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +void gpsd_report(int errlevel UNUSED, const char *fmt, ...) + __attribute__ ((weak)); +#endif + +void gpsd_report(int errlevel UNUSED, const char *fmt, ...) +/* stub logger for clients that don't supply one */ +{ + va_list ap; + + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); +} diff --git a/gpsdclient.c b/gpsdclient.c new file mode 100644 index 0000000..4e99123 --- /dev/null +++ b/gpsdclient.c @@ -0,0 +1,188 @@ +/* + * gpsdclient.c -- support functions for GPSD clients + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include +#include + +#include "gpsd_config.h" +#include "gps.h" +#include "gpsdclient.h" + +#ifdef HAVE_SETLOCALE +#include +#endif + +/* convert double degrees to a static string and return a pointer to it + * + * deg_str_type: + * deg_dd : return DD.dddddd + * deg_ddmm : return DD MM.mmmm' + * deg_ddmmss : return DD MM' SS.sss" + * + */ +/*@observer@*/ char *deg_to_str(enum deg_str_type type, double f) +{ + static char str[40]; + int dsec, sec, deg, min; + long frac_deg; + double fdsec, fsec, fdeg, fmin; + + if (f < 0 || f > 360) { + (void)strlcpy(str, "nan", 40); + return str; + } + + fmin = modf(f, &fdeg); + deg = (int)fdeg; + frac_deg = (long)(fmin * 1000000); + + if (deg_dd == type) { + /* DD.dddddd */ + (void)snprintf(str, sizeof(str), "%3d.%06ld", deg, frac_deg); + return str; + } + fsec = modf(fmin * 60, &fmin); + min = (int)fmin; + sec = (int)(fsec * 10000.0); + + if (deg_ddmm == type) { + /* DD MM.mmmm */ + (void)snprintf(str, sizeof(str), "%3d %02d.%04d'", deg, min, sec); + return str; + } + /* else DD MM SS.sss */ + fdsec = modf(fsec * 60, &fsec); + sec = (int)fsec; + dsec = (int)(fdsec * 1000.0); + (void)snprintf(str, sizeof(str), "%3d %02d' %02d.%03d\"", deg, min, sec, + dsec); + + return str; +} + +/* + * check the environment to determine proper GPS units + * + * clients should only call this if no user preference is specified on + * the command line or via X resources. + * + * return imperial - Use miles/feet + * nautical - Use knots/feet + * metric - Use km/meters + * unspecified - use compiled default + * + * In order check these environment vars: + * GPSD_UNITS one of: + * imperial = miles/feet + * nautical = knots/feet + * metric = km/meters + * LC_MEASUREMENT + * en_US = miles/feet + * C = miles/feet + * POSIX = miles/feet + * [other] = km/meters + * LANG + * en_US = miles/feet + * C = miles/feet + * POSIX = miles/feet + * [other] = km/meters + * + * if none found then return compiled in default + */ +enum unit gpsd_units(void) +{ + char *envu = NULL; + +#ifdef HAVE_SETLOCALE + (void)setlocale(LC_NUMERIC, "C"); +#endif + if ((envu = getenv("GPSD_UNITS")) != NULL && *envu != '\0') { + if (0 == strcasecmp(envu, "imperial")) { + return imperial; + } + if (0 == strcasecmp(envu, "nautical")) { + return nautical; + } + if (0 == strcasecmp(envu, "metric")) { + return metric; + } + /* unrecognized, ignore it */ + } + if (((envu = getenv("LC_MEASUREMENT")) != NULL && *envu != '\0') + || ((envu = getenv("LANG")) != NULL && *envu != '\0')) { + if (strncasecmp(envu, "en_US", 5) == 0 + || strcasecmp(envu, "C") == 0 || strcasecmp(envu, "POSIX") == 0) { + return imperial; + } + /* Other, must be metric */ + return metric; + } + /* TODO: allow a compile time default here */ + return unspecified; +} + +/*@ -observertrans -statictrans -mustfreeonly -branchstate -kepttrans @*/ +void gpsd_source_spec(const char *arg, struct fixsource_t *source) +/* standard parsing of a GPS data source spec */ +{ + source->server = "localhost"; + source->port = DEFAULT_GPSD_PORT; + source->device = NULL; + + /*@-usedef@ Sigh, splint is buggy */ + if (arg != NULL) { + char *colon1, *skipto, *rbrk; + source->spec = strdup(arg); + assert(source->spec != NULL); + + skipto = source->spec; + if (*skipto == '[' && (rbrk = strchr(skipto, ']')) != NULL) { + skipto = rbrk; + } + colon1 = strchr(skipto, ':'); + + if (colon1 != NULL) { + char *colon2; + *colon1 = '\0'; + if (colon1 != source->spec) { + source->server = source->spec; + } + source->port = colon1 + 1; + colon2 = strchr(source->port, ':'); + if (colon2 != NULL) { + *colon2 = '\0'; + source->device = colon2 + 1; + } + } else if (strchr(source->spec, '/') != NULL) { + source->device = source->spec; + } else { + source->server = source->spec; + } + } + + /*@-modobserver@*/ + if (*source->server == '[') { + char *rbrk = strchr(source->server, ']'); + ++source->server; + if (rbrk != NULL) + *rbrk = '\0'; + } + /*@+modobserver@*/ + /*@+usedef@*/ +} + +/*@ +observertrans -statictrans +mustfreeonly +branchstate +kepttrans @*/ + +/* gpsclient.c ends here */ diff --git a/gpsdclient.h b/gpsdclient.h new file mode 100644 index 0000000..dc984f6 --- /dev/null +++ b/gpsdclient.h @@ -0,0 +1,30 @@ +/* + * gpsdclient.h -- common functions for GPSD clients + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + */ + +#ifndef _GPSD_GPSDCLIENT_H_ +#define _GPSD_GPSDCLIENT_H_ +struct fixsource_t +/* describe a data source */ +{ + char *spec; /* pointer to actual storage */ + char *server; + char *port; + /*@null@*/char *device; +}; + +enum unit {unspecified, imperial, nautical, metric}; +enum unit gpsd_units(void); +enum deg_str_type { deg_dd, deg_ddmm, deg_ddmmss }; + +extern /*@observer@*/ char *deg_to_str( enum deg_str_type type, double f); + +extern void gpsd_source_spec(/*@null@*/const char *fromstring, + /*@out@*/struct fixsource_t *source); + +#endif /* _GPSDCLIENT_H_ */ +/* gpsdclient.h ends here */ diff --git a/gpsdecode.c b/gpsdecode.c new file mode 100644 index 0000000..b021265 --- /dev/null +++ b/gpsdecode.c @@ -0,0 +1,509 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "gps_json.h" + +static int verbose = 0; +static bool scaled = true; +static bool json = false; + +/************************************************************************** + * + * Generic machinery + * + **************************************************************************/ + +void gpsd_report(int errlevel, const char *fmt, ...) +/* assemble command in printf(3) style, use stderr or syslog */ +{ + if (errlevel <= verbose) { + char buf[BUFSIZ]; + va_list ap; + + (void)strlcpy(buf, "gpsdecode: ", BUFSIZ); + va_start(ap, fmt); + (void)vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, + ap); + va_end(ap); + (void)fputs(buf, stdout); + } +} + +static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen) +{ + (void)snprintf(buf, buflen, "%u|%u|%09u|", ais->type, ais->repeat, + ais->mmsi); + /*@ -formatcode @*/ + switch (ais->type) { + case 1: /* Position Report */ + case 2: + case 3: + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%d|%u|%u|%d|%d|%u|%u|%u|0x%x|%u|0x%x", + ais->type1.status, + ais->type1.turn, + ais->type1.speed, + (uint) ais->type1.accuracy, + ais->type1.lon, + ais->type1.lat, + ais->type1.course, + ais->type1.heading, + ais->type1.second, + ais->type1.maneuver, + (uint) ais->type1.raim, ais->type1.radio); + break; + case 4: /* Base Station Report */ + case 11: /* UTC/Date Response */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%04u-%02u-%02uT%02u:%02u:%02uZ|%u|%d|%d|%u|%u|0x%x", + ais->type4.year, + ais->type4.month, + ais->type4.day, + ais->type4.hour, + ais->type4.minute, + ais->type4.second, + (uint) ais->type4.accuracy, + ais->type4.lon, + ais->type4.lat, + ais->type4.epfd, + (uint) ais->type4.raim, ais->type4.radio); + break; + case 5: /* Ship static and voyage related data */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%s|%s|%u|%u|%u|%u|%u|%u|%02u-%02uT%02u:%02uZ|%u|%s|%u", + ais->type5.imo, + ais->type5.ais_version, + ais->type5.callsign, + ais->type5.shipname, + ais->type5.shiptype, + ais->type5.to_bow, + ais->type5.to_stern, + ais->type5.to_port, + ais->type5.to_starboard, + ais->type5.epfd, + ais->type5.month, + ais->type5.day, + ais->type5.hour, + ais->type5.minute, + ais->type5.draught, + ais->type5.destination, ais->type5.dte); + break; + case 6: /* Binary Message */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%u|%u|%zd:%s", + ais->type6.seqno, + ais->type6.dest_mmsi, + (uint) ais->type6.retransmit, + ais->type6.dac, + ais->type6.fid, + ais->type6.bitcount, + gpsd_hexdump(ais->type6.bitdata, + (ais->type6.bitcount + 7) / 8)); + break; + case 7: /* Binary Acknowledge */ + case 13: /* Safety Related Acknowledge */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%u", + ais->type7.mmsi1, + ais->type7.mmsi2, ais->type7.mmsi3, ais->type7.mmsi4); + break; + case 8: /* Binary Broadcast Message */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%zd:%s", + ais->type8.dac, + ais->type8.fid, + ais->type8.bitcount, + gpsd_hexdump(ais->type8.bitdata, + (ais->type8.bitcount + 7) / 8)); + break; + case 9: + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%d|%d|%u|%u|0x%x|%u|%u|0x%x", + ais->type9.alt, + ais->type9.speed, + (uint) ais->type9.accuracy, + ais->type9.lon, + ais->type9.lat, + ais->type9.course, + ais->type9.second, + ais->type9.regional, + ais->type9.dte, + (uint) ais->type9.raim, ais->type9.radio); + break; + case 10: /* UTC/Date Inquiry */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u", ais->type10.dest_mmsi); + break; + case 12: /* Safety Related Message */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%s", + ais->type12.seqno, + ais->type12.dest_mmsi, + (uint) ais->type12.retransmit, ais->type12.text); + break; + case 14: /* Safety Related Broadcast Message */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%s", ais->type14.text); + break; + case 15: + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%u|%u|%u|%u|%u", + ais->type15.mmsi1, + ais->type15.type1_1, + ais->type15.offset1_1, + ais->type15.type1_2, + ais->type15.offset1_2, + ais->type15.mmsi2, + ais->type15.type2_1, ais->type15.offset2_1); + break; + case 16: + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%u|%u|%u", + ais->type16.mmsi1, + ais->type16.offset1, + ais->type16.increment1, + ais->type16.mmsi2, + ais->type16.offset2, ais->type16.increment2); + break; + case 17: + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%d|%d|%zd:%s", + ais->type17.lon, + ais->type17.lat, + ais->type17.bitcount, + gpsd_hexdump(ais->type17.bitdata, + (ais->type17.bitcount + 7) / 8)); + break; + case 18: + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%d|%d|%u|%u|%u|0x%x|%u|%u|%u|%u|%u|%u|0x%x", + ais->type18.reserved, + ais->type18.speed, + (uint) ais->type18.accuracy, + ais->type18.lon, + ais->type18.lat, + ais->type18.course, + ais->type18.heading, + ais->type18.second, + ais->type18.regional, + (uint) ais->type18.cs, + (uint) ais->type18.display, + (uint) ais->type18.dsc, + (uint) ais->type18.band, + (uint) ais->type18.msg22, + (uint) ais->type18.raim, ais->type18.radio); + break; + case 19: + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%d|%d|%u|%u|%u|0x%x|%s|%u|%u|%u|%u|%u|%u|%u|%u|%u", + ais->type19.reserved, + ais->type19.speed, + (uint) ais->type19.accuracy, + ais->type19.lon, + ais->type19.lat, + ais->type19.course, + ais->type19.heading, + ais->type19.second, + ais->type19.regional, + ais->type19.shipname, + ais->type19.shiptype, + ais->type19.to_bow, + ais->type19.to_stern, + ais->type19.to_port, + ais->type19.to_starboard, + ais->type19.epfd, + (uint) ais->type19.raim, + ais->type19.dte, (uint) ais->type19.assigned); + break; + case 20: /* Data Link Management Message */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u", + ais->type20.offset1, + ais->type20.number1, + ais->type20.timeout1, + ais->type20.increment1, + ais->type20.offset2, + ais->type20.number2, + ais->type20.timeout2, + ais->type20.increment2, + ais->type20.offset3, + ais->type20.number3, + ais->type20.timeout3, + ais->type20.increment3, + ais->type20.offset4, + ais->type20.number4, + ais->type20.timeout4, ais->type20.increment4); + break; + case 21: /* Aid to Navigation */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%s|%u|%d|%d|%u|%u|%u|%u|%u|%u|%u|0x%x|%u|%u", + ais->type21.aid_type, + ais->type21.name, + (uint) ais->type21.accuracy, + ais->type21.lon, + ais->type21.lat, + ais->type21.to_bow, + ais->type21.to_stern, + ais->type21.to_port, + ais->type21.to_starboard, + ais->type21.epfd, + ais->type21.second, + ais->type21.regional, + (uint) ais->type21.off_position, + (uint) ais->type21.raim, + (uint) ais->type21.virtual_aid); + break; + case 22: /* Channel Management */ + if (!ais->type22.addressed) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%u|%d|%d|%d|%d|%u|%u|%u|%u", + ais->type22.channel_a, + ais->type22.channel_b, + ais->type22.txrx, + (uint) ais->type22.power, + ais->type22.area.ne_lon, + ais->type22.area.ne_lat, + ais->type22.area.sw_lon, + ais->type22.area.sw_lat, + (uint) ais->type22.addressed, + (uint) ais->type22.band_a, + (uint) ais->type22.band_b, ais->type22.zonesize); + else + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%u|%u|%u|%u|%u|%u|%u", + ais->type22.channel_a, + ais->type22.channel_b, + ais->type22.txrx, + (uint) ais->type22.power, + ais->type22.mmsi.dest1, + ais->type22.mmsi.dest2, + (uint) ais->type22.addressed, + (uint) ais->type22.band_a, + (uint) ais->type22.band_b, ais->type22.zonesize); + break; + case 23: /* Group Management Command */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%d|%d|%d|%d|%u|%u|%u|%u|%u", + ais->type23.ne_lon, + ais->type23.ne_lat, + ais->type23.sw_lon, + ais->type23.sw_lat, + ais->type23.stationtype, + ais->type23.shiptype, + ais->type23.txrx, + ais->type23.interval, ais->type23.quiet); + break; + case 24: /* Class B CS Static Data Report */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%s|", ais->type24.shipname); + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|", ais->type24.shiptype); + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%s|%s|", ais->type24.vendorid, ais->type24.callsign); + if (AIS_AUXILIARY_MMSI(ais->mmsi)) { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u", ais->type24.mothership_mmsi); + } else { + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%u", + ais->type24.dim.to_bow, + ais->type24.dim.to_stern, + ais->type24.dim.to_port, + ais->type24.dim.to_starboard); + } + break; + case 25: /* Binary Message, Single Slot */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%u|%zd:%s\r\n", + (uint) ais->type25.addressed, + (uint) ais->type25.structured, + ais->type25.dest_mmsi, + ais->type25.app_id, + ais->type25.bitcount, + gpsd_hexdump(ais->type25.bitdata, + (ais->type25.bitcount + 7) / 8)); + break; + case 26: /* Binary Message, Multiple Slot */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "%u|%u|%u|%u|%zd:%s:%u\r\n", + (uint) ais->type26.addressed, + (uint) ais->type26.structured, + ais->type26.dest_mmsi, + ais->type26.app_id, + ais->type26.bitcount, + gpsd_hexdump(ais->type26.bitdata, + (ais->type26.bitcount + 7) / 8), + ais->type26.radio); + break; + default: + (void)snprintf(buf + strlen(buf), + buflen - strlen(buf), + "unknown AIVDM message content."); + break; + } + /*@ +formatcode @*/ + (void)strlcat(buf, "\r\n", buflen); +} + +/*@ -compdestroy -compdef -usedef @*/ +static void decode(FILE * fpin, FILE * fpout) +/* RTCM or AIS packets on fpin to dump format on fpout */ +{ + struct gps_packet_t lexer; + struct rtcm2_t rtcm2; + struct rtcm3_t rtcm3; + struct ais_t ais; + struct aivdm_context_t aivdm[AIVDM_CHANNELS]; + char buf[BUFSIZ]; + + memset(&aivdm, '\0', sizeof(aivdm)); + packet_reset(&lexer); + + while (packet_get(fileno(fpin), &lexer) > 0) { + if (lexer.type == COMMENT_PACKET) + continue; +#ifdef RTCM104V2_ENABLE + else if (lexer.type == RTCM2_PACKET) { + rtcm2_unpack(&rtcm2, (char *)lexer.isgps.buf); + if (json) + rtcm2_json_dump(&rtcm2, buf, sizeof(buf)); + else + rtcm2_sager_dump(&rtcm2, buf, sizeof(buf)); + (void)fputs(buf, fpout); + } +#endif +#ifdef RTCM104V3_ENABLE + else if (lexer.type == RTCM3_PACKET) { + rtcm3_unpack(&rtcm3, (char *)lexer.outbuffer); + rtcm3_dump(&rtcm3, stdout); + } +#endif + else if (lexer.type == AIVDM_PACKET) { + if (verbose >= 1) + (void)fputs((char *)lexer.outbuffer, stdout); + /*@ -uniondef */ + if (aivdm_decode + ((char *)lexer.outbuffer, lexer.outbuflen, aivdm, &ais)) { + if (!json) + aivdm_csv_dump(&ais, buf, sizeof(buf)); + else + aivdm_json_dump(&ais, scaled, buf, sizeof(buf)); + (void)fputs(buf, fpout); + } + + /*@ +uniondef */ + } + } +} + +/*@ +compdestroy +compdef +usedef @*/ + +/*@ -compdestroy @*/ +static void encode(FILE * fpin, FILE * fpout) +/* dump format on fpin to RTCM-104 on fpout */ +{ + char inbuf[BUFSIZ]; + struct gps_data_t gpsdata; + int lineno = 0; + + memset(&gpsdata, '\0', sizeof(gpsdata)); /* avoid segfault due to garbage in thread-hook slots */ + while (fgets(inbuf, (int)sizeof(inbuf), fpin) != NULL) { + int status; + + ++lineno; + if (inbuf[0] == '#') + continue; + status = libgps_json_unpack(inbuf, &gpsdata, NULL); + if (status != 0) { + (void)fprintf(stderr, + "gpsdecode: bailing out with status %d (%s) on line %d\n", + status, json_error_string(status), lineno); + exit(1); + } + if ((gpsdata.set & RTCM2_SET) != 0) { + /* this works */ + char outbuf[BUFSIZ]; + rtcm2_json_dump(&gpsdata.rtcm2, outbuf, sizeof(outbuf)); + (void)fputs(outbuf, fpout); + } + if ((gpsdata.set & AIS_SET) != 0) { + char outbuf[BUFSIZ]; + aivdm_json_dump(&gpsdata.ais, false, outbuf, sizeof(outbuf)); + (void)fputs(outbuf, fpout); + } + } +} + +/*@ +compdestroy @*/ + +int main(int argc, char **argv) +{ + int c; + enum + { doencode, dodecode } mode = dodecode; + + while ((c = getopt(argc, argv, "cdejpuVD:")) != EOF) { + switch (c) { + case 'c': + json = false; + break; + + case 'd': + mode = dodecode; + break; + + case 'e': + mode = doencode; + break; + + case 'j': + json = true; + break; + + case 'u': + scaled = false; + break; + + case 'D': + verbose = atoi(optarg); + gpsd_hexdump_level = verbose; +#ifdef CLIENTDEBUG_ENABLE + json_enable_debug(verbose - 2, stderr); +#endif + break; + + case 'V': + (void)fprintf(stderr, "gpsdecode revision " VERSION "\n"); + exit(0); + + case '?': + default: + (void)fputs("gpsdecode [-v]\n", stderr); + exit(1); + } + } + argc -= optind; + argv += optind; + + if (mode == doencode) + encode(stdin, stdout); + else + decode(stdin, stdout); + exit(0); +} + +/* gpsdecode.c ends here */ diff --git a/gpsdecode.xml b/gpsdecode.xml new file mode 100644 index 0000000..4ca2176 --- /dev/null +++ b/gpsdecode.xml @@ -0,0 +1,204 @@ + + + + +13 Jul 2005 + +gpsdecode +1 +The GPSD Project +GPSD Documentation + + +gpsdecode +decode RTCM or AIVDM streams into a readable format + + + + + gpsdecode + -c + -d + -e + -j + -u + -D debuglevel + -V + + + +DESCRIPTION + +This tool is a decoder/encoder for various binary packet formats +associated with GPS and differential-correction services. It produces +a text dump on standard output from binary on standard input, or +binary packets on standard output from text on standard input, and +aims to be 100% information-preserving in both directions. As well as +data, the decoder also prints decoder status messages to standard +error as necessary. + +Two of the supported formats are RTCM 2 and 3, a pair of obscure +and complicated serial protocol used for broadcasting pseudorange +corrections from differential-GPS reference stations. You can use this +mode of the tool with +nc1 +to examine RTCM feeds from DGPSIP servers or Ntrip broadcasters. The +decoder dump formats for RTCM2 are described in +rtcm5; +these lines go to standard output. + +Another supported format is AIVDM. This is the sentence format +used by the marine Automatic Identification System. This can be +decoded, but not yet encoded. + + +OPTIONS + +The option tells the program to decode +packets presented on standard input to a text dump on standard +output. This is the default behavior. + +RTCM2 will be dumped in one of the formats of +rtcm-1045 +on standard output. + +The option option tells the program to +encode a text dump in one of the formats of +rtcm-1045 +to standard output. This option is a placeholder: support for RTCM2 +encoding from the Sager format has been removed + +The suppresses scaling of AIS data to float quantities +and text expansion of numeric codes. A dump with this option is +lossless. + +The sets the dump format to JSON, with +each each field preceded by a quoted label and colon and the +entire dump line wrapped in curly braces. + +The sets the AIS dump format to separate +fields with an ASCII pipe symbol. Fields are dumped in the order they +occur in the AIS packet. Numerics are not scaled. Strings are unpacked +from six-bit to full ASCII + +The option directs the program to emit its +version number, then exit. + +The option sets a debug verbosity level. It is +mainly of interest to developers. + + +AIS DUMP FORMATS + +Without the option, dump lines are values of AIS +payload fields, pipe-separated, in the order that they occur in the +payload. Spans of fields expressing a date are emitted as an ISO8601 +timestamp (look for colons and the trailing Z indicating Zulu/UTC +time), and the 19-bit group of TDMA status fields found at the end of +message types 1-4 are are dumped as a single unsigned integer (in hex +preceded by "0x"). Unused regional-authority fields are also dumped +(in hex preceded by "0x"). Variable-length binary fields are dumped as +an integer bit length, followed by a colon, followed by a hex +dump. + +By default, certain scaling and conversion operations are +performed for the output. Latitudes and longitudes are scaled to +decimal degrees rather than the native AIS unit of 1/10000th of a +minute of arc. Ship (but not air) speeds are scaled to knots rather +than tenth-of-knot units. Navigation status and positioning-system +type are dumped as text strings rather than IAS numeric codes. Rate of +turn may appear as "nan" if is unavailable, or as one of the strings +"fastright" or "fastleft" if it is out of the IAS encoding range; +otherwise it is quadratically mapped back to the turn sensor number in +degrees per minute. Vessel draughts are converted to decimal meters +rather than native AIS decimeters. + +With the option, the AIS dump format changes +to JSON. Data fields are handled as described above in scaled and +unscaled modes, but are values attached to JSON attributes as +described in AIVDM/AIVDO protocol +decoding. + + +APPLICABLE STANDARDS + +The applicable standard for V2 is RTCM Recommended +Standards for Differential NAVSTAR GPS Service RTCM Paper +194-93/SC 104-STD. + +Note that gpsdecode presently +recognizes only the 2.1 level of RTCM; the protocol was revised up to +a version 2.3 including additional messages relating to GLONASS and +real-time kinematics before being deprecated in favor of V3. It is +now semi-obsolete. + +The applicable standard for V3 is RTCM Standard +10403.1 for Differential GNSS Services - Version 3 RTCM +Paper 177-2006-SC104-STD. + +Ordering instructions for the RTCM standards are accessible from +the website of the Radio Technical +Commission for Maritime Services under "Publications". + +The applicable standard for AIVDM is ITU-R M.1371: +ITU Recommendation on the Technical Characteristics for a Universal +Shipborne Automatic Identification System (AIS) using Time Division +Multiple Access in the Maritime Mobile Band, A more +accessible description can be found at AIVDM/AIVDO protocol +decoding on the references page of the +GPSD project website. + + +BUGS AND LIMITATIONS + +AIDVM decoding of types 16-17, 22-23, and 25-26 is unverified. + +RTCM3 decoding is buggy and incomplete. + +RTCM2 represents floating-point quantities as an integer +multiple of a fixed scale factor. Editing an RTCM2 dump can produce +numbers that are not an integer multiple of the scale factor for their +field. If you do this, the value actually packed into binary RTCM2 +will be rounded down to the nearest scale unit, and dumping will show +slightly different numbers than those you entered. This bug could be +fixed by supporting the option to suppress +scaling. + +The RTCM2 decoder logic is sufficiently convoluted to confuse some +compiler optimizers, notably in GCC 3.x at -O2, into generating bad +code. + +Older version of this utility used comma as a field separator with +the option. This was a mistake, as ship name and +other string fields can contain commas. + + +SEE ALSO + +gpsd8, +gps1, +libgps3, +libgpsd3, +gpsprof1, +gpsfake1, +rtcm-1045. + + +AUTHOR + +Eric S. Raymond esr@thyrsus.com. This is a +somewhat hacked version of an RTCM decoder originally written by +Wolfgang Rupprecht. There is a project page for +gpsd here. + + + + diff --git a/gpsfake b/gpsfake new file mode 100755 index 0000000..82874bc --- /dev/null +++ b/gpsfake @@ -0,0 +1,207 @@ +#!/usr/bin/env python +# +# gpsfake -- test harness for gpsd +# +# Simulates a GPS, playing back a logfile +# Most of the logic for this now lives in gps.fake, +# factored out so we can write other test programs with it. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. + +import sys, os, signal, time, getopt, socket, random +import gps.fake + +class Baton: + "Ship progress indications to stderr." + def __init__(self, prompt, endmsg=None): + self.stream = sys.stderr + self.stream.write(prompt + "...") + if os.isatty(self.stream.fileno()): + self.stream.write(" \010") + self.stream.flush() + self.count = 0 + self.endmsg = endmsg + self.time = time.time() + return + + def twirl(self, ch=None): + if self.stream is None: + return + if os.isatty(self.stream.fileno()): + if ch: + self.stream.write(ch) + else: + self.stream.write("-/|\\"[self.count % 4]) + self.stream.write("\010") + self.stream.flush() + self.count = self.count + 1 + return + + def end(self, msg=None): + if msg == None: + msg = self.endmsg + if self.stream: + self.stream.write("...(%2.2f sec) %s.\n" % (time.time() - self.time, msg)) + return + +def fakeport(): + "Find a port that isn't in use to bind to." + # Grab a random port from IANA's unassigned/private range. Not perfect, + # but at least less than in 16000 chance of a pair collision. It would + # be very hard to get this deterministically correct, since there would + # always be a window between port allocation and when the daemon picked + # it up. We'd need to do some kind of semaphore, etc., and even that + # wouldn't prevent collisions with other apps using the range. + return random.randint(49152, 65535) + +def hexdump(s): + rep = "" + for c in s: + rep += "%02x" % ord(c) + return rep + +def fakehook(linenumber, fakegps): + if len(fakegps.testload.sentences) == 0: + print >>sys.stderr, "fakegps: no sentences in test load." + raise SystemExit, 1 + if linenumber % len(fakegps.testload.sentences) == 0: + if singleshot and linenumber > 0: + return False + if progress: + baton.twirl('*\010') + elif not singleshot: + sys.stderr.write("gpsfake: log cycle of %s begins.\n" % fakegps.testload.name) + time.sleep(cycle) + if linedump and fakegps.testload.legend: + ml = fakegps.testload.sentences[linenumber % len(fakegps.testload.sentences)].strip() + if not fakegps.testload.textual: + ml = hexdump(ml) + announce = fakegps.testload.legend % (linenumber % len(fakegps.testload.sentences) + 1) + ml + if promptme: + raw_input(announce + "? ") + else: + print announce + if progress: + baton.twirl() + return True + +if __name__ == '__main__': + try: + (options, arguments) = getopt.getopt(sys.argv[1:], "1bc:D:fghilm:no:pr:s:uvx") + except getopt.GetoptError, msg: + print "gpsfake: " + str(msg) + raise SystemExit, 1 + + if not arguments: + print >>sys.stderr, "gpsfake: requires at least one logfile argument." + raise SystemExit, 1 + + port = None + progress = False + cycle = 0 + monitor = "" + speed = 4800 + linedump = False + predump = False + pipe = False + singleshot = False + promptme = False + client_init = '?WATCH={"json":true,"nmea":true}' + doptions = "" + udp = False + verbose = 0 + for (switch, val) in options: + if (switch == '-1'): + singleshot = True + port = fakeport() + elif (switch == '-b'): + progress = True + elif (switch == '-c'): + cycle = float(val) + elif (switch == '-D'): + doptions += " -D " + val + elif (switch == '-g'): + monitor = "xterm -e gdb -tui --args " + elif (switch == '-i'): + linedump = promptme = True + elif (switch == '-l'): + linedump = True + elif (switch == '-m'): + monitor = val + " " + elif (switch == '-n'): + doptions += " -n" + elif (switch == '-x'): + predump = True + elif (switch == '-o'): + doptions = val + elif (switch == '-p'): + pipe = True + elif (switch == '-r'): + client_init = val + elif (switch == '-s'): + speed = int(val) + elif (switch == '-u'): + udp = True + elif (switch == '-v'): + verbose += 1 + elif (switch == '-h'): + sys.stderr.write("usage: gpsfake [-h] [-l] [-m monitor] [--D debug] [-o options] [-p] [-s speed] [-c cycle] [-b] logfile\n") + raise SystemExit,0 + + if progress: + baton = Baton("Processing %s" % ",".join(arguments), "done") + else: + print >>sys.stderr, "Processing %s" % ",".join(arguments) + + test = gps.fake.TestSession(prefix=monitor, port=port, options=doptions, udp=udp, verbose=verbose, predump=predump) + + if pipe: + test.reporter = sys.stdout.write + if verbose: + progress = False + test.progress = sys.stdout.write + test.spawn() + try: + for logfile in arguments: + try: + test.gps_add(logfile, speed=speed, pred=fakehook) + except gps.fake.TestLoadError, e: + sys.stderr.write("gpsfake: " + e.msg + "\n") + raise SystemExit, 1 + except gps.fake.PacketError, e: + sys.stderr.write("gpsfake: " + e.msg + "\n") + raise SystemExit, 1 + except gps.fake.DaemonError, e: + sys.stderr.write("gpsfake: " + e.msg + "\n") + raise SystemExit, 1 + except IOError, e: + sys.stderr.write("gpsfake: no such file as %s or file unreadable\n"%e.filename) + raise SystemExit, 1 + except OSError: + sys.stderr.write("gpsfake: can't open pty.\n") + raise SystemExit, 1 + + try: + if pipe: + test.client_add(client_init + "\n") + # Give daemon time to get ready for the feeds. + # Without a delay here there's a window for test + # sentences to arrive before the watch takes effect. + # This needs to increase if leading sentences in + # test loads aren't being processed. + time.sleep(1) + test.run() + except socket.error, msg: + sys.stderr.write("gpsfake: socket error %s.\n" % msg) + raise SystemExit, 1 + finally: + test.cleanup(); + + if progress: + baton.end() + +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:python +# End: diff --git a/gpsfake.xml b/gpsfake.xml new file mode 100644 index 0000000..17b6dd0 --- /dev/null +++ b/gpsfake.xml @@ -0,0 +1,192 @@ + + + + +12 Feb 2005 + +gpsfake +1 +The GPSD Project +GPSD Documentation + + +gpsfake +test harness for gpsd, simulating a GPS + + + + + gpsfake + -1 + -h + -b + -c interval + -i + -D debuglevel + -l + -m monitor + -n + -o options + -p + -r initcmd + -s speed + -u + -v + + logfile + + + + +DESCRIPTION + +gpsfake is a test harness for +gpsd and its clients. It opens a pty +(pseudo-TTY), launches a gpsd instance that +thinks the slave side of the pty is its GPS device, and repeatedly +feeds the contents of one or more test logfiles through the master side to the +GPS. If there are multiple logfiles, sentences from them are +interleaved in the order the fuiles are specified. + +gpsfake does not require root +privileges, and can be run concurrently with a production +gpsd instance without causing problems. + +The logfiles may be of NMEA, SiRF packets, TSIP packets, or +Zodiac packets. Leading lines beginning with # will be treated as +comments and ignored. + +The gpsd instance is run in +foreground. The thread sending fake GPS data to the daemon +is run in background. + + +OPTIONS + +With the -1 option, the logfile is interpreted once only rather +than repeatedly. This option is intended to facilitate regression +testing. + +The -b option enables a twirling-baton progress indicator +on standard error. At termination, it reports elapsed time. + +The -c option sets the delay between sentences in +seconds. Fractional values of seconds are legal. The default is zero +(no delay). + +The -l option makes the program dump a line or packet number +just before each sentence is fed to the daemon. If the sentence is +textual (e.g. NMEA), the text is dumped as well. If not, the packet +will be dumped in hexadecimal (except for RTCM packets, which aren't +dumped at all). This option is useful for checking that gpsfake is +getting packet boundaries right. + +The -i option is for single-stepping through logfiles. It dumps +the line or packet number (and the sentence if the protocol is +textual) followed by "? ". Only when the user keys Enter is the line +actually fed to gpsd. + +The -m option specifies a monitor program inside which the +daemon should be run. This option is intended to be used with +valgrind1, +gdb1 +and similar programs. + +The -g option uses the monitor facility to run the +gpsd instance within gpsfake under control +of gdb. + +The -o option specifies options to pass to the daemon. The -n +option passes -n to start the daemon reading the GPS without waiting +for a client (equivalent to -o "-n"). The -D option passes a -D +option to the daemon: thus -D 4 is shorthand for -o "-D 4". + +The -p ("pipe") option sets watcher mode and dumps the NMEA and GPSD +notifications generated by the log to standard output. This is useful +for regression-testing. + +The -r option specifies an initialization command to use in pipe mode. +The default is ?WATCH={"enable":true,"json":true}. + +The -s option sets the baud rate for the slave tty. The +default is 4800. + +The -u option forces the test framework to use UDP rather than +pty devices. This may be useful for testing from within chroot jails +where access to pty devices is locked out. + +The -v option enables verbose progress reports to stderr. It is +mainly useful for debugging gpsfake +itself. + +The -x option dumps packets as +gpsfake gathers them. It is mainly useful +for debugging gpsfake itself. + +The -h option makes gpsfake print +a usage message and exit. + +The argument must be the name of a file containing the +data to be cycled at the device. gpsfake +will print a notification each time it cycles. + +Normally, gpsfake creates a pty for each logfile and passes the +slave side of the debice to the daemon. If the header comment in the +logfile contains the string "UDP", packets are instead shipped via UDP +port 5000 to the addess 192.168.0.1.255. You can monitoer them with +this: tcpdump -s0 -n -A -i lo udp and port 5000. + + +CUSTOM TESTS + +gpsfake is a trivial wrapper around a +Python module, also named gpsfake, that can be used to fully script +sessions involving a gpsd instance, any +number of client sessions, and any number of fake GPSes feeding the +daemon instance with data from specified sentence logs. + +Source and embedded documentation for this module is shipped with the +gpsd development tools. You can use it to +torture-test either gpsd itself or any +gpsd-aware client application. + +Logfiles for the use with gpsfake can +be retrieved using gpspipe, +gpscat, or +gpsmon from the gpsd distribution, or any +other application which is able to create a compatible output. + +If gpsfake exits with "Cannot execute +gpsd: executable not found." the environment variable GPSD_HOME can be +set to the path where gpsd can be found. (instead of adding that folder +to the PATH envirnment variable + + +SEE ALSO + +gpsd8, +gps1, +libgps3, +libgpsd3, +gpsctl1, +gpspipe1, +gpsprof1 +gpsmon1. + + + +AUTHOR + +Eric S. Raymond esr@thyrsus.com. There is a +project page for gpsd here. + + + + + diff --git a/gpsmon.c b/gpsmon.c new file mode 100644 index 0000000..86ccb58 --- /dev/null +++ b/gpsmon.c @@ -0,0 +1,989 @@ +/* + * The generic GPS packet monitor. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +/* Cygwin has only _timezone and not timezone unless the following is set */ +#if defined(__CYGWIN__) +#define timezonevar +#endif /* defined(__CYGWIN__) */ +#include +#include +#include /* for O_RDWR */ +#include +#include +#include +#include /* for O_RDWR */ +#include + +#include "gpsd_config.h" + +#ifdef HAVE_BLUEZ +#include +#endif + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif /* HAVE_NCURSES_H */ +#include "gpsd.h" + +#include "bits.h" + +#if defined(HAVE_SYS_TIME_H) +#include +#endif +#if defined (HAVE_SYS_SELECT_H) +#include +#endif + +#include "gpsdclient.h" +#include "gpsmon.h" +#include "revision.h" + +#ifdef S_SPLINT_S +extern struct tm *localtime_r(const time_t *, /*@out@*/ struct tm *tp); +#endif /* S_SPLINT_S */ + +#define BUFLEN 2048 + +/* external capability tables */ +extern struct monitor_object_t nmea_mmt, sirf_mmt, garmin_mmt, ashtech_mmt; +extern struct monitor_object_t italk_mmt, ubx_mmt, superstar2_mmt; +extern struct monitor_object_t fv18_mmt, gpsclock_mmt, mtk3301_mmt; +extern struct monitor_object_t oncore_mmt, tnt_mmt; + +/* These are public */ +struct gps_device_t session; +WINDOW *devicewin; +int gmt_offset; + +/* These are private */ +static struct gps_context_t context; +static int controlfd = -1; +static bool serial, curses_active; +static int debuglevel = 0; +static WINDOW *statwin, *cmdwin; +/*@null@*/ static WINDOW *packetwin; +static FILE *logfile; +static char *type_name; +/*@ -nullassign @*/ +static const struct monitor_object_t *monitor_objects[] = { +#ifdef NMEA_ENABLE + &nmea_mmt, +#if defined(GARMIN_ENABLE) && defined(NMEA_ENABLE) + &garmin_mmt, +#endif /* GARMIN_ENABLE && NMEA_ENABLE */ +#ifdef ASHTECH_ENABLE + &ashtech_mmt, +#endif /* ASHTECH_ENABLE */ +#ifdef FV18_ENABLE + &fv18_mmt, +#endif /* FV18_ENABLE */ +#ifdef GPSCLOCK_ENABLE + &gpsclock_mmt, +#endif /* GPSCLOCK_ENABLE */ +#ifdef MTK3301_ENABLE + &mtk3301_mmt, +#endif /* MTK3301_ENABLE */ +#endif /* NMEA_ENABLE */ +#if defined(SIRF_ENABLE) && defined(BINARY_ENABLE) + &sirf_mmt, +#endif /* defined(SIRF_ENABLE) && defined(BINARY_ENABLE) */ +#if defined(UBX_ENABLE) && defined(BINARY_ENABLE) + &ubx_mmt, +#endif /* defined(UBX_ENABLE) && defined(BINARY_ENABLE) */ +#if defined(ITRAX_ENABLE) && defined(BINARY_ENABLE) + &italk_mmt, +#endif /* defined(ITALK_ENABLE) && defined(BINARY_ENABLE) */ +#if defined(SUPERSTAR2_ENABLE) && defined(BINARY_ENABLE) + &superstar2_mmt, +#endif /* defined(SUPERSTAR2_ENABLE) && defined(BINARY_ENABLE) */ +#if defined(ONCORE_ENABLE) && defined(BINARY_ENABLE) + &oncore_mmt, +#endif /* defined(ONCORE_ENABLE) && defined(BINARY_ENABLE) */ +#ifdef TNT_ENABLE + &tnt_mmt, +#endif /* TNT_ENABLE */ + NULL, +}; + +static const struct monitor_object_t **active; +/*@ +nullassign @*/ + +static jmp_buf terminate; + +#define display (void)mvwprintw + +/* ternination codes */ +#define TERM_SELECT_FAILED 1 +#define TERM_DRIVER_SWITCH 2 +#define TERM_EMPTY_READ 3 +#define TERM_READ_ERROR 4 + +void monitor_fixframe(WINDOW * win) +{ + int ymax, xmax, ycur, xcur; + + assert(win != NULL); + getyx(win, ycur, xcur); + getmaxyx(win, ymax, xmax); + (void)mvwaddch(win, ycur, xmax - 1, ACS_VLINE); +} + +/****************************************************************************** + * + * Device-independent I/O routines + * + ******************************************************************************/ + +void gpsd_report(int errlevel UNUSED, const char *fmt, ...) +/* our version of the logger */ +{ + if (errlevel <= debuglevel && packetwin != NULL) { + va_list ap; + va_start(ap, fmt); + if (!curses_active) + (void)vprintf(fmt, ap); + else + (void)wprintw(packetwin, (char *)fmt, ap); + va_end(ap); + } +} + +/*@ -globstate @*/ +static ssize_t readpkt(void) +{ + /*@ -type -shiftnegative -compdef -nullpass @*/ + struct timeval timeval; + fd_set select_set; + gps_mask_t changed; + + FD_ZERO(&select_set); + FD_SET(session.gpsdata.gps_fd, &select_set); + if (controlfd > -1) + FD_SET(controlfd, &select_set); + timeval.tv_sec = 3; + timeval.tv_usec = 0; + if (select(session.gpsdata.gps_fd + 1, &select_set, NULL, NULL, &timeval) + == -1) + longjmp(terminate, TERM_SELECT_FAILED); + + if (!FD_ISSET(session.gpsdata.gps_fd, &select_set)) + longjmp(terminate, TERM_SELECT_FAILED); + + changed = gpsd_poll(&session); + if (changed == 0) + longjmp(terminate, TERM_EMPTY_READ); + + if ((changed & ERROR_IS) != 0) + longjmp(terminate, TERM_READ_ERROR); + + if (logfile != NULL) { + /*@ -shiftimplementation -sefparams +charint @*/ + assert(fwrite + (session.packet.outbuffer, sizeof(char), + session.packet.outbuflen, logfile) >= 1); + /*@ +shiftimplementation +sefparams -charint @*/ + } + return session.packet.outbuflen; + /*@ +type +shiftnegative +compdef +nullpass @*/ +} + +/*@ +globstate @*/ + +static void packet_dump(char *buf, size_t buflen) +{ + if (packetwin != NULL) { + size_t i; + bool printable = true; + for (i = 0; i < buflen; i++) + if (!isprint(buf[i]) && !isspace(buf[i])) + printable = false; + if (printable) { + for (i = 0; i < buflen; i++) + if (isprint(buf[i])) + (void)waddch(packetwin, (chtype) buf[i]); + else + (void)wprintw(packetwin, "\\x%02x", + (unsigned char)buf[i]); + } else { + for (i = 0; i < buflen; i++) + (void)wprintw(packetwin, "%02x", (unsigned char)buf[i]); + } + (void)wprintw(packetwin, "\n"); + } +} + +#if defined(ALLOW_CONTROLSEND) || defined(ALLOW_RECONFIGURE) +static void monitor_dump_send(void) +{ + if (packetwin != NULL) { + (void)wattrset(packetwin, A_BOLD); + (void)wprintw(packetwin, ">>>"); + packet_dump(session.msgbuf, session.msgbuflen); + (void)wattrset(packetwin, A_NORMAL); + } +} +#endif /* defined(ALLOW_CONTROLSEND) || defined(ALLOW_RECONFIGURE) */ + +#ifdef ALLOW_CONTROLSEND +bool monitor_control_send( /*@in@*/ unsigned char *buf, size_t len) +{ + if (controlfd == -1) + return false; + else { + int savefd; + ssize_t st; + + if (!serial) { + /*@ -sefparams @*/ + assert(write(controlfd, "!", 1) != -1); + assert(write + (controlfd, session.gpsdata.dev.path, + strlen(session.gpsdata.dev.path)) != -1); + assert(write(controlfd, "=", 1) != -1); + /*@ +sefparams @*/ + /* + * Ugh...temporarily con the libgpsd layer into using the + * socket descriptor. + */ + savefd = session.gpsdata.gps_fd; + session.gpsdata.gps_fd = controlfd; + } + + st = (*active)->driver->control_send(&session, (char *)buf, len); + + if (!serial) { + /* stop pretending now */ + session.gpsdata.gps_fd = controlfd; + /* enough room for "ERROR\r\n\0" */ + /*@ -sefparams @*/ + assert(read(controlfd, buf, 8) != -1); + /*@ +sefparams @*/ + } + monitor_dump_send(); + return (st != -1); + } +} + +static bool monitor_raw_send( /*@in@*/ unsigned char *buf, size_t len) +{ + if (controlfd == -1) + return false; + else { + ssize_t st; + + if (!serial) { + /*@ -sefparams @*/ + assert(write(controlfd, "!", 1) != -1); + assert(write(controlfd, session.gpsdata.dev.path, + strlen(session.gpsdata.dev.path)) != -1); + assert(write(controlfd, "=", 1) != -1); + /*@ +sefparams @*/ + } + + st = write(controlfd, (char *)buf, len); + + if (!serial) { + /* enough room for "ERROR\r\n\0" */ + /*@ -sefparams @*/ + assert(read(controlfd, buf, 8) != -1); + /*@ +sefparams @*/ + } + (void)memcpy(session.msgbuf, buf, len); + session.msgbuflen = len; + monitor_dump_send(); + return (st > 0 && (size_t) st == len); + } +} +#endif /* ALLOW_CONTROLSEND */ + +/***************************************************************************** + * + * Main sequence and display machinery + * + *****************************************************************************/ + +static long tzoffset(void) +{ + time_t now = time(NULL); + struct tm tm; + long res = 0; + + tzset(); +#ifdef HAVE_TIMEZONE + res = timezone; +#else + res = localtime_r(&now, &tm)->tm_gmtoff; +#endif +#ifdef HAVE_DAYLIGHT + if (daylight != 0 && localtime_r(&now, &tm)->tm_isdst != 0) + res -= 3600; +#else + if (localtime_r(&now, &tm)->tm_isdst) + res -= 3600; +#endif + return res; +} + +void monitor_complain(const char *fmt, ...) +{ + va_list ap; + (void)wmove(cmdwin, 0, (int)strlen(type_name) + 2); + (void)wclrtoeol(cmdwin); + (void)wattrset(cmdwin, A_BOLD | A_BLINK); + va_start(ap, fmt); + (void)vwprintw(cmdwin, (char *)fmt, ap); + va_end(ap); + (void)wattrset(cmdwin, A_NORMAL); + (void)wrefresh(cmdwin); + (void)wgetch(cmdwin); +} + + +void monitor_log(const char *fmt, ...) +{ + if (packetwin != NULL) { + va_list ap; + va_start(ap, fmt); + (void)vwprintw(packetwin, (char *)fmt, ap); + va_end(ap); + } +} + +static bool switch_type(const struct gps_type_t *devtype) +{ + const struct monitor_object_t **trial, **newobject; + newobject = NULL; + for (trial = monitor_objects; *trial; trial++) + if ((*trial)->driver == devtype) + newobject = trial; + if (newobject) { + int leftover; + if (LINES < (*newobject)->min_y + 1 || COLS < (*newobject)->min_x) { + monitor_complain("New type requires %dx%d screen", + (*newobject)->min_x, (*newobject)->min_y + 1); + } else { + if (active != NULL) { + (*active)->wrap(); + (void)delwin(devicewin); + } + active = newobject; + devicewin = newwin((*active)->min_y, (*active)->min_x, 1, 0); + if ((devicewin == NULL) || !(*active)->initialize()) { + monitor_complain("Internal initialization failure - screen " + "must be at least 80x24. aborting."); + return false; + } + + /*@ -onlytrans @*/ + leftover = LINES - 1 - (*active)->min_y; + if (leftover <= 0) { + if (packetwin != NULL) + (void)delwin(packetwin); + packetwin = NULL; + } else if (packetwin == NULL) { + packetwin = newwin(leftover, COLS, (*active)->min_y + 1, 0); + (void)scrollok(packetwin, true); + (void)wsetscrreg(packetwin, 0, leftover - 1); + } else { + (void)wresize(packetwin, leftover, COLS); + (void)mvwin(packetwin, (*active)->min_y + 1, 0); + (void)wsetscrreg(packetwin, 0, leftover - 1); + } + /*@ +onlytrans @*/ + } + return true; + } + + monitor_complain("No matching monitor type."); + return false; +} + +static jmp_buf assertbuf; + +static void onsig(int sig UNUSED) +{ + longjmp(assertbuf, 1); +} + +int main(int argc, char **argv) +{ +#if defined(ALLOW_CONTROLSEND) || defined(ALLOW_RECONFIGURE) + unsigned int v; +#endif /* defined(ALLOW_CONTROLSEND) || defined(ALLOW_RECONFIGURE) */ + int option, status, last_type = BAD_PACKET; + ssize_t len; + struct fixsource_t source; + char *p, *controlsock = "/var/run/gpsd.sock"; + fd_set select_set; + unsigned char buf[BUFLEN]; + char line[80], *explanation; + int bailout = 0; + + gmt_offset = (int)tzoffset(); + /*@ -observertrans @*/ + (void)putenv("TZ=GMT"); // for ctime() + /*@ +observertrans @*/ + /*@ -branchstate @*/ + while ((option = getopt(argc, argv, "D:F:LVhl:")) != -1) { + switch (option) { + case 'D': + debuglevel = atoi(optarg); + break; + case 'F': + controlsock = optarg; + break; + case 'V': + (void)printf("gpsmon: %s (revision %s)\n", VERSION, REVISION); + exit(0); + case 'L': /* list known device types */ + (void) + fputs + ("General commands available per type. '+' means there are private commands.\n", + stdout); + for (active = monitor_objects; *active; active++) { + (void)fputs("i l q ^S ^Q", stdout); + (void)fputc(' ', stdout); +#ifdef ALLOW_RECONFIGURE + if ((*active)->driver->mode_switcher != NULL) + (void)fputc('n', stdout); + else + (void)fputc(' ', stdout); + (void)fputc(' ', stdout); + if ((*active)->driver->speed_switcher != NULL) + (void)fputc('s', stdout); + else + (void)fputc(' ', stdout); + (void)fputc(' ', stdout); + if ((*active)->driver->rate_switcher != NULL) + (void)fputc('x', stdout); + else + (void)fputc(' ', stdout); + (void)fputc(' ', stdout); +#endif /* ALLOW_RECONFIGURE */ +#ifdef ALLOW_CONTROLSEND + if ((*active)->driver->control_send != NULL) + (void)fputc('x', stdout); + else + (void)fputc(' ', stdout); +#endif /* ALLOW_CONTROLSEND */ + (void)fputc(' ', stdout); + if ((*active)->command != NULL) + (void)fputc('+', stdout); + else + (void)fputc(' ', stdout); + (void)fputs("\t", stdout); + (void)fputs((*active)->driver->type_name, stdout); + (void)fputc('\n', stdout); + } + exit(0); + case 'l': /* enable logging at startup */ + logfile = fopen(optarg, "w"); + if (logfile == NULL) { + (void)fprintf(stderr, "Couldn't open logfile for writing.\n"); + exit(1); + } + break; + case 'h': + case '?': + default: + (void) + fputs + ("usage: gpsmon [-?hVl] [-D debuglevel] [-F controlsock] [server[:port:[device]]]\n", + stderr); + exit(1); + } + } + /*@ +branchstate @*/ + + if (optind < argc) { + gpsd_source_spec(argv[optind], &source); + } else + gpsd_source_spec(NULL, &source); + + gpsd_init(&session, &context, NULL); + + /*@ -boolops */ + if ((optind >= argc || source.device == NULL + || strchr(argv[optind], ':') != NULL) +#ifdef HAVE_BLUEZ + && bachk(argv[optind])) { +#else + ) { +#endif + (void)gps_open_r(source.server, source.port, &session.gpsdata); + if (session.gpsdata.gps_fd < 0) { + (void)fprintf(stderr, + "%s: connection failure on %s:%s, error %d = %s.\n", + argv[0], source.server, source.port, + session.gpsdata.gps_fd, + netlib_errstr(session.gpsdata.gps_fd)); + exit(1); + } + controlfd = open(controlsock, O_RDWR); + if (source.device != NULL) + (void)gps_send(&session.gpsdata, + "?WATCH={\"raw\":2,\"device\":\"%s\"}\r\n", + source.device); + else + (void)gps_send(&session.gpsdata, "?WATCH={\"raw\":2}\r\n"); + serial = false; + } else { + (void)strlcpy(session.gpsdata.dev.path, argv[optind], + sizeof(session.gpsdata.dev.path)); + if (gpsd_activate(&session) == -1) { + gpsd_report(LOG_ERROR, + "activation of device %s failed, errno=%d\n", + session.gpsdata.dev.path, errno); + exit(2); + } + + controlfd = session.gpsdata.gps_fd; + serial = true; + } + /*@ +boolops */ + /*@ +nullpass +branchstate @*/ + + /* + * This is a monitoring utility. Disable autoprobing, because + * in some cases (e.g. SiRFs) there is no way to probe a chip + * type without flipping it to native mode. + */ + context.readonly = true; + + /* quit cleanly if an assertion fails */ + (void)signal(SIGABRT, onsig); + if (setjmp(assertbuf) > 0) { + if (logfile) + (void)fclose(logfile); + (void)endwin(); + (void)fputs("gpsmon: assertion failure, probable I/O error\n", + stderr); + exit(1); + } + + (void)initscr(); + (void)cbreak(); + (void)noecho(); + (void)intrflush(stdscr, FALSE); + (void)keypad(stdscr, true); + curses_active = true; + +#define CMDWINHEIGHT 1 + + /*@ -onlytrans @*/ + statwin = newwin(CMDWINHEIGHT, 30, 0, 0); + cmdwin = newwin(CMDWINHEIGHT, 0, 0, 30); + packetwin = newwin(0, 0, CMDWINHEIGHT, 0); + if (statwin == NULL || cmdwin == NULL || packetwin == NULL) + goto quit; + (void)scrollok(packetwin, true); + (void)wsetscrreg(packetwin, 0, LINES - CMDWINHEIGHT); + /*@ +onlytrans @*/ + + (void)wmove(packetwin, 0, 0); + + FD_ZERO(&select_set); + + + if ((bailout = setjmp(terminate)) == 0) { + /*@ -observertrans @*/ + for (;;) { + /* *INDENT-OFF* */ + type_name = + session.device_type ? session.device_type->type_name : "Unknown device"; + /* *INDENT-ON* */ + (void)wattrset(statwin, A_BOLD); + if (serial) + display(statwin, 0, 0, "%s %4d %c %d", + session.gpsdata.dev.path, + gpsd_get_speed(&session.ttyset), + session.gpsdata.dev.parity, + session.gpsdata.dev.stopbits); + else + /*@ -nullpass @*/ + display(statwin, 0, 0, "%s:%s:%s", + source.server, source.port, session.gpsdata.dev.path); + /*@ +nullpass @*/ + (void)wattrset(statwin, A_NORMAL); + (void)wmove(cmdwin, 0, 0); + + /* get a packet -- calls gpsd_poll() */ + if ((len = readpkt()) > 0 && session.packet.outbuflen > 0) { + /* switch types on packet receipt */ + /*@ -nullpass */ + if (session.packet.type != last_type) { + last_type = session.packet.type; + if (!switch_type(session.device_type)) + longjmp(terminate, TERM_DRIVER_SWITCH); + } + /*@ +nullpass */ + + /* refresh all windows */ + (void)wprintw(cmdwin, type_name); + (void)wprintw(cmdwin, "> "); + (void)wclrtoeol(cmdwin); + if (active != NULL && len > 0 && session.packet.outbuflen > 0) + (*active)->update(); + (void)wprintw(packetwin, "(%d) ", session.packet.outbuflen); + packet_dump((char *)session.packet.outbuffer, + session.packet.outbuflen); + (void)wnoutrefresh(statwin); + (void)wnoutrefresh(cmdwin); + if (devicewin != NULL) + (void)wnoutrefresh(devicewin); + if (packetwin != NULL) + (void)wnoutrefresh(packetwin); + (void)doupdate(); + } + + /* rest of this invoked only if user has pressed a key */ + FD_SET(0, &select_set); + FD_SET(session.gpsdata.gps_fd, &select_set); + + if (select(FD_SETSIZE, &select_set, NULL, NULL, NULL) == -1) + break; + + if (FD_ISSET(0, &select_set)) { + char *arg; + (void)wmove(cmdwin, 0, (int)strlen(type_name) + 2); + (void)wrefresh(cmdwin); + (void)echo(); + /*@ -usedef -compdef @*/ + (void)wgetnstr(cmdwin, line, 80); + (void)noecho(); + if (packetwin != NULL) + (void)wrefresh(packetwin); + (void)wrefresh(cmdwin); + + if ((p = strchr(line, '\r')) != NULL) + *p = '\0'; + + if (line[0] == '\0') + continue; + /*@ +usedef +compdef @*/ + + arg = line; + if (isspace(line[1])) { + for (arg = line + 2; *arg != '\0' && isspace(*arg); arg++) + arg++; + arg++; + } else + arg = line + 1; + + if (active != NULL && (*active)->command != NULL) { + status = (*active)->command(line); + if (status == COMMAND_TERMINATE) + goto quit; + else if (status == COMMAND_MATCH) + continue; + assert(status == COMMAND_UNKNOWN); + } + switch (line[0]) { +#ifdef ALLOW_RECONFIGURE + case 'c': /* change cycle time */ + if (active == NULL) + monitor_complain("No device defined yet"); + else if (serial) { + double rate = strtod(arg, NULL); + /* Ugh...should have a controlfd slot + * in the session structure, really + */ + if ((*active)->driver->rate_switcher) { + int dfd = session.gpsdata.gps_fd; + session.gpsdata.gps_fd = controlfd; + /* *INDENT-OFF* */ + if ((*active)->driver->rate_switcher(&session, rate)) { + monitor_dump_send(); + } else + monitor_complain("Rate not supported."); + /* *INDENT-ON* */ + session.gpsdata.gps_fd = dfd; + } else + monitor_complain + ("Device type has no rate switcher"); + } else { + line[0] = 'c'; + /*@ -sefparams @*/ + assert(write + (session.gpsdata.gps_fd, line, + strlen(line)) != -1); + /* discard response */ + assert(read(session.gpsdata.gps_fd, buf, sizeof(buf)) + != -1); + /*@ +sefparams @*/ + } + break; +#endif /* ALLOW_RECONFIGURE */ + + case 'i': /* start probing for subtype */ + if (active == NULL) + monitor_complain("No GPS type detected."); + else { + if (strcspn(line, "01") == strlen(line)) + context.readonly = !context.readonly; + else + context.readonly = (atoi(line + 1) == 0); + /* *INDENT-OFF* */ + (void)gpsd_switch_driver(&session, + (*active)->driver->type_name); + /* *INDENT-ON* */ + } + break; + + case 'l': /* open logfile */ + if (logfile != NULL) { + if (packetwin != NULL) + (void)wprintw(packetwin, + ">>> Logging to %s off", logfile); + (void)fclose(logfile); + } + + if ((logfile = fopen(line + 1, "a")) != NULL) + if (packetwin != NULL) + (void)wprintw(packetwin, + ">>> Logging to %s on", logfile); + break; + +#ifdef ALLOW_RECONFIGURE + case 'n': /* change mode */ + /* if argument not specified, toggle */ + if (strcspn(line, "01") == strlen(line)) { + /* *INDENT-OFF* */ + v = (unsigned int)TEXTUAL_PACKET_TYPE( + session.packet.type); + /* *INDENT-ON* */ + } else + v = (unsigned)atoi(line + 1); + if (active == NULL) + monitor_complain("No device defined yet"); + else if (serial) { + /* Ugh...should have a controlfd slot + * in the session structure, really + */ + if ((*active)->driver->mode_switcher) { + int dfd = session.gpsdata.gps_fd; + session.gpsdata.gps_fd = controlfd; + (*active)->driver->mode_switcher(&session, + (int)v); + monitor_dump_send(); + (void)tcdrain(session.gpsdata.gps_fd); + (void)usleep(50000); + session.gpsdata.gps_fd = dfd; + } else + monitor_complain + ("Device type has no mode switcher"); + } else { + line[0] = 'n'; + line[1] = ' '; + line[2] = '0' + v; + /*@ -sefparams @*/ + assert(write + (session.gpsdata.gps_fd, line, + strlen(line)) != -1); + /* discard response */ + assert(read(session.gpsdata.gps_fd, buf, sizeof(buf)) + != -1); + /*@ +sefparams @*/ + } + break; +#endif /* ALLOW_RECONFIGURE */ + + case 'q': /* quit */ + goto quit; + +#ifdef ALLOW_RECONFIGURE + case 's': /* change speed */ + if (active == NULL) + monitor_complain("No device defined yet"); + else if (serial) { + speed_t speed; + char parity = session.gpsdata.dev.parity; + unsigned int stopbits = + (unsigned int)session.gpsdata.dev.stopbits; + char *modespec; + + modespec = strchr(arg, ':'); + /*@ +charint @*/ + if (modespec != NULL) { + if (strchr("78", *++modespec) == NULL) { + monitor_complain + ("No support for that word length."); + break; + } + parity = *++modespec; + if (strchr("NOE", parity) == NULL) { + monitor_complain("What parity is '%c'?.", + parity); + break; + } + stopbits = (unsigned int)*++modespec; + if (strchr("12", (char)stopbits) == NULL) { + monitor_complain("Stop bits must be 1 or 2."); + break; + } + stopbits = (unsigned int)(stopbits - '0'); + } + /*@ -charint @*/ + speed = (unsigned)atoi(arg); + /* Ugh...should have a controlfd slot + * in the session structure, really + */ + /* *INDENT-OFF* */ + if ((*active)->driver->speed_switcher) { + int dfd = session.gpsdata.gps_fd; + session.gpsdata.gps_fd = controlfd; + if ((*active)-> + driver->speed_switcher(&session, speed, + parity, (int) + stopbits)) { + monitor_dump_send(); + /* + * See the comment attached to the 'B' + * command in gpsd. Allow the control + * string time to register at the GPS + * before we do the baud rate switch, + * which effectively trashes the UART's + * buffer. + */ + (void)tcdrain(session.gpsdata.gps_fd); + (void)usleep(50000); + (void)gpsd_set_speed(&session, speed, + parity, stopbits); + } else + monitor_complain + ("Speed/mode combination not supported."); + session.gpsdata.gps_fd = dfd; + } else + monitor_complain + ("Device type has no speed switcher"); + /* *INDENT-ON* */ + } else { + line[0] = 'b'; + /*@ -sefparams @*/ + assert(write + (session.gpsdata.gps_fd, line, + strlen(line)) != -1); + /* discard response */ + assert(read(session.gpsdata.gps_fd, buf, sizeof(buf)) + != -1); + /*@ +sefparams @*/ + } + break; +#endif /* ALLOW_RECONFIGURE */ + + case 't': /* force device type */ + if (strlen(arg) > 0) { + int matchcount = 0; + const struct gps_type_t **dp, *forcetype = NULL; + for (dp = gpsd_drivers; *dp; dp++) { + if (strstr((*dp)->type_name, arg) != NULL) { + forcetype = *dp; + matchcount++; + } + } + if (matchcount == 0) { + monitor_complain + ("No driver type matches '%s'.", arg); + } else if (matchcount == 1) { + assert(forcetype != NULL); + /* *INDENT-OFF* */ + if (switch_type(forcetype)) + (void)gpsd_switch_driver(&session, + forcetype->type_name); + /* *INDENT-ON* */ + } else { + monitor_complain + ("Multiple driver type names match '%s'.", + arg); + } + } + break; + +#ifdef ALLOW_CONTROLSEND + case 'x': /* send control packet */ + if (active == NULL) + monitor_complain("No device defined yet"); + else { + /*@ -compdef @*/ + int st = gpsd_hexpack(arg, (char *)buf, strlen(arg)); + if (st < 0) + monitor_complain + ("Invalid hex string (error %d)", st); + else if ((*active)->driver->control_send == NULL) + monitor_complain + ("Device type has no control-send method."); + else if (!monitor_control_send(buf, (size_t) st)) + monitor_complain("Control send failed."); + } + /*@ +compdef @*/ + break; + + case 'X': /* send raw packet */ + /*@ -compdef @*/ + len = + (ssize_t) gpsd_hexpack(arg, (char *)buf, strlen(arg)); + if (len < 0) + monitor_complain("Invalid hex string (error %d)", + len); + else if (!monitor_raw_send(buf, (size_t) len)) + monitor_complain("Raw send failed."); + /*@ +compdef @*/ + break; +#endif /* ALLOW_CONTROLSEND */ + + default: + monitor_complain("Unknown command"); + break; + } + } + } + /*@ +nullpass @*/ + /*@ +observertrans @*/ + } + + quit: + /* we'll fall through to here on longjmp() */ + gpsd_close(&session); + if (logfile) + (void)fclose(logfile); + (void)endwin(); + + explanation = NULL; + switch (bailout) { + case TERM_SELECT_FAILED: + explanation = "select(2) failed\n"; + break; + case TERM_DRIVER_SWITCH: + explanation = "Driver type switch failed\n"; + break; + case TERM_EMPTY_READ: + explanation = "Device went offline\n"; + break; + case TERM_READ_ERROR: + explanation = "Read error from device\n"; + break; + } + + if (explanation != NULL) + (void)fputs(explanation, stderr); + exit(0); +} + +/* gpsmon.c ends here */ diff --git a/gpsmon.h b/gpsmon.h new file mode 100644 index 0000000..32cf3e7 --- /dev/null +++ b/gpsmon.h @@ -0,0 +1,38 @@ +/* gpsmon.h -- what monitor capabuilities look like + * + * By Eric S. Raymond, 2009 + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#ifndef _GPSD_GPSMON_H_ +#define _GPSD_GPSMON_H_ + +#define COMMAND_TERMINATE -1 +#define COMMAND_MATCH 1 +#define COMMAND_UNKNOWN 0 + +struct monitor_object_t { + /* a device-specific capability table for the monitor */ + bool (*initialize)(void); /* paint legends on windows */ + void (*update)(void); /* now paint the data */ + int (*command)(char[]); /* interpret device-specfic commands */ + void (*wrap)(void); /* deallocate storage */ + int min_y, min_x; /* space required for device info */ + const struct gps_type_t *driver; /* device driver table */ +}; + +// Device-specific may need these. +extern bool monitor_control_send(unsigned char *buf, size_t len); +extern void monitor_fixframe(WINDOW *win); +extern void monitor_log(const char *fmt, ...); +extern void monitor_complain(const char *fmt, ...); + +#define BUFLEN 2048 + +extern WINDOW *devicewin; +extern struct gps_device_t session; +extern int gmt_offset; + +#endif /* _GPSD_GPSMON_H_ */ +/* gpsmon.h ends here */ diff --git a/gpsmon.xml b/gpsmon.xml new file mode 100644 index 0000000..04c4b23 --- /dev/null +++ b/gpsmon.xml @@ -0,0 +1,369 @@ + + + + +17 Feb 2009 + +gpsmon +1 +The GPSD Project +GPSD Documentation + + +gpsmon +real-time GPS packet monitor and control utility + + + + + gpsmon + -h + -L + -V + -l logfile + -F control-socket + + + + server + + :port + :device + + + device + + + -D debuglevel + + + +DESCRIPTION + +gpsmon is a monitor that watches +packets coming from a GPS and displays them along with diagnostic +information. It supports commands that can be used to tweak GPS +settings in various ways; some are device-independent, some vary +with the GPS chipset type. + +This tool used to be called 'sirfmon', and worked only on SiRF +devices (and the command set has changed to resemble the command +switches of gpsctl). It now has support for a range +of NMEA devices as well; support for other (binary-protocol) device +types is planned. It will behave sanely, just dumping packets, when +connected to a GPS type it knows nothing about. + +gpsmon differs from a navigation +client in that it mostly dumps raw data from the GPS, with only enough +data-massaging to allow checks against expected output. In +particular, this tool does not do any interpolation or modeling +to derive climb/sink or error estimates. Nor does it discard +altitude reports when the fix quality is too low. + +gpsmon is a designed to run in a +terminal emulator with a minimum 25x80 size; the non-GUI interface is +a design choice made to accommodate users operating in constrained +environments and over telnet or ssh connections. If run in a larger +window, the size of the packet-log window will be increased to +fit. + +gpsmon accepts an -h option that +displays a usage message, or a -V option to dump the package +version and exit. + +This program may be run in either of two modes, as a client for +the gpsd daemon (and its associated control +socket) or directly connected to a specified serial device. When run +with no argument, it attempts to connect to the daemon. If the +argument looks like a server:port specification it will also attempt +to connect to the daemon. If the argument looks like a bare server +name it will attempt to connect to a daemon running on the default +gpsd port on that server. Only if the device argument contains +slashes but no colons will it be treated as a serial device for direct +connection. In direct-connect mode gpsmon +will hunt for a correct baud rate and lock on to it +automatically. + +The -F option is only valid in client mode; it specifies a +control socket to which the program should send device control +strings. You must specify a valid pathname of a Unix-domain socket on +your local filesystem. + +The -D option enables packet-getter debugging output and is +probably only useful to developers of the GPSD code. Consult the +packet-getter source code for relevant values. + +The -L option lists a table showing which GPS device types +gpsmon has built-in support for, and which +generic commands can be applied to which GPS types, and then +exits. Note that this does not list type-specific commands associated +with individual GPS types. + +The -l option sets up logging to a specified file to start +immediately on device open. This may be useful is, for example, +you want to capture the startup message from a device that displays +firmware version information there. + +After startup, the top part of the screen reports the contents +of several especially interesting packet types. The bottom half of +the screen is a scrolling hex dump of all packets the GPS is issuing. +Dump lines beginning >>> represent control packets sent to the +GPS. + + +COMMANDS + +The following device-independent comands are available while +gpsmon is running: + + + + +i + +Enable/disable subtype probing and reinitialize the driver. In +normal operation, gpsmon does not send +configuration strings to the device (except for wakeup strings needed +to get it to send data, if any). The command 'i1' causes it to send +the same sequence of subtype probes that +gpsd would. The command 'i0' turns off +probing; 'i' alone toggles the bit. In either case, the current driver +is re-selected; if the probe bit is enabled, probes will begin to be +issued immediately. + +Note that enabling probing might flip the device into another +mode; in particular, it will flip a SiRF chip into binary mode as if +you had used the n command. This is due to a +limitation in the SiRF firmware that we can't fix. + + + + +c + +Change cycle time. Follow it with a number interpreted as a +cycle time in seconds. Most devices have a fixed cycle time of 1 +second, so this command may fail with a message. + + + + +l + +Toggle packet logging. If packet logging is on, it will be +turned off and the log closed. If it is off, logging to the filename +following the l will be enabled. Differs from simply capturing the +data from the GPS device in that only whole packets are logged. +The logfile is opened for append, so you can log more than one +portion of the packet stream and they will be stitched together +correctly. + + + + +n + +With an argument of 0, switch device to NMEA mode at current +speed; with an argument of 1, change to binary (native) mode. With no +argument, toggle the setting. Will show an error if the device doesn't +have such modes. + + + + +q + +Quit gpsmon. Control-C, or whatever +your current interrupt chracter is, works as well. + + + + +s + +Change baud rate. Follow it with a number interpreted as bits +per second, for example "s9600". The speed number may optionally be +followed by a colon and a wordlength-parity-stopbits specification in +the traditional style, e.g 8N1 (the default), 7E1, etc. Some +devices don't support serial modes other than their default, so +this command may fail with a message. + +Use this command with caution. On USB and Bluetooth GPSes it is +also possible for serial mode setting to fail either because the +serial adaptor chip does not support non-8N1 modes or because the +device firmware does not properly synchronize the serrial adaptor chip +with the UART on the GPS chipset whjen the speed changes. These +failures can hang your device, possibly requiring a GPS power cycle or (in +extreme cases) physically disconnecting the NVRAM backup battery. + + + + +t + +Force a switch of monitoring type. Follow it with a string that +is unique to the name of a gpsd driver with +gpsmon support; +gpsmon will switch to using that driver and +display code. Will show an error message if there is no matching gpsd +driver, or multiple matches, or the unique match has no display +support in gpsmon. + + + + +x + +Send hex payload to device. Following the command letter you may +type hex digit pairs; end with a newline. These will become the +payload of a control packet shipped to the device. The packet will be +wrapped with headers, trailers, and checksum appropriate for the +current driver type. The first one or two bytes of the payload may be +specially interpreted, see the description of the +of +gpsctl1. + + + + +X + +Send raw hex bytes to device. Following the command letter you +may type hex digit pairs; end with a newline. These will be shipped +to the device. + + + + +Ctrl-S + +Freeze display, suspend scrolling in debug window. + + + +Ctrl-Q + +Unfreeze display, resume normal operation. + + + + +NMEA support + +(These remarks apply to not just generic NMEA devices +but all extended NMEA devices for which +gpsmon presently has support.) + +All fields are raw data from the GPS except the "Cooked PVT" +window near top of screen, provided as a sheck. + +There are no device-specific commands. Which generic +commands are available may vary by type: examine the output +of gpsmon -l to learn more. + + +SiRF support +Most information is raw from the GPS. Underlined fields are +derived by translation from ECEF coordinates or application of +leap-second and local time-zone offsets. + +The following commands are supported for SiRF GPSes only: + + + +A + +Toggle reporting of 50BPS subframe data. + + + +M + +Set (M1) or clear (M0) static navigation. The SiRF documentation +says Static navigation is a position filter designed to be used +with motor vehicles. When the vehicle's velocity falls below a +threshold, the position and heading are frozen, and velocity is set to +zero. This condition will continue until the computed velocity rises +above 1.2 times the threshold or until the computed position is at +least a set distance from the frozen place. The threshold velocity and +set distance may vary with software versions. + +Non-static mode is designed for use with road navigation +software, which often snaps the reported position to the nearest road +within some uncertainty radius. You probably want to turn static +navigation off for pedestrian use, as it is likely to report speed +zero and position changing in large jumps. + + + +P + +Toggle navigation-parameter display mode. Toggles between +normal display and one that shows selected navigation parameters from +MID 19, including the Static Navigation bit toggled by the 'M' command. + + + + +To interpret what you see, you will need a copy of the +SiRF Binary Protocol Reference Manual. + + + +FILES + + + +/var/run/gpsd.sock + +The default location of the control socket. + + + + + +BUGS AND LIMITATIONS + +If you run gpsmon in client mode, +and kill the daemon while gpsmon is +still running, gpsmon will hang. +Don't do that... + + + + +SEE ALSO + +gpsd8, +gps1, +libgps3, +libgpsd3, +gpsprof1, +gpsfake1, +gpsctl1, +gpscat1. +gpspipe1. + + + +AUTHOR + +Eric S. Raymond esr@thyrsus.com. This code is +part of the gpsd toolset; there is a project page for +gpsd here. + + + + diff --git a/gpspacket.c b/gpspacket.c new file mode 100644 index 0000000..45c56d9 --- /dev/null +++ b/gpspacket.c @@ -0,0 +1,270 @@ +/* + * Python binding for the packet.c module. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + */ +#include + +#include +#include "gpsd.h" + +static PyObject *ErrorObject = NULL; + +static PyObject *report_callback = NULL; + +void gpsd_report(int errlevel, const char *fmt, ... ) +{ + char buf[BUFSIZ]; + PyObject *args; + va_list ap; + + gpsd_hexdump_level = errlevel; + + if (!report_callback) /* no callback defined, exit early */ + return; + + if (!PyCallable_Check(report_callback)) { + PyErr_SetString(ErrorObject, "Cannot call Python callback function"); + return; + } + + va_start(ap, fmt); + (void)vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + args = Py_BuildValue("(is)", errlevel, buf); + if (!args) + return; + + PyObject_Call(report_callback, args, NULL); + Py_DECREF(args); +} + +static PyTypeObject Lexer_Type; + +typedef struct { + PyObject_HEAD + struct gps_packet_t lexer; +} LexerObject; + +static LexerObject * +newLexerObject(PyObject *arg) +{ + LexerObject *self; + self = PyObject_New(LexerObject, &Lexer_Type); + if (self == NULL) + return NULL; + memset(&self->lexer, 0, sizeof(struct gps_packet_t)); + packet_reset(&self->lexer); + return self; +} + +/* Lexer methods */ + +static int +Lexer_init(LexerObject *self) +{ + packet_reset(&self->lexer); + return 0; +} + +static PyObject * +Lexer_get(LexerObject *self, PyObject *args) +{ + ssize_t len; + int fd; + + if (!PyArg_ParseTuple(args, "i;missing or invalid file descriptor argument to gps.packet.get", &fd)) + return NULL; + + len = packet_get(fd, &self->lexer); + if (PyErr_Occurred()) + return NULL; + + return Py_BuildValue("(i, i, s#)", + len, + self->lexer.type, + self->lexer.outbuffer, + self->lexer.outbuflen); +} + +static PyObject * +Lexer_reset(LexerObject *self) +{ + packet_reset(&self->lexer); + if (PyErr_Occurred()) + return NULL; + return 0; +} + +static void +Lexer_dealloc(LexerObject *self) +{ + PyObject_Del(self); +} + +static PyMethodDef Lexer_methods[] = { + {"get", (PyCFunction)Lexer_get, METH_VARARGS, + PyDoc_STR("Get a packet from a file descriptor.")}, + {"reset", (PyCFunction)Lexer_reset, METH_NOARGS, + PyDoc_STR("Reset the packet lexer to ground state.")}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +Lexer_getattr(LexerObject *self, char *name) +{ + return Py_FindMethod(Lexer_methods, (PyObject *)self, name); +} + +PyDoc_STRVAR(Lexer__doc__, +"GPS packet lexer object\n\ +\n\ +Fetch a single packet from file descriptor"); + +static PyTypeObject Lexer_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "gps.packet.lexer", /*tp_name*/ + sizeof(LexerObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)Lexer_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)Lexer_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + Lexer__doc__, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + Lexer_methods, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + (initproc)Lexer_init, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +/* Function of no arguments returning new Lexer object */ + +static PyObject * +gpspacket_new(PyObject *self, PyObject *args) +{ + LexerObject *rv; + + if (!PyArg_ParseTuple(args, ":new")) + return NULL; + rv = newLexerObject(args); + if (rv == NULL) + return NULL; + return (PyObject *)rv; +} + +PyDoc_STRVAR(register_report__doc__, +"register_report(callback)\n\ +\n\ +callback must be a callable object expecting a string as parameter."); + +static PyObject * +register_report(LexerObject *self, PyObject *args) +{ + PyObject *callback = NULL; + + if (!PyArg_ParseTuple(args, "O:register_report", &callback)) + return NULL; + + if (!PyCallable_Check(callback)) { + PyErr_SetString(PyExc_TypeError, "First argument must be callable"); + return NULL; + } + + if (report_callback) { + Py_DECREF(report_callback); + report_callback = NULL; + } + + report_callback = callback; + Py_INCREF(report_callback); + + Py_INCREF(Py_None); + return Py_None; +} + + +/* List of functions defined in the module */ + +static PyMethodDef packet_methods[] = { + {"new", gpspacket_new, METH_VARARGS, + PyDoc_STR("new() -> new packet-lexer object")}, + {"register_report", (PyCFunction)register_report, METH_VARARGS, + register_report__doc__}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(module_doc, +"Python binding of the libgpsd module for recognizing GPS packets.\n\ +The new() function returns a new packet-lexer instance. Lexer instances\n\ +have two methods:\n\ + get() takes a file descriptor argument and returns a tuple consisting of\n\ +the integer packet type and string packet value. On end of file it returns\n\ +(-1, '').\n\ + reset() resets the packet-lexer to its initial state.\n\ + The module also has a register_report() function that accepts a callback\n\ +for debug message reporting. The callback will get two arguments, the error\n\ +level of the message and the message itself.\n\ +"); + +PyMODINIT_FUNC +initpacket(void) +{ + PyObject *m; + + if (PyType_Ready(&Lexer_Type) < 0) + return; + + /* Create the module and add the functions */ + m = Py_InitModule3("packet", packet_methods, module_doc); + + PyModule_AddIntConstant(m, "BAD_PACKET", BAD_PACKET); + PyModule_AddIntConstant(m, "COMMENT_PACKET", COMMENT_PACKET); + PyModule_AddIntConstant(m, "NMEA_PACKET", NMEA_PACKET); + PyModule_AddIntConstant(m, "SIRF_PACKET", SIRF_PACKET); + PyModule_AddIntConstant(m, "ZODIAC_PACKET", ZODIAC_PACKET); + PyModule_AddIntConstant(m, "TSIP_PACKET", TSIP_PACKET); + PyModule_AddIntConstant(m, "EVERMORE_PACKET", EVERMORE_PACKET); + PyModule_AddIntConstant(m, "ITALK_PACKET", ITALK_PACKET); + PyModule_AddIntConstant(m, "GARMIN_PACKET", GARMIN_PACKET); + PyModule_AddIntConstant(m, "NAVCOM_PACKET", NAVCOM_PACKET); + PyModule_AddIntConstant(m, "RTCM2_PACKET", RTCM2_PACKET); + PyModule_AddIntConstant(m, "RTCM3_PACKET", RTCM3_PACKET); + PyModule_AddIntConstant(m, "UBX_PACKET", UBX_PACKET); + PyModule_AddIntConstant(m, "GARMINTXT_PACKET", GARMINTXT_PACKET); + + PyModule_AddIntConstant(m, "LOG_IO", LOG_IO); +} diff --git a/gpspipe.c b/gpspipe.c new file mode 100644 index 0000000..ade902c --- /dev/null +++ b/gpspipe.c @@ -0,0 +1,408 @@ +/* + * gpspipe + * + * a simple program to connect to a gpsd daemon and dump the received data + * to stdout + * + * This will dump the raw NMEA from gpsd to stdout + * gpspipe -r + * + * This will dump the super-raw data (gps binary) from gpsd to stdout + * gpspipe -R + * + * This will dump the GPSD sentences from gpsd to stdout + * gpspipe -w + * + * This will dump the GPSD and the NMEA sentences from gpsd to stdout + * gpspipe -wr + * + * Original code by: Gary E. Miller . Cleanup by ESR. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + */ + +#include +#include +#include "gpsd_config.h" +#include +#include +#ifndef S_SPLINT_S +#if HAVE_SYS_SOCKET_H +#include +#endif /* HAVE_SYS_SOCKET_H */ +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include +#if HAVE_TERMIOS +#include +#endif /* HAVE_TERMIOS */ +#include +#include "gpsd.h" +#include "gpsdclient.h" +#include "revision.h" + +static struct gps_data_t gpsdata; +static void spinner(unsigned int, unsigned int); + +/* NMEA-0183 standard baud rate */ +#define BAUDRATE B4800 + +/* Serial port variables */ +static struct termios oldtio, newtio; +static int fd_out = 1; /* output initially goes to standard output */ +static char serbuf[255]; +static int debug; + +static void daemonize(void) +/* Daemonize me. */ +{ + int i; + pid_t pid; + + /* Run as my child. */ + pid = fork(); + if (pid == -1) + exit(1); /* fork error */ + if (pid > 0) + exit(0); /* parent exits */ + + /* Obtain a new process group. */ + (void)setsid(); + + /* Close all open descriptors. */ + for (i = getdtablesize(); i >= 0; --i) + (void)close(i); + + /* Reopen STDIN, STDOUT, STDERR to /dev/null. */ + i = open("/dev/null", O_RDWR); /* STDIN */ + /*@ -sefparams @*/ + assert(dup(i) != -1); /* STDOUT */ + assert(dup(i) != -1); /* STDERR */ + + /* Know thy mask. */ + (void)umask(0x033); + + /* Run from a known spot. */ + assert(chdir("/") != -1); + /*@ +sefparams @*/ + + /* Catch child sig */ + (void)signal(SIGCHLD, SIG_IGN); + + /* Ignore tty signals */ + (void)signal(SIGTSTP, SIG_IGN); + (void)signal(SIGTTOU, SIG_IGN); + (void)signal(SIGTTIN, SIG_IGN); +} + +static void open_serial(char *device) +/* open the serial port and set it up */ +{ + /* + * Open modem device for reading and writing and not as controlling + * tty. + */ + if ((fd_out = open(device, O_RDWR | O_NOCTTY)) == -1) { + fprintf(stderr, "gpspipe: error opening serial port\n"); + exit(1); + } + + /* Save current serial port settings for later */ + if (tcgetattr(fd_out, &oldtio) != 0) { + fprintf(stderr, "gpspipe: error reading serial port settings\n"); + exit(1); + } + + /* Clear struct for new port settings. */ + /*@i@*/ bzero(&newtio, sizeof(newtio)); + + /* make it raw */ + (void)cfmakeraw(&newtio); + /* set speed */ + /*@i@*/ (void)cfsetospeed(&newtio, BAUDRATE); + + /* Clear the modem line and activate the settings for the port. */ + (void)tcflush(fd_out, TCIFLUSH); + if (tcsetattr(fd_out, TCSANOW, &newtio) != 0) { + (void)fprintf(stderr, "gpspipe: error configuring serial port\n"); + exit(1); + } +} + +static void usage(void) +{ + (void)fprintf(stderr, + "Usage: gpspipe [OPTIONS] [server[:port[:device]]]\n\n" + "-d Run as a daemon.\n" "-f [file] Write output to file.\n" + "-h Show this help.\n" "-r Dump raw NMEA.\n" + "-R Dump super-raw mode (GPS binary).\n" + "-w Dump gpsd native data.\n" + "-l Sleep for ten seconds before connecting to gpsd.\n" + "-t Time stamp the data.\n" + "-T [format] set the timestamp format (strftime(3)-like; implies '-t')\n" + "-s [serial dev] emulate a 4800bps NMEA GPS on serial port (use with '-r').\n" + "-n [count] exit after count packets.\n" + "-v Print a little spinner.\n" + "-V Print version and exit.\n\n" + "You must specify one, or both, of -r/-w.\n" + "You must use -f if you use -d.\n"); +} + +/*@ -compdestroy @*/ +int main(int argc, char **argv) +{ + char buf[4096]; + bool timestamp = false; + char *format = "%c"; + char tmstr[200]; + bool daemon = false; + bool binary = false; + bool sleepy = false; + bool new_line = true; + bool raw = false; + bool watch = false; + long count = -1; + int option; + unsigned int vflag = 0, l = 0; + FILE *fp; + unsigned int flags; + + struct fixsource_t source; + char *serialport = NULL; + char *outfile = NULL; + + /*@-branchstate@*/ + flags = WATCH_ENABLE; + while ((option = getopt(argc, argv, "?dD:lhrRwtT:vVn:s:o:")) != -1) { + switch (option) { + case 'D': + debug = atoi(optarg); +#ifdef CLIENTDEBUG_ENABLE + gps_enable_debug(debug, stderr); +#endif /* CLIENTDEBUG_ENABLE */ + break; + case 'n': + count = strtol(optarg, 0, 0); + break; + case 'r': + raw = true; + /* + * Yes, -r invokes NMEA mode rather than proper raw mode. + * This emulates the behavior under the old protocol. + */ + flags |= WATCH_NMEA; + break; + case 'R': + flags |= WATCH_RAW; + binary = true; + break; + case 'd': + daemon = true; + break; + case 'l': + sleepy = true; + break; + case 't': + timestamp = true; + break; + case 'T': + timestamp = true; + format = optarg; + break; + case 'v': + vflag++; + break; + case 'w': + flags |= WATCH_JSON; + watch = true; + break; + case 'V': + (void)fprintf(stderr, "%s: %s (revision %s)\n", + argv[0], VERSION, REVISION); + exit(0); + case 's': + serialport = optarg; + break; + case 'o': + outfile = optarg; + break; + case '?': + case 'h': + default: + usage(); + exit(1); + } + } + /*@+branchstate@*/ + + /* Grok the server, port, and device. */ + if (optind < argc) { + gpsd_source_spec(argv[optind], &source); + } else + gpsd_source_spec(NULL, &source); + + if (serialport != NULL && !raw) { + (void)fprintf(stderr, "gpspipe: use of '-s' requires '-r'.\n"); + exit(1); + } + + if (outfile == NULL && daemon) { + (void)fprintf(stderr, "gpspipe: use of '-d' requires '-f'.\n"); + exit(1); + } + + if (!raw && !watch && !binary) { + (void)fprintf(stderr, + "gpspipe: one of '-R', '-r' or '-w' is required.\n"); + exit(1); + } + + /* Daemonize if the user requested it. */ + if (daemon) + daemonize(); + + /* Sleep for ten seconds if the user requested it. */ + if (sleepy) + (void)sleep(10); + + /* Open the output file if the user requested it. If the user + * requested '-R', we use the 'b' flag in fopen() to "do the right + * thing" in non-linux/unix OSes. */ + if (outfile == NULL) { + fp = stdout; + } else { + if (binary) + fp = fopen(outfile, "wb"); + else + fp = fopen(outfile, "w"); + + if (fp == NULL) { + (void)fprintf(stderr, + "gpspipe: unable to open output file: %s\n", + outfile); + exit(1); + } + } + + /* Open the serial port and set it up. */ + if (serialport) + open_serial(serialport); + + /*@ -nullpass -onlytrans @*/ + if (gps_open_r(source.server, source.port, &gpsdata) != 0) { + (void)fprintf(stderr, + "gpspipe: could not connect to gpsd %s:%s, %s(%d)\n", + source.server, source.port, strerror(errno), errno); + exit(1); + } + /*@ +nullpass +onlytrans @*/ + + if (source.device != NULL) + flags |= WATCH_DEVICE; + (void)gps_stream(&gpsdata, flags, source.device); + + if ((isatty(STDERR_FILENO) == 0) || daemon) + vflag = 0; + + for (;;) { + int i = 0; + int j = 0; + int readbytes = 0; + + if (vflag) + spinner(vflag, l++); + + /* reading directly from the socket avoids decode overhead */ + readbytes = (int)read(gpsdata.gps_fd, buf, sizeof(buf)); + if (readbytes > 0) { + for (i = 0; i < readbytes; i++) { + char c = buf[i]; + if (j < (int)(sizeof(serbuf) - 1)) { + serbuf[j++] = buf[i]; + } + if (new_line && timestamp) { + time_t now = time(NULL); + + struct tm *tmp_now = localtime(&now); + (void)strftime(tmstr, sizeof(tmstr), format, tmp_now); + new_line = 0; + if (fprintf(fp, "%.24s :", tmstr) <= 0) { + (void)fprintf(stderr, + "gpspipe: write error, %s(%d)\n", + strerror(errno), errno); + exit(1); + } + } + if (fputc(c, fp) == EOF) { + fprintf(stderr, "gpspipe: Write Error, %s(%d)\n", + strerror(errno), errno); + exit(1); + } + + if (c == '\n') { + if (serialport != NULL) { + if (write(fd_out, serbuf, (size_t) j) == -1) { + fprintf(stderr, + "gpspipe: Serial port write Error, %s(%d)\n", + strerror(errno), errno); + exit(1); + } + j = 0; + } + + new_line = true; + /* flush after every good line */ + if (fflush(fp)) { + (void)fprintf(stderr, + "gpspipe: fflush Error, %s(%d)\n", + strerror(errno), errno); + exit(1); + } + if (count > 0) { + if (0 >= --count) { + /* completed count */ + exit(0); + } + } + } + } + } else { + if (readbytes == -1) { + (void)fprintf(stderr, "gpspipe: read error %s(%d)\n", + strerror(errno), errno); + exit(1); + } else { + exit(0); + } + } + } + +#ifdef __UNUSED__ + if (serialport != NULL) { + /* Restore the old serial port settings. */ + if (tcsetattr(fd_out, TCSANOW, &oldtio) != 0) { + (void)fprintf(stderr, "Error restoring serial port settings\n"); + exit(1); + } + } +#endif /* __UNUSED__ */ + + /*@i1@*/ exit(0); +} + +/*@ +compdestroy @*/ + +static void spinner(unsigned int v, unsigned int num) +{ + char *spin = "|/-\\"; + + (void)fprintf(stderr, "\010%c", spin[(num / (1 << (v - 1))) % 4]); + (void)fflush(stderr); + return; +} diff --git a/gpspipe.xml b/gpspipe.xml new file mode 100644 index 0000000..dd935d9 --- /dev/null +++ b/gpspipe.xml @@ -0,0 +1,151 @@ + + + + +03 Aug 2005 + +gpspipe +1 +The GPSD Project +GPSD Documentation + + +gpspipe +tool to connect to gpsd and retrieve sentences + + + + + gpspipe + -h + -d + -l + -o filename + -n count + -r + -R + -s serial-device + -t + -T timestamp-format + -w + -v + -D debug-level + + server + :port + :device + + + + + +DESCRIPTION + +gpspipe is a tool to connect +to gpsd and output the received +sentences to stdout. This makes the program useful as a pipe from +gpsd to another program or file. + +gpspipe does not require root +privileges, and can be run concurrently with other tools connecting +to the local gpsd without causing problems. + +The output will consist of one or both of the raw NMEA or native +gpsd sentences. Each line can be optionally +time stamped. There is also an option to exit gracefully after a +given count of packets. + +Optionally a server, TCP/IP port number and remote device can be given. +If omitted, gpspipe connects to localhost on +the default port (2947) and watches all devices opened by +gpsd. + +gpspipe may be run as a daemon, but +requires the -o flag for writing the output to a file. + + +OPTIONS + +-h makes gpspipe print +a usage message and exit. + +-d causes gpspipe to run as a daemon. + +-l causes gpspipe to sleep for ten +seconds before attempting to connect to gpsd. This is very useful +when running as a daemon, giving gpsd time to start before +attempting a connection. + +-r causes raw NMEA sentences to be output. + +-R causes super-raw (gps binary) data to be output. This overrides +NMEA and gpsd output modes. + +-s option causes the collected data to be written to the +specified serial device with settings 4800 8N1. Thus +gpspipe can be used with -s and -r options +to emulate a serial port hardwired to a GPS that +gpsd is managing. + +-o option causes the collected data to be written to the +specified file. Use of this option is mandatory +if gpspipe is run as a daemon. + +-w causes native gpsdsentences to be +output. + +-t adds a timestamp to each sentence output. + +-T sets the format of the timestamp. See +strftime3 +for the available placeholders. Setting this option implies -t. + +-n [count] causes [count] sentences to be output. +gpspipe will then exit gracefully. + +-v causes gpspipe to show a spinning +activity indicator on stderr. This is useful if stdout is redirected +into a file or a pipe. By default the spinner is advanced with every +messages written; specifying -v more than once will double the number +of messages required to rotate the spinner. + +-V prints the version, then exits. + +At least one of -R, -r or -w must be specified. + + +EXAMPLE +When gpsd is running gpspipe +-r -n 100 will send one hundred raw NMEA sentences to +standard output, then exit. + + +SEE ALSO + +gpsd8, +gps1, +libgps3, +libgpsd3, +gpsprof1, +gpsfake1, +gpsctl1, +gpscat1. +gpsmon1. + + + +AUTHOR + +Gary E. Miller gem@rellim.com. There is a +project page for gpsd here. + + + + + diff --git a/gpsprof b/gpsprof new file mode 100755 index 0000000..e88936b --- /dev/null +++ b/gpsprof @@ -0,0 +1,494 @@ +#!/usr/bin/env python +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# Collect and plot latency-profiling data from a running gpsd. +# Requires gnuplot. +# +import sys, os, time, getopt, tempfile, time, socket, math, copy +import gps + +class Baton: + "Ship progress indication to stderr." + def __init__(self, prompt, endmsg=None): + self.stream = sys.stderr + self.stream.write(prompt + "...") + if os.isatty(self.stream.fileno()): + self.stream.write(" \010") + self.stream.flush() + self.count = 0 + self.endmsg = endmsg + self.time = time.time() + return + + def twirl(self, ch=None): + if self.stream is None: + return + if ch: + self.stream.write(ch) + elif os.isatty(self.stream.fileno()): + self.stream.write("-/|\\"[self.count % 4]) + self.stream.write("\010") + self.count = self.count + 1 + self.stream.flush() + return + + def end(self, msg=None): + if msg == None: + msg = self.endmsg + if self.stream: + self.stream.write("...(%2.2f sec) %s.\n" % (time.time() - self.time, msg)) + return + +class spaceplot: + "Total times without instrumentation." + name = "space" + def __init__(self): + self.fixes = [] + def d(self, a, b): + return math.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2) + def gather(self, session): + # Include altitude, not used here, for 3D plot experiments. + # Watch out for the NaN value from gps.py. + self.fixes.append((session.fix.latitude, session.fix.longitude, session.fix.altitude)) + return True + def header(self, session): + res = "# Position uncertainty, %s, %s, %ds cycle\n" % \ + (title, session.gps_id, session.cycle) + return res + def data(self, session): + res = "" + for i in range(len(self.recentered)): + (lat, lon) = self.recentered[i][:2] + (raw1, raw2, alt) = self.fixes[i] + res += "%f\t%f\t%f\t%f\t%f\n" % (lat, lon, raw1, raw2, alt) + return res + def plot(self, title, session): + if len(self.fixes) == 0: + sys.stderr.write("No fixes collected, can't estimate accuracy.") + sys.exit(1) + # centroid is just arithmetic avg of lat,lon + self.centroid = (sum(map(lambda x:x[0], self.fixes))/len(self.fixes), sum(map(lambda x:x[1], self.fixes))/len(self.fixes)) + # Sort fixes by distance from centroid + self.fixes.sort(lambda x, y: cmp(self.d(self.centroid, x), self.d(self.centroid, y))) + # Convert fixes to offsets from centroid in meters + self.recentered = map(lambda fix: gps.MeterOffset(self.centroid, fix[:2]), self.fixes) + # Compute CEP(50%) + cep_meters = gps.EarthDistance(self.centroid[:2], self.fixes[len(self.fixes)/2][:2]) + alt_sum = 0 + alt_num = 0 + alt_fixes = [] + lon_max = -9999 + for i in range(len(self.recentered)): + (lat, lon) = self.recentered[i][:2] + (raw1, raw2, alt) = self.fixes[i] + if not gps.isnan(alt): + alt_sum += alt + alt_fixes.append( alt) + alt_num += 1 + if lon > lon_max : + lon_max = lon + if alt_num == 0: + alt_avg = gps.NaN + alt_ep = gps.NaN + else: + alt_avg = alt_sum / alt_num + # Sort fixes by distance from average altitude + alt_fixes.sort(lambda x, y: cmp(abs(alt_avg - x), abs(alt_avg - y))) + alt_ep = abs( alt_fixes[ len(alt_fixes)/2 ] - alt_avg) + if self.centroid[0] < 0: + latstring = "%fS" % -self.centroid[0] + elif self.centroid[0] == 0: + latstring = "0" + else: + latstring = "%fN" % self.centroid[0] + if self.centroid[1] < 0: + lonstring = "%fW" % -self.centroid[1] + elif self.centroid[1] == 0: + lonstring = "0" + else: + lonstring = "%fE" % self.centroid[1] + fmt = "set autoscale\n" + fmt += 'set key below\n' + fmt += 'set key title "%s"\n' % time.asctime() + fmt += 'set size ratio -1\n' + fmt += 'set style line 2 pt 1\n' + fmt += 'set style line 3 pt 2\n' + fmt += 'set xlabel "Meters east from %s"\n' % lonstring + fmt += 'set ylabel "Meters north from %s"\n' % latstring + fmt += 'set border 15\n' + if not gps.isnan(alt_avg): + fmt += 'set y2label "Meters Altitude from %f"\n' % alt_avg + fmt += 'set ytics nomirror\n' + fmt += 'set y2tics\n' + fmt += 'cep=%f\n' % self.d((0,0), self.recentered[len(self.fixes)/2]) + fmt += 'set parametric\n' + fmt += 'set trange [0:2*pi]\n' + fmt += 'cx(t, r) = sin(t)*r\n' + fmt += 'cy(t, r) = cos(t)*r\n' + fmt += 'chlen = cep/20\n' + fmt += "set arrow from -chlen,0 to chlen,0 nohead\n" + fmt += "set arrow from 0,-chlen to 0,chlen nohead\n" + fmt += 'plot cx(t, cep),cy(t, cep) title "CEP (50%%) = %f meters", ' % (cep_meters) + fmt += ' "-" using 1:2 with points ls 3 title "%d GPS fixes" ' % (len(self.fixes)) + if not gps.isnan(alt_avg): + fmt += ', "-" using ( %f ):($5 < 100000 ? $5 - %f : 1/0) axes x1y2 with points ls 2 title " %d Altitude fixes, Average = %f, EP (50%%) = %f" \n' % (lon_max +1, alt_avg, alt_num, alt_avg, alt_ep) + else: + fmt += "\n" + fmt += self.header(session) + fmt += self.data(session) + if not gps.isnan(alt_avg): + fmt += "e\n" + self.data(session) + return fmt + +class uninstrumented: + "Total times without instrumentation." + name = "uninstrumented" + def __init__(self): + self.stats = [] + def gather(self, session): + if session.fix.time: + seconds = time.time() - session.fix.time + self.stats.append(seconds) + return True + else: + return False + def header(self, session): + return "# Uninstrumented total latency, %s, %s, %dN%d, cycle %ds\n" % \ + (title, + session.gps_id, session.baudrate, + session.stopbits, session.cycle) + def data(self, session): + res = "" + for seconds in self.stats: + res += "%2.6lf\n" % seconds + return res + def plot(self, title, session): + fmt = ''' +set autoscale +set key below +set key title "Uninstrumented total latency, %s, %s, %dN%d, cycle %ds" +plot "-" using 0:1 title "Total time" with impulses +''' + res = fmt % (title, + session.gps_id, session.baudrate, + session.stopbits, session.cycle) + res += self.header(session) + return res + self.data(session) + +class rawplot: + "All measurement, no deductions." + name = "raw" + def __init__(self): + self.stats = [] + def gather(self, session): + self.stats.append(copy.copy(session.timings)) + return True + def header(self, session): + res = "# Raw latency data, %s, %s, %dN%d, cycle %ds\n" % \ + (title, + session.gps_id, session.baudrate, + session.stopbits, session.cycle) + res += "# tag len xmit " + for hn in ("T1", "D1", "E2", "T2", "D2"): + res += "%-13s" % hn + res += "\n#------- ----- --------------------" + for i in range(0, 5): + res += " " + ("-" * 11) + return res + "\n" + def data(self, session): + res = "" + for timings in self.stats: + res += "% 8s %4d %2.9f %2.9f %2.9f %2.9f %2.9f %2.9f\n" \ + % (timings.tag, + timings.len, + timings.xmit, + timings.recv - timings.xmit, + timings.decode - timings.recv, + timings.emit - timings.decode, + timings.c_recv - timings.emit, + timings.c_decode - timings.c_recv) + return res + def plot(self, file, session): + fmt = ''' +set autoscale +set key below +set key title "Raw latency data, %s, %s, %dN%d, cycle %ds" +plot \ + "-" using 0:8 title "D2 = Client decode time" with impulses, \ + "-" using 0:7 title "T2 = TCP/IP latency" with impulses, \ + "-" using 0:6 title "E2 = Daemon encode time" with impulses, \ + "-" using 0:5 title "D1 = Daemon decode time" with impulses, \ + "-" using 0:4 title "T1 = RS232 time" with impulses +''' + res = fmt % (title, + session.gps_id, session.baudrate, + session.stopbits, session.cycle) + res += self.header(session) + for dummy in range(0, 5): + res += self.data(session) + "e\n" + return res + +class splitplot: + "Discard base time, use color to indicate different tags." + name = "split" + sentences = [] + def __init__(self): + self.stats = [] + def gather(self, session): + self.stats.append(copy.copy(session.timings)) + if session.timings.tag not in self.sentences: + self.sentences.append(session.timings.tag) + return True + def header(self, session): + res = "# Split latency data, %s, %s, %dN%d, cycle %ds\n#" % \ + (title, + session.gps_id, session.baudrate, + session.stopbits, session.cycle) + for s in splitplot.sentences: + res += "%8s\t" % s + for hn in ("T1", "D1", "E2", "T2", "D2", "length"): + res += "%8s\t" % hn + res += "tag\n# " + for s in tuple(splitplot.sentences) + ("T1", "D1", "E2", "T2", "D2", "length"): + res += "---------\t" + return res + "--------\n" + def data(self, session): + res = "" + for timings in self.stats: + for s in splitplot.sentences: + if s == timings.tag: + res += "%2.6f\t" % timings.xmit + else: + res += "- \t" + res += "%2.6f\t%2.6f\t%2.6f\t%2.6f\t%2.6f\t%8d\t# %s\n" \ + % (timings.recv - timings.xmit, + timings.decode - timings.recv, + timings.emit - timings.decode, + timings.c_recv - timings.emit, + timings.c_decode - timings.c_recv, + timings.len, + timings.tag) + return res + def plot(self, title, session): + fixed = ''' +set autoscale +set key below +set key title "Filtered latency data, %s, %s, %dN%d, cycle %ds" +plot \ + "-" using 0:%d title "D2 = Client decode time" with impulses, \ + "-" using 0:%d title "T2 = TCP/IP latency" with impulses, \ + "-" using 0:%d title "E2 = Daemon encode time" with impulses, \ + "-" using 0:%d title "D1 = Daemon decode time" with impulses, \ + "-" using 0:%d title "T1 = RS3232 time" with impulses, \ +''' + sc = len(splitplot.sentences) + fmt = fixed % (title, + session.gps_id, session.baudrate, + session.stopbits, session.cycle, + sc+5, + sc+4, + sc+3, + sc+2, + sc+1) + for i in range(sc): + fmt += ' "-" using 0:%d title "%s" with impulses,' % \ + (i+1, self.sentences[i]) + res = fmt[:-1] + "\n" + res += self.header(session) + for dummy in range(sc+5): + res += self.data(session) + "e\n" + return res + +class cycle: + "Send-cycle analysis." + name = "cycle" + def __init__(self): + self.stats = [] + def gather(self, session): + self.stats.append(copy.copy(session.timings)) + return True + def plot(self, title, session): + msg = "" + def roundoff(n): + # Round a time to hundredths of a second + return round(n*100) / 100.0 + intervals = {} + last_seen = {} + for timing in self.stats: + # Throw out everything but the leader in each GSV group + if timing.tag[-3:] == "GSV" and last_command[-3:] == "GSV": + continue + last_command = timing.tag + # Record timings + received = timing.d_received() + if not timing.tag in intervals: + intervals[timing.tag] = [] + if timing.tag in last_seen: + intervals[timing.tag].append(roundoff(received - last_seen[timing.tag])) + last_seen[timing.tag] = received + + # Step three: get command frequencies and the basic send cycle time + frequencies = {} + for (key, interval_list) in intervals.items(): + frequencies[key] = {} + for interval in interval_list: + frequencies[key][interval] = frequencies[key].get(interval, 0) + 1 + # filter out noise + for key in frequencies: + distribution = frequencies[key] + for interval in distribution.keys(): + if distribution[interval] < 2: + del distribution[interval] + cycles = {} + for key in frequencies: + distribution = frequencies[key] + if len(frequencies[key].values()) == 1: + # The value is uniqe after filtering + cycles[key] = distribution.keys()[0] + else: + # Compute the mode + maxfreq = 0 + for (interval, frequency) in distribution.items(): + if distribution[interval] > maxfreq: + cycles[key] = interval + maxfreq = distribution[interval] + msg += "Cycle report %s, %s, %dN%d, cycle %ds" % \ + (title, + session.gps_id, session.baudrate, + session.stopbits, session.cycle) + msg += "The sentence set emitted by this GPS is: %s\n" % " ".join(intervals.keys()) + for key in cycles: + if len(frequencies[key].values()) == 1: + if cycles[key] == 1: + msg += "%s: is emitted once a second.\n" % key + else: + msg += "%s: is emitted once every %d seconds.\n" % (key, cycles[key]) + else: + if cycles[key] == 1: + msg += "%s: is probably emitted once a second.\n" % key + else: + msg += "%s: is probably emitted once every %d seconds.\n" % (key, cycles[key]) + sendcycle = min(*cycles.values()) + if sendcycle == 1: + msg += "Send cycle is once per second.\n" + else: + msg += "Send cycle is once per %d seconds.\n" % sendcycle + return msg + +formatters = (spaceplot, uninstrumented, rawplot, splitplot, cycle) + +def plotframe(await, fname, speed, threshold, title): + "Return a string containing a GNUplot script " + if fname: + for formatter in formatters: + if formatter.name == fname: + plotter = formatter() + break + else: + sys.stderr.write("gpsprof: no such formatter.\n") + sys.exit(1) + try: + session = gps.gps(verbose=verbose) + except socket.error: + sys.stderr.write("gpsprof: gpsd unreachable.\n") + sys.exit(1) + # Initialize + session.poll() + if session.version == None: + print >>sys.stderr, "gpsprof: requires gpsd to speak new protocol." + sys.exit(1) + session.send("?DEVICES;") + while session.poll() != -1: + if session.data["class"] == "DEVICES": + break + if len(session.data.devices) != 1: + print >>sys.stderr, "gpsprof: exactly one device must be attached." + sys.exit(1) + device = session.data.devices[0] + path = device["path"] + session.baudrate = device["bps"] + session.parity = device["bps"] + session.stopbits = device["stopbits"] + session.cycle = device["cycle"] + session.gps_id = device["driver"] + # Set parameters + if speed: + session.send('?DEVICE={"path":"%s","bps:":%d}' % (path, speed)) + session.poll() + if session.baudrate != speed: + sys.stderr.write("gpsprof: baud rate change failed.\n") + options = "" + if formatter not in (spaceplot, uninstrumented): + options = ',"timing":true' + try: + #session.set_raw_hook(lambda x: sys.stderr.write(`x`+"\n")) + session.send('?WATCH={"enable":true%s}' % options) + baton = Baton("gpsprof: looking for fix", "done") + countdown = await + basetime = time.time() + while countdown > 0: + if session.poll() == -1: + sys.stderr.write("gpsprof: gpsd has vanished.\n") + sys.exit(1) + baton.twirl() + if session.data["class"] == "WATCH": + if "timing" in options and not session.data.get("timing"): + sys.stderr.write("gpsprof: timing is not enabled.\n") + sys.exit(1) + # We can get some funky artifacts at start of session + # apparently due to RS232 buffering effects. Ignore + # them. + if threshold and time.time()-basetime < session.cycle * threshold: + continue + if session.fix.mode <= gps.MODE_NO_FIX: + continue + if countdown == await: + sys.stderr.write("first fix in %.2fsec, gathering %d samples..." % (time.time()-basetime,await)) + if plotter.gather(session): + countdown -= 1 + baton.end() + finally: + session.send('?WATCH={"enable":false,"timing":false}') + command = plotter.plot(title, session) + del session + return command + +if __name__ == '__main__': + try: + (options, arguments) = getopt.getopt(sys.argv[1:], "f:hm:n:s:t:D:") + + formatter = "space" + raw = False + speed = 0 + title = time.ctime() + threshold = 0 + await = 100 + verbose = 0 + for (switch, val) in options: + if (switch == '-f'): + formatter = val + elif (switch == '-m'): + threshold = int(val) + elif (switch == '-n'): + await = int(val) + elif (switch == '-s'): + speed = int(val) + elif (switch == '-t'): + title = val + elif (switch == '-D'): + verbose = int(val) + elif (switch == '-h'): + sys.stderr.write(\ + "usage: gpsprof [-h] [-D debuglevel] [-m threshold] [-n samplecount] \n" + + "\t[-f {" + "|".join(map(lambda x: x.name, formatters)) + "}] [-s speed] [-t title]\n") + sys.exit(0) + sys.stdout.write(plotframe(await,formatter,speed,threshold,title)) + except KeyboardInterrupt: + pass + +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:python +# End: diff --git a/gpsprof.xml b/gpsprof.xml new file mode 100644 index 0000000..d0b5330 --- /dev/null +++ b/gpsprof.xml @@ -0,0 +1,181 @@ + + + + +10 Feb 2005 + +gpsprof +1 +The GPSD Project +GPSD Documentation + + +gpsprof +profile a GPS and gpsd, plotting latency information + + + + + gpsprof + -f plot_type + -m threshold + -n packetcount + -s speed + -t title + -D debuglevel + -h + + + +DESCRIPTION + +gpsprof measures the various +latencies between a GPS and its client. It emits to standard output a +GNUPLOT program that draws an illustrative graph. It can also be told +to emit the raw profile data. The information it provides can be +useful for establishing an upper bound on latency, and thus on +position accuracy of a GPS in motion. + +gpsprof uses instrumentation built +into gpsd. + +To display the graph, use +gnuplot1. +Thus, for example, to display the default spatial scatter plot, do +this: + + +gpsprof | gnuplot -persist + + + + +OPTIONS + +The -f option sets the plot type. The X axis is samples +(sentences with timestamps). The Y axis is normally latency in seconds. +Currently the following plot types are defined: + + + +space + +Generate a scattergram of fixes and plot a probable-error +circle. This data is only meaningful if the GPS is held stationary +while gpsprof is running. +This is the default. + + + + +uninstrumented + +Plot total latency without instrumentation. Useful mainly as a +check that the instrumentation is not producing significant +distortion. It only plots times for sentences that contain fixes; +staircase-like artifacts in the plot are created when elapsed time +from sentences without fixes is lumped in. + + + +raw + +Plot raw data. + + + +split + +Each sentence has its RS232 latency time colored differently. + + + +cycle + +Report on the set of sentences or packets emitted by the GPS, +their send intervals, and the basic cycle time. (This report is +plain text rather than a gnuplot script.) + + + + +The instrumented time plot conveys the following information: + + + +RS232 time + +Time required to send the sentence from the GPS to +gpsd. This measured from the time of +the last zero-length read before the packet to when the packet sniffer +recognizes a complete sentence, so there is a small aountt of +computational overhead mixed in. + + + +Decode time + +Elapsed time between sentence reception and the moment that +gpsd ships the resulting update to +the profiling client. + + + +TCP/IP latency + +Elapsed time between the moment that +gpsd ships the update to +the profiling client and the moment it is decoded and timestamped. + + + + +Because of RS232 buffering effects, the profiler sometimes +generates reports of ridiculously high latencies right at the +beginning of a session. The -m option lets you set a latency threshold, in +multiples of the cycle time, above which reports are discarded. + +The -n option sets the number of packets to sample. The default +is 100. + +The -s option sets the baud rate. Note, this will only work if +the chipset accepts a speed-change command (SiRFstarII and SiRFstarIII +support this feature). + +The -t option sets a text string to be included in the plot +title. + +The -h option makes gpsprof print +a usage message and exit. + +The -D sets debug level. + + +SEE ALSO + +gpsd8, +gps1, +libgps3, +libgpsd3, +gpsfake1, +gpsctl1, +gpscat1, +gnuplot1. + + + +AUTHOR + +Eric S. Raymond esr@thyrsus.com. There is a +project page for gpsd here. + + + + + diff --git a/gpsutils.c b/gpsutils.c new file mode 100644 index 0000000..6b94de0 --- /dev/null +++ b/gpsutils.c @@ -0,0 +1,577 @@ +/* gpsutils.c -- code shared between low-level and high-level interfaces + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include + +#include "gpsd.h" + +#ifdef USE_QT +#include +#include +#endif + +#define MONTHSPERYEAR 12 /* months per calendar year */ + +void gps_clear_fix( /*@out@*/ struct gps_fix_t *fixp) +/* stuff a fix structure with recognizable out-of-band values */ +{ + fixp->time = NAN; + fixp->mode = MODE_NOT_SEEN; + fixp->latitude = fixp->longitude = NAN; + fixp->track = NAN; + fixp->speed = NAN; + fixp->climb = NAN; + fixp->altitude = NAN; + fixp->ept = NAN; + fixp->epx = NAN; + fixp->epy = NAN; + fixp->epv = NAN; + fixp->epd = NAN; + fixp->eps = NAN; + fixp->epc = NAN; +} + +void gps_merge_fix( /*@ out @*/ struct gps_fix_t *to, + gps_mask_t transfer, + /*@ in @*/ struct gps_fix_t *from) +/* merge new data into an old fix */ +{ + if ((NULL == to) || (NULL == from)) + return; + if ((transfer & TIME_IS) != 0) + to->time = from->time; + if ((transfer & LATLON_IS) != 0) { + to->latitude = from->latitude; + to->longitude = from->longitude; + } + if ((transfer & MODE_IS) != 0) + to->mode = from->mode; + if ((transfer & ALTITUDE_IS) != 0) + to->altitude = from->altitude; + if ((transfer & TRACK_IS) != 0) + to->track = from->track; + if ((transfer & SPEED_IS) != 0) + to->speed = from->speed; + if ((transfer & CLIMB_IS) != 0) + to->climb = from->climb; + if ((transfer & TIMERR_IS) != 0) + to->ept = from->ept; + if ((transfer & HERR_IS) != 0) { + to->epx = from->epx; + to->epy = from->epy; + } + if ((transfer & VERR_IS) != 0) + to->epv = from->epv; + if ((transfer & SPEEDERR_IS) != 0) + to->eps = from->eps; +} + +double timestamp(void) +{ + struct timeval tv; + (void)gettimeofday(&tv, NULL); + /*@i1@*/ return (tv.tv_sec + tv.tv_usec * 1e-6); +} + +time_t mkgmtime(register struct tm * t) +/* struct tm to seconds since Unix epoch */ +{ + register int year; + register time_t result; + static const int cumdays[MONTHSPERYEAR] = + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + + /*@ +matchanyintegral @*/ + year = 1900 + t->tm_year + t->tm_mon / MONTHSPERYEAR; + result = (year - 1970) * 365 + cumdays[t->tm_mon % MONTHSPERYEAR]; + result += (year - 1968) / 4; + result -= (year - 1900) / 100; + result += (year - 1600) / 400; + if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0) && + (t->tm_mon % MONTHSPERYEAR) < 2) + result--; + result += t->tm_mday - 1; + result *= 24; + result += t->tm_hour; + result *= 60; + result += t->tm_min; + result *= 60; + result += t->tm_sec; + /*@ -matchanyintegral @*/ + return (result); +} + +double iso8601_to_unix( /*@in@*/ char *isotime) +/* ISO8601 UTC to Unix UTC */ +{ +#ifndef USE_QT + char *dp = NULL; + double usec; + struct tm tm; + + /*@i1@*/ dp = strptime(isotime, "%Y-%m-%dT%H:%M:%S", &tm); + if (dp != NULL && *dp == '.') + usec = strtod(dp, NULL); + else + usec = 0; + return (double)mkgmtime(&tm) + usec; +#else + double usec = 0; + + QString t(isotime); + QDateTime d = QDateTime::fromString(isotime, Qt::ISODate); + QStringList sl = t.split("."); + if (sl.size() > 1) + usec = sl[1].toInt() / pow(10., (double)sl[1].size()); + return d.toTime_t() + usec; +#endif +} + +/* *INDENT-OFF* */ +/*@observer@*/char *unix_to_iso8601(double fixtime, /*@ out @*/ + char isotime[], size_t len) +/* Unix UTC time to ISO8601, no timezone adjustment */ +/* example: 2007-12-11T23:38:51.0Z */ +{ + struct tm when; + double integral, fractional; + time_t intfixtime; + char timestr[30]; + char fractstr[10]; + + fractional = modf(fixtime, &integral); + intfixtime = (time_t) integral; + (void)gmtime_r(&intfixtime, &when); + + (void)strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &when); + (void)snprintf(fractstr, sizeof(fractstr), "%.1f", fractional); + /* add fractional part, ignore leading 0; "0.2" -> ".2" */ + (void)snprintf(isotime, len, "%s%sZ", timestr, fractstr + 1); + return isotime; +} +/* *INDENT-ON* */ + +/* + * The 'week' part of GPS dates are specified in weeks since 0000 on 06 + * January 1980, with a rollover at 1024. At time of writing the last + * rollover happened at 0000 22 August 1999. Time-of-week is in seconds. + * + * This code copes with both conventional GPS weeks and the "extended" + * 15-or-16-bit version with no wraparound that appears in Zodiac + * chips and is supposed to appear in the Geodetic Navigation + * Information (0x29) packet of SiRF chips. Some SiRF firmware versions + * (notably 231) actually ship the wrapped 10-bit week, despite what + * the protocol reference claims. + * + * Note: This time will need to be corrected for leap seconds. + */ +#define GPS_EPOCH 315964800 /* GPS epoch in Unix time */ +#define SECS_PER_WEEK (60*60*24*7) /* seconds per week */ +#define GPS_ROLLOVER (1024*SECS_PER_WEEK) /* rollover period */ + +double gpstime_to_unix(int week, double tow) +{ + double fixtime; + + if (week >= 1024) + fixtime = GPS_EPOCH + (week * SECS_PER_WEEK) + tow; + else { + time_t now, last_rollover; + (void)time(&now); + last_rollover = + GPS_EPOCH + ((now - GPS_EPOCH) / GPS_ROLLOVER) * GPS_ROLLOVER; + /*@i@*/ fixtime = last_rollover + (week * SECS_PER_WEEK) + tow; + } + return fixtime; +} + +void unix_to_gpstime(double unixtime, + /*@out@*/ int *week, + /*@out@*/ double *tow) +{ + unixtime -= GPS_EPOCH; + *week = (int)(unixtime / SECS_PER_WEEK); + *tow = fmod(unixtime, SECS_PER_WEEK); +} + +#define Deg2Rad(n) ((n) * DEG_2_RAD) + +double earth_distance(double lat1, double lon1, double lat2, double lon2) +/* distance in meters between two points specified in degrees. */ +{ + /* + * this is a translation of the javascript implementation of the + * Vincenty distance formula by Chris Veness. See + * http://www.movable-type.co.uk/scripts/latlong-vincenty.html + */ + double a, b, f; // WGS-84 ellipsoid params + double L, L_P, U1, U2, s_U1, c_U1, s_U2, c_U2; + double uSq, A, B, d_S, lambda; + double s_L, c_L, s_S, C; + double c_S, S, s_A, c_SqA, c_2SM; + int i = 100; + + a = WGS84A; + b = WGS84B; + f = 1 / WGS84F; + L = Deg2Rad(lon2 - lon1); + U1 = atan((1 - f) * tan(Deg2Rad(lat1))); + U2 = atan((1 - f) * tan(Deg2Rad(lat2))); + s_U1 = sin(U1); + c_U1 = cos(U1); + s_U2 = sin(U2); + c_U2 = cos(U2); + lambda = L; + + do { + s_L = sin(lambda); + c_L = cos(lambda); + s_S = sqrt((c_U2 * s_L) * (c_U2 * s_L) + + (c_U1 * s_U2 - s_U1 * c_U2 * c_L) * + (c_U1 * s_U2 - s_U1 * c_U2 * c_L)); + + if (s_S == 0) + return 0; + + c_S = s_U1 * s_U2 + c_U1 * c_U2 * c_L; + S = atan2(s_S, c_S); + s_A = c_U1 * c_U2 * s_L / s_S; + c_SqA = 1 - s_A * s_A; + c_2SM = c_S - 2 * s_U1 * s_U2 / c_SqA; + + if (isnan(c_2SM)) + c_2SM = 0; + + C = f / 16 * c_SqA * (4 + f * (4 - 3 * c_SqA)); + L_P = lambda; + lambda = L + (1 - C) * f * s_A * + (S + C * s_S * (c_2SM + C * c_S * (2 * c_2SM * c_2SM - 1))); + } while ((fabs(lambda - L_P) > 1.0e-12) && (--i > 0)); + + if (i == 0) + return NAN; // formula failed to converge + + uSq = c_SqA * ((a * a) - (b * b)) / (b * b); + A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))); + B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))); + d_S = B * s_S * (c_2SM + B / 4 * + (c_S * (-1 + 2 * c_2SM * c_2SM) - B / 6 * c_2SM * + (-3 + 4 * s_S * s_S) * (-3 + 4 * c_2SM * c_2SM))); + + return (WGS84B * A * (S - d_S)); +} + +/***************************************************************************** + +Carl Carter of SiRF supplied this algorithm for computing DOPs from +a list of visible satellites (some typos corrected)... + +For satellite n, let az(n) = azimuth angle from North and el(n) be elevation. +Let: + + a(k, 1) = sin az(k) * cos el(k) + a(k, 2) = cos az(k) * cos el(k) + a(k, 3) = sin el(k) + +Then form the line-of-sight matrix A for satellites used in the solution: + + | a(1,1) a(1,2) a(1,3) 1 | + | a(2,1) a(2,2) a(2,3) 1 | + | : : : : | + | a(n,1) a(n,2) a(n,3) 1 | + +And its transpose A~: + + |a(1, 1) a(2, 1) . . . a(n, 1) | + |a(1, 2) a(2, 2) . . . a(n, 2) | + |a(1, 3) a(2, 3) . . . a(n, 3) | + | 1 1 . . . 1 | + +Compute the covariance matrix (A~*A)^-1, which is guaranteed symmetric: + + | s(x)^2 s(x)*s(y) s(x)*s(z) s(x)*s(t) | + | s(y)*s(x) s(y)^2 s(y)*s(z) s(y)*s(t) | + | s(z)*s(x) s(z)*s(y) s(z)^2 s(z)*s(t) | + | s(t)*s(x) s(t)*s(y) s(t)*s(z) s(t)^2 | + +Then: + +GDOP = sqrt(s(x)^2 + s(y)^2 + s(z)^2 + s(t)^2) +TDOP = sqrt(s(t)^2) +PDOP = sqrt(s(x)^2 + s(y)^2 + s(z)^2) +HDOP = sqrt(s(x)^2 + s(y)^2) +VDOP = sqrt(s(z)^2) + +Here's how we implement it... + +First, each compute element P(i,j) of the 4x4 product A~*A. +If S(k=1,k=n): f(...) is the sum of f(...) as k varies from 1 to n, then +applying the definition of matrix product tells us: + +P(i,j) = S(k=1,k=n): B(i, k) * A(k, j) + +But because B is the transpose of A, this reduces to + +P(i,j) = S(k=1,k=n): A(k, i) * A(k, j) + +This is not, however, the entire algorithm that SiRF uses. Carl writes: + +> As you note, with rounding accounted for, most values agree exactly, and +> those that don't agree our number is higher. That is because we +> deweight some satellites and account for that in the DOP calculation. +> If a satellite is not used in a solution at the same weight as others, +> it should not contribute to DOP calculation at the same weight. So our +> internal algorithm does a compensation for that which you would have no +> way to duplicate on the outside since we don't output the weighting +> factors. In fact those are not even available to API users. + +Queried about the deweighting, Carl says: + +> In the SiRF tracking engine, each satellite track is assigned a quality +> value based on the tracker's estimate of that signal. It includes C/No +> estimate, ability to hold onto the phase, stability of the I vs. Q phase +> angle, etc. The navigation algorithm then ranks all the tracks into +> quality order and selects which ones to use in the solution and what +> weight to give those used in the solution. The process is actually a +> bit of a "trial and error" method -- we initially use all available +> tracks in the solution, then we sequentially remove the lowest quality +> ones until the solution stabilizes. The weighting is inherent in the +> Kalman filter algorithm. Once the solution is stable, the DOP is +> computed from those SVs used, and there is an algorithm that looks at +> the quality ratings and determines if we need to deweight any. +> Likewise, if we use altitude hold mode for a 3-SV solution, we deweight +> the phantom satellite at the center of the Earth. + +So we cannot exactly duplicate what SiRF does internally. We'll leave +HDOP alone and use our computed values for VDOP and PDOP. Note, this +may have to change in the future if this code is used by a non-SiRF +driver. + +******************************************************************************/ + +void clear_dop( /*@out@*/ struct dop_t *dop) +{ + dop->xdop = dop->ydop = dop->vdop = dop->tdop = dop->hdop = dop->pdop = + dop->gdop = NAN; +} + +/*@ -fixedformalarray -mustdefine @*/ +static bool invert(double mat[4][4], /*@out@*/ double inverse[4][4]) +{ + // Find all NECESSARY 2x2 subdeterminants + double Det2_12_01 = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]; + double Det2_12_02 = mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0]; + //double Det2_12_03 = mat[1][0]*mat[2][3] - mat[1][3]*mat[2][0]; + double Det2_12_12 = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; + //double Det2_12_13 = mat[1][1]*mat[2][3] - mat[1][3]*mat[2][1]; + //double Det2_12_23 = mat[1][2]*mat[2][3] - mat[1][3]*mat[2][2]; + double Det2_13_01 = mat[1][0] * mat[3][1] - mat[1][1] * mat[3][0]; + //double Det2_13_02 = mat[1][0]*mat[3][2] - mat[1][2]*mat[3][0]; + double Det2_13_03 = mat[1][0] * mat[3][3] - mat[1][3] * mat[3][0]; + //double Det2_13_12 = mat[1][1]*mat[3][2] - mat[1][2]*mat[3][1]; + double Det2_13_13 = mat[1][1] * mat[3][3] - mat[1][3] * mat[3][1]; + //double Det2_13_23 = mat[1][2]*mat[3][3] - mat[1][3]*mat[3][2]; + double Det2_23_01 = mat[2][0] * mat[3][1] - mat[2][1] * mat[3][0]; + double Det2_23_02 = mat[2][0] * mat[3][2] - mat[2][2] * mat[3][0]; + double Det2_23_03 = mat[2][0] * mat[3][3] - mat[2][3] * mat[3][0]; + double Det2_23_12 = mat[2][1] * mat[3][2] - mat[2][2] * mat[3][1]; + double Det2_23_13 = mat[2][1] * mat[3][3] - mat[2][3] * mat[3][1]; + double Det2_23_23 = mat[2][2] * mat[3][3] - mat[2][3] * mat[3][2]; + + // Find all NECESSARY 3x3 subdeterminants + double Det3_012_012 = mat[0][0] * Det2_12_12 - mat[0][1] * Det2_12_02 + + mat[0][2] * Det2_12_01; + //double Det3_012_013 = mat[0][0]*Det2_12_13 - mat[0][1]*Det2_12_03 + // + mat[0][3]*Det2_12_01; + //double Det3_012_023 = mat[0][0]*Det2_12_23 - mat[0][2]*Det2_12_03 + // + mat[0][3]*Det2_12_02; + //double Det3_012_123 = mat[0][1]*Det2_12_23 - mat[0][2]*Det2_12_13 + // + mat[0][3]*Det2_12_12; + //double Det3_013_012 = mat[0][0]*Det2_13_12 - mat[0][1]*Det2_13_02 + // + mat[0][2]*Det2_13_01; + double Det3_013_013 = mat[0][0] * Det2_13_13 - mat[0][1] * Det2_13_03 + + mat[0][3] * Det2_13_01; + //double Det3_013_023 = mat[0][0]*Det2_13_23 - mat[0][2]*Det2_13_03 + // + mat[0][3]*Det2_13_02; + //double Det3_013_123 = mat[0][1]*Det2_13_23 - mat[0][2]*Det2_13_13 + // + mat[0][3]*Det2_13_12; + //double Det3_023_012 = mat[0][0]*Det2_23_12 - mat[0][1]*Det2_23_02 + // + mat[0][2]*Det2_23_01; + //double Det3_023_013 = mat[0][0]*Det2_23_13 - mat[0][1]*Det2_23_03 + // + mat[0][3]*Det2_23_01; + double Det3_023_023 = mat[0][0] * Det2_23_23 - mat[0][2] * Det2_23_03 + + mat[0][3] * Det2_23_02; + //double Det3_023_123 = mat[0][1]*Det2_23_23 - mat[0][2]*Det2_23_13 + // + mat[0][3]*Det2_23_12; + double Det3_123_012 = mat[1][0] * Det2_23_12 - mat[1][1] * Det2_23_02 + + mat[1][2] * Det2_23_01; + double Det3_123_013 = mat[1][0] * Det2_23_13 - mat[1][1] * Det2_23_03 + + mat[1][3] * Det2_23_01; + double Det3_123_023 = mat[1][0] * Det2_23_23 - mat[1][2] * Det2_23_03 + + mat[1][3] * Det2_23_02; + double Det3_123_123 = mat[1][1] * Det2_23_23 - mat[1][2] * Det2_23_13 + + mat[1][3] * Det2_23_12; + + // Find the 4x4 determinant + static double det; + det = mat[0][0] * Det3_123_123 + - mat[0][1] * Det3_123_023 + + mat[0][2] * Det3_123_013 - mat[0][3] * Det3_123_012; + + // Very small determinants probably reflect floating-point fuzz near zero + if (fabs(det) < 0.0001) + return false; + + inverse[0][0] = Det3_123_123 / det; + //inverse[0][1] = -Det3_023_123 / det; + //inverse[0][2] = Det3_013_123 / det; + //inverse[0][3] = -Det3_012_123 / det; + + //inverse[1][0] = -Det3_123_023 / det; + inverse[1][1] = Det3_023_023 / det; + //inverse[1][2] = -Det3_013_023 / det; + //inverse[1][3] = Det3_012_023 / det; + + //inverse[2][0] = Det3_123_013 / det; + //inverse[2][1] = -Det3_023_013 / det; + inverse[2][2] = Det3_013_013 / det; + //inverse[2][3] = -Det3_012_013 / det; + + //inverse[3][0] = -Det3_123_012 / det; + //inverse[3][1] = Det3_023_012 / det; + //inverse[3][2] = -Det3_013_012 / det; + inverse[3][3] = Det3_012_012 / det; + + return true; +} + +/*@ +fixedformalarray +mustdefine @*/ + +gps_mask_t fill_dop(const struct gps_data_t * gpsdata, struct dop_t * dop) +{ + double prod[4][4]; + double inv[4][4]; + double satpos[MAXCHANNELS][4]; + double xdop, ydop, hdop, vdop, pdop, tdop, gdop; + int i, j, k, n; + +#ifdef __UNUSED__ + gpsd_report(LOG_INF, "Satellite picture:\n"); + for (k = 0; k < MAXCHANNELS; k++) { + if (gpsdata->used[k]) + gpsd_report(LOG_INF, "az: %d el: %d SV: %d\n", + gpsdata->azimuth[k], gpsdata->elevation[k], + gpsdata->used[k]); + } +#endif /* __UNUSED__ */ + + for (n = k = 0; k < gpsdata->satellites_used; k++) { + if (gpsdata->used[k] == 0) + continue; + satpos[n][0] = sin(gpsdata->azimuth[k] * DEG_2_RAD) + * cos(gpsdata->elevation[k] * DEG_2_RAD); + satpos[n][1] = cos(gpsdata->azimuth[k] * DEG_2_RAD) + * cos(gpsdata->elevation[k] * DEG_2_RAD); + satpos[n][2] = sin(gpsdata->elevation[k] * DEG_2_RAD); + satpos[n][3] = 1; + n++; + } + +#ifdef __UNUSED__ + gpsd_report(LOG_INF, "Line-of-sight matrix:\n"); + for (k = 0; k < n; k++) { + gpsd_report(LOG_INF, "%f %f %f %f\n", + satpos[k][0], satpos[k][1], satpos[k][2], satpos[k][3]); + } +#endif /* __UNUSED__ */ + + for (i = 0; i < 4; ++i) { //< rows + for (j = 0; j < 4; ++j) { //< cols + prod[i][j] = 0.0; + for (k = 0; k < n; ++k) { + prod[i][j] += satpos[k][i] * satpos[k][j]; + } + } + } + +#ifdef __UNUSED__ + gpsd_report(LOG_INF, "product:\n"); + for (k = 0; k < 4; k++) { + gpsd_report(LOG_INF, "%f %f %f %f\n", + prod[k][0], prod[k][1], prod[k][2], prod[k][3]); + } +#endif /* __UNUSED__ */ + + if (invert(prod, inv)) { +#ifdef __UNUSED__ + /* + * Note: this will print garbage unless all the subdeterminants + * are computed in the invert() function. + */ + gpsd_report(LOG_RAW, "inverse:\n"); + for (k = 0; k < 4; k++) { + gpsd_report(LOG_RAW, "%f %f %f %f\n", + inv[k][0], inv[k][1], inv[k][2], inv[k][3]); + } +#endif /* __UNUSED__ */ + } else { +#ifndef USE_QT + gpsd_report(LOG_DATA, + "LOS matrix is singular, can't calculate DOPs - source '%s'\n", + gpsdata->dev.path); +#endif + return 0; + } + + xdop = sqrt(inv[0][0]); + ydop = sqrt(inv[1][1]); + hdop = sqrt(inv[0][0] + inv[1][1]); + vdop = sqrt(inv[2][2]); + pdop = sqrt(inv[0][0] + inv[1][1] + inv[2][2]); + tdop = sqrt(inv[3][3]); + gdop = sqrt(inv[0][0] + inv[1][1] + inv[2][2] + inv[3][3]); + +#ifndef USE_QT + gpsd_report(LOG_DATA, + "DOPS computed/reported: X=%f/%f, Y=%f/%f, H=%f/%f, V=%f/%f, P=%f/%f, T=%f/%f, G=%f/%f\n", + xdop, dop->xdop, ydop, dop->ydop, hdop, dop->hdop, vdop, + dop->vdop, pdop, dop->pdop, tdop, dop->tdop, gdop, dop->gdop); +#endif + + /*@ -usedef @*/ + if (isnan(dop->xdop) != 0) { + dop->xdop = xdop; + } + if (isnan(dop->ydop) != 0) { + dop->ydop = ydop; + } + if (isnan(dop->hdop) != 0) { + dop->hdop = hdop; + } + if (isnan(dop->vdop) != 0) { + dop->vdop = vdop; + } + if (isnan(dop->pdop) != 0) { + dop->pdop = pdop; + } + if (isnan(dop->tdop) != 0) { + dop->tdop = tdop; + } + if (isnan(dop->gdop) != 0) { + dop->gdop = gdop; + } + /*@ +usedef @*/ + + return DOP_IS; +} diff --git a/gpxlogger.c b/gpxlogger.c new file mode 100644 index 0000000..b9cb578 --- /dev/null +++ b/gpxlogger.c @@ -0,0 +1,417 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include "gpsd_config.h" +#include +#include +#include +#ifdef HAVE_SYSLOG_H +#include +#endif /* HAVE_SYSLOG_H */ +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include "gps.h" +#include "gpsdclient.h" +#include "revision.h" + +#ifdef S_SPLINT_S +extern struct tm *gmtime_r(const time_t *, /*@out@*/ struct tm *tp); +#endif /* S_SPLINT_S */ + +/************************************************************************** + * + * Transport-layer-independent functions + * + **************************************************************************/ + +static char *author = "Amaury Jacquot, Chris Kuethe"; +static char *license = "BSD"; +static char *progname; + +static time_t int_time, old_int_time; +static bool intrack = false; +static bool first = true; +static time_t timeout = 5; /* seconds */ +#ifdef CLIENTDEBUG_ENABLE +static int debug; +#endif /* CLIENTDEBUG_ENABLE */ + +static void print_gpx_header(void) +{ + (void)printf("\n"); + (void)printf("\n"); + (void)printf(" \n"); + (void)printf(" NavSys GPS logger dump\n"); + (void)printf(" %s\n", author); + (void)printf(" %s\n", license); + (void)printf(" \n"); + (void)fflush(stdout); +} + +static void print_gpx_trk_end(void) +{ + (void)printf(" \n"); + (void)printf(" \n"); + (void)fflush(stdout); +} + +static void print_gpx_footer(void) +{ + if (intrack) + print_gpx_trk_end(); + (void)printf("\n"); + (void)fclose(stdout); +} + +static void print_gpx_trk_start(void) +{ + (void)printf(" \n"); + (void)printf(" \n"); + (void)fflush(stdout); +} + +static void print_fix(struct gps_fix_t *fix, struct tm *time) +{ + (void)printf(" \n", + fix->latitude, fix->longitude); + (void)printf(" %f\n", fix->altitude); + (void)printf(" \n", + time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, + time->tm_hour, time->tm_min, time->tm_sec); + if (fix->mode == MODE_NO_FIX) + (void)fprintf(stdout, " none\n"); + else + (void)fprintf(stdout, " %dd\n", fix->mode); +#if 0 + /* + * Can't print this more detailed report because in D-Bus mode + * we don't necessarily have access to some of the stuff in gsdata. + * Might mean some of this stuff should be promoted. + */ + if ((gpsdata->status >= 2) && (gpsdata->fix.mode >= MODE_3D)) { + /* dgps or pps */ + if (gpsdata->fix.mode == 4) { /* military pps */ + (void)printf(" pps\n"); + } else { /* civilian dgps or sbas */ + (void)printf(" dgps\n"); + } + } else { /* no dgps or pps */ + if (gpsdata->fix.mode == MODE_3D) { + (void)printf(" 3d\n"); + } else if (gpsdata->fix.mode == MODE_2D) { + (void)printf(" 2d\n"); + } else if (gpsdata->fix.mode == MODE_NOFIX) { + (void)printf(" none\n"); + } /* don't print anything if no fix indicator */ + } + + /* print # satellites used in fix, if reasonable to do so */ + if (gpsdata->fix.mode >= MODE_2D) { + (void)printf(" %.1f\n", gpsdata->hdop); + (void)printf(" %d\n", gpsdata->satellites_used); + } +#endif + + (void)printf(" \n"); + (void)fflush(stdout); +} + +static void conditionally_log_fix(struct gps_fix_t *gpsfix) +{ + int_time = (time_t) floor(gpsfix->time); + if ((int_time != old_int_time) && gpsfix->mode >= MODE_2D) { + struct tm time; + /* + * Make new track if the jump in time is above + * timeout. Handle jumps both forward and + * backwards in time. The clock sometimes jumps + * backward when gpsd is submitting junk on the + * dbus. + */ + /*@-type@*/ + if (fabs(int_time - old_int_time) > timeout && !first) { + print_gpx_trk_end(); + intrack = false; + } + /*@+type@*/ + + if (!intrack) { + print_gpx_trk_start(); + intrack = true; + if (first) + first = false; + } + + old_int_time = int_time; + (void)gmtime_r(&(int_time), &time); + print_fix(gpsfix, &time); + } +} + +static void quit_handler(int signum) +{ + /* don't clutter the logs on Ctrl-C */ + if (signum != SIGINT) + syslog(LOG_INFO, "exiting, signal %d received", signum); + print_gpx_footer(); + exit(0); +} + +static struct gps_fix_t gpsfix; + +#ifdef DBUS_ENABLE +/************************************************************************** + * + * Doing it with D-Bus + * + **************************************************************************/ + +#include +#include +#include +#include + +#include + +#define EMIX(x, y) (((x) > (y)) ? (x) : (y)) + +DBusConnection *connection; + +static char gpsd_devname[BUFSIZ]; + +static DBusHandlerResult handle_gps_fix(DBusMessage * message) +{ + DBusError error; + /* this packet format was designed before we split eph */ + double eph = EMIX(gpsfix.epx, gpsfix.epy); + + dbus_error_init(&error); + + dbus_message_get_args(message, + &error, + DBUS_TYPE_DOUBLE, &gpsfix.time, + DBUS_TYPE_INT32, &gpsfix.mode, + DBUS_TYPE_DOUBLE, &gpsfix.ept, + DBUS_TYPE_DOUBLE, &gpsfix.latitude, + DBUS_TYPE_DOUBLE, &gpsfix.longitude, + DBUS_TYPE_DOUBLE, &eph, + DBUS_TYPE_DOUBLE, &gpsfix.altitude, + DBUS_TYPE_DOUBLE, &gpsfix.epv, + DBUS_TYPE_DOUBLE, &gpsfix.track, + DBUS_TYPE_DOUBLE, &gpsfix.epd, + DBUS_TYPE_DOUBLE, &gpsfix.speed, + DBUS_TYPE_DOUBLE, &gpsfix.eps, + DBUS_TYPE_DOUBLE, &gpsfix.climb, + DBUS_TYPE_DOUBLE, &gpsfix.epc, + DBUS_TYPE_STRING, &gpsd_devname, DBUS_TYPE_INVALID); + + conditionally_log_fix(&gpsfix); + return DBUS_HANDLER_RESULT_HANDLED; +} + +/* + * Message dispatching function + * + */ +static DBusHandlerResult signal_handler(DBusConnection * connection, + DBusMessage * message) +{ + /* dummy, need to use the variable for some reason */ + connection = NULL; + + if (dbus_message_is_signal(message, "org.gpsd", "fix")) + return handle_gps_fix(message); + /* + * ignore all other messages + */ + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static int dbus_mainloop(void) +{ + GMainLoop *mainloop; + DBusError error; + + mainloop = g_main_loop_new(NULL, FALSE); + + dbus_error_init(&error); + connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (dbus_error_is_set(&error)) { + syslog(LOG_CRIT, "%s: %s", error.name, error.message); + return 3; + } + + dbus_bus_add_match(connection, "type='signal'", &error); + if (dbus_error_is_set(&error)) { + syslog(LOG_CRIT, "unable to add match for signals %s: %s", error.name, + error.message); + return 4; + } + + if (!dbus_connection_add_filter + (connection, (DBusHandleMessageFunction) signal_handler, NULL, + NULL)) { + syslog(LOG_CRIT, "unable to register filter with the connection"); + return 5; + } + + dbus_connection_setup_with_g_main(connection, NULL); + + g_main_loop_run(mainloop); + return 0; +} + +#endif /* DBUS_ENABLE */ + +/************************************************************************** + * + * Doing it with sockets + * + **************************************************************************/ + +static struct fixsource_t source; + +static void process(struct gps_data_t *gpsdata, + char *buf UNUSED, size_t len UNUSED) +{ + /* this is where we implement source-device filtering */ + if (gpsdata->dev.path[0] != '\0' && source.device != NULL + && strcmp(source.device, gpsdata->dev.path) != 0) + return; + + conditionally_log_fix(&gpsdata->fix); +} + +/*@-mustfreefresh -compdestroy@*/ +static int socket_mainloop(void) +{ + fd_set fds; + struct gps_data_t gpsdata; + + if (gps_open_r(source.server, source.port, &gpsdata) != 0) { + (void)fprintf(stderr, + "%s: no gpsd running or network error: %d, %s\n", + progname, errno, gps_errstr(errno)); + exit(1); + } + + gps_set_raw_hook(&gpsdata, process); + (void)gps_stream(&gpsdata, WATCH_ENABLE, NULL); + + for (;;) { + int data; + struct timeval tv; + + FD_ZERO(&fds); + FD_SET(gpsdata.gps_fd, &fds); + + tv.tv_usec = 250000; + tv.tv_sec = 0; + data = select(gpsdata.gps_fd + 1, &fds, NULL, NULL, &tv); + + if (data == -1) { + (void)fprintf(stderr, "%s\n", strerror(errno)); + break; + } else if (data) + (void)gps_read(&gpsdata); + } + (void)gps_close(&gpsdata); + return 0; +} +/*@+mustfreefresh +compdestroy@*/ + +/************************************************************************** + * + * Main sequence + * + **************************************************************************/ + +static void usage(void) +{ + fprintf(stderr, + "Usage: %s [-V] [-h] [-i timeout] [-j casoc] [server[:port:[device]]]\n", + progname); + fprintf(stderr, + "\tdefaults to '%s -i 5 -j 0 localhost:2947'\n", progname); + exit(1); +} + +int main(int argc, char **argv) +{ + int ch; + + progname = argv[0]; + while ((ch = getopt(argc, argv, "D:hi:V")) != -1) { + switch (ch) { +#ifdef CLIENTDEBUG_ENABLE + case 'D': + debug = atoi(optarg); + gps_enable_debug(debug, stdout); + break; +#endif /* CLIENTDEBUG_ENABLE */ + case 'i': /* set polling interfal */ + timeout = (time_t) atoi(optarg); + if (timeout < 1) + timeout = 1; + if (timeout >= 3600) + fprintf(stderr, + "WARNING: track timeout is an hour or more!\n"); + break; + case 'V': + (void)fprintf(stderr, "gpxlogger revision " REVISION "\n"); + exit(0); + default: + usage(); + /* NOTREACHED */ + } + } + + if (optind < argc) { + gpsd_source_spec(argv[optind], &source); + } else + gpsd_source_spec(NULL, &source); +#if 0 + (void)printf("\n", + source.server, source.port, source.device); +#endif + + /* initializes the gpsfix data structure */ + gps_clear_fix(&gpsfix); + + /* catch all interesting signals */ + (void)signal(SIGTERM, quit_handler); + (void)signal(SIGQUIT, quit_handler); + (void)signal(SIGINT, quit_handler); + + //openlog ("gpxlogger", LOG_PID | LOG_NDELAY , LOG_DAEMON); + //syslog (LOG_INFO, "---------- STARTED ----------"); + + print_gpx_header(); + +#ifdef DBUS_ENABLE + /* To force socket use in the default way just give a 'localhost' arg */ + if (optind < argc) + return socket_mainloop(); + else + return dbus_mainloop(); +#else + return socket_mainloop(); +#endif +} diff --git a/hex.c b/hex.c new file mode 100644 index 0000000..7a7a233 --- /dev/null +++ b/hex.c @@ -0,0 +1,272 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include + +#include "gpsd.h" + +int gpsd_hexdump_level = -1; +/* + * A wrapper around gpsd_hexdump to prevent wasting cpu time by hexdumping + * buffers and copying strings that will never be printed. only messages at + * level "N" and lower will be printed. By way of example, without any -D + * options, gpsd probably won't ever call the real gpsd_hexdump. At -D2, + * LOG_PROG (and higher) won't get to call the real gpsd_hexdump. For high + * speed, chatty protocols, this can save a lot of CPU. + */ +char *gpsd_hexdump_wrapper(const void *binbuf, size_t binbuflen, + int msg_debug_level) +{ +#ifndef SQUELCH_ENABLE + if (msg_debug_level <= gpsd_hexdump_level) + return gpsd_hexdump(binbuf, binbuflen); +#endif /* SQUELCH_ENABLE */ + return ""; +} + +char /*@ observer @*/ *gpsd_hexdump(const void *binbuf, size_t binbuflen) +{ + static char hexbuf[MAX_PACKET_LENGTH * 2 + 1]; +#ifndef SQUELCH_ENABLE + size_t i, j = 0; + size_t len = + (size_t) ((binbuflen > + MAX_PACKET_LENGTH) ? MAX_PACKET_LENGTH : binbuflen); + const char *ibuf = (const char *)binbuf; + const char *hexchar = "0123456789abcdef"; + + if (NULL == binbuf || 0 == binbuflen) + return ""; + + /*@ -shiftimplementation @*/ + for (i = 0; i < len; i++) { + hexbuf[j++] = hexchar[(ibuf[i] & 0xf0) >> 4]; + hexbuf[j++] = hexchar[ibuf[i] & 0x0f]; + } + /*@ +shiftimplementation @*/ + hexbuf[j] = '\0'; +#else /* SQUELCH defined */ + hexbuf[0] = '\0'; +#endif /* SQUELCH_ENABLE */ + return hexbuf; +} + +int gpsd_hexpack( /*@in@*/ const char *src, /*@out@ */ char *dst, size_t len) +{ +/* hex2bin source string to destination - destination can be same as source */ + int i, k, l; + + /*@ -mustdefine @*/ + l = (int)(strlen(src) / 2); + if ((l < 1) || ((size_t) l > len)) + return -2; + + for (i = 0; i < l; i++) + if ((k = hex2bin(src + i * 2)) != -1) + dst[i] = (char)(k & 0xff); + else + return -1; + (void)memset(dst + i, '\0', (size_t) (len - i)); + return l; + /*@ +mustdefine @*/ +} + +/*@ +charint -shiftimplementation @*/ +int hex2bin(const char *s) +{ + int a, b; + + a = s[0] & 0xff; + b = s[1] & 0xff; + + if ((a >= 'a') && (a <= 'f')) + a = a + 10 - 'a'; + else if ((a >= 'A') && (a <= 'F')) + a = a + 10 - 'A'; + else if ((a >= '0') && (a <= '9')) + a -= '0'; + else + return -1; + + if ((b >= 'a') && (b <= 'f')) + b = b + 10 - 'a'; + else if ((b >= 'A') && (b <= 'F')) + b = b + 10 - 'A'; + else if ((b >= '0') && (b <= '9')) + b -= '0'; + else + return -1; + + return ((a << 4) + b); +} + +/*@ -charint +shiftimplementation @*/ + +ssize_t hex_escapes( /*@out@*/ char *cooked, const char *raw) +/* interpret C-style hex escapes */ +{ + char c, *cookend; + + /*@ +charint -mustdefine -compdef @*/ + for (cookend = cooked; *raw != '\0'; raw++) + if (*raw != '\\') + *cookend++ = *raw; + else { + switch (*++raw) { + case 'b': + *cookend++ = '\b'; + break; + case 'e': + *cookend++ = '\x1b'; + break; + case 'f': + *cookend++ = '\f'; + break; + case 'n': + *cookend++ = '\n'; + break; + case 'r': + *cookend++ = '\r'; + break; + case 't': + *cookend++ = '\r'; + break; + case 'v': + *cookend++ = '\v'; + break; + case 'x': + switch (*++raw) { + case '0': + c = (char)0x00; + break; + case '1': + c = (char)0x10; + break; + case '2': + c = (char)0x20; + break; + case '3': + c = (char)0x30; + break; + case '4': + c = (char)0x40; + break; + case '5': + c = (char)0x50; + break; + case '6': + c = (char)0x60; + break; + case '7': + c = (char)0x70; + break; + case '8': + c = (char)0x80; + break; + case '9': + c = (char)0x90; + break; + case 'A': + case 'a': + c = (char)0xa0; + break; + case 'B': + case 'b': + c = (char)0xb0; + break; + case 'C': + case 'c': + c = (char)0xc0; + break; + case 'D': + case 'd': + c = (char)0xd0; + break; + case 'E': + case 'e': + c = (char)0xe0; + break; + case 'F': + case 'f': + c = (char)0xf0; + break; + default: + return -1; + } + switch (*++raw) { + case '0': + c += 0x00; + break; + case '1': + c += 0x01; + break; + case '2': + c += 0x02; + break; + case '3': + c += 0x03; + break; + case '4': + c += 0x04; + break; + case '5': + c += 0x05; + break; + case '6': + c += 0x06; + break; + case '7': + c += 0x07; + break; + case '8': + c += 0x08; + break; + case '9': + c += 0x09; + break; + case 'A': + case 'a': + c += 0x0a; + break; + case 'B': + case 'b': + c += 0x0b; + break; + case 'C': + case 'c': + c += 0x0c; + break; + case 'D': + case 'd': + c += 0x0d; + break; + case 'E': + case 'e': + c += 0x0e; + break; + case 'F': + case 'f': + c += 0x0f; + break; + default: + return -2; + } + *cookend++ = c; + break; + case '\\': + *cookend++ = '\\'; + break; + default: + return -3; + } + } + return (ssize_t) (cookend - cooked); + /*@ +charint +mustdefine +compdef @*/ +} diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..6781b98 --- /dev/null +++ b/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/isgps.c b/isgps.c new file mode 100644 index 0000000..db13d43 --- /dev/null +++ b/isgps.c @@ -0,0 +1,319 @@ +/***************************************************************************** + +This is a decoder for the unnamed protocol described in IS-GPS-200, +the Navstar GPS Interface Specification, and used as a transport layer +for both GPS satellite downlink transmissions and the RTCM104 version 2 +format for broadcasting differential-GPS corrections. + +The purpose of this protocol is to support analyzing a serial bit +stream without byte framing into parity-checked packets. +Interpretation of the packets is left to an upper layer. Note that +RTCM104 version 3 does *not* use this code; it assumes a byte-oriented +underlayer. + +The upper layer must supply a preamble_match() hook to tell our +decoder when it has a legitimate start of packet, and a length_check() +hook to tell it when the packet has reached the length it is supposed +to have. + +Here are Wolfgang's original rather cryptic notes on this code: + +-------------------------------------------------------------------------- +1) trim and bitflip the input. + +While syncing the msb of the input gets shifted into lsb of the +assembled word. + word <<= 1, or in input >> 5 + word <<= 1, or in input >> 4 + word <<= 1, or in input >> 3 + word <<= 1, or in input >> 2 + word <<= 1, or in input >> 1 + word <<= 1, or in input + +At one point it should sync-lock. + +---- + +Shift 6 bytes of RTCM data in as such: + +---> (trim-bits-to-5-bits) ---> (end-for-end-bit-flip) ---> + +---> shift-into-30-bit-shift-register + ||||||||||||||||||||||| + detector-for-preamble + ||||||||||||||||||||||| + detector-for-parity + ||||||||||||||||||||||| +-------------------------------------------------------------------------- + +The code was originally by Wolfgang Rupprecht. ESR severely hacked +it, with Wolfgang's help, in order to separate message analysis from +message dumping and separate this lower layer from the upper layer +handing GPS and RTCM decoding. + +You are not expected to understand any of this. + +This file is Copyright (c) 2010 by the GPSD project +BSD terms apply: see the file COPYING in the distribution root for details. + +*****************************************************************************/ + +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd.h" + +#define MAG_SHIFT 6u +#define MAG_TAG_DATA (1 << MAG_SHIFT) +#define MAG_TAG_MASK (3 << MAG_SHIFT) + +#define W_DATA_MASK 0x3fffffc0u + +/*@ +charint @*/ +static unsigned char parity_array[] = { + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 +}; + +static unsigned int reverse_bits[] = { + 0, 32, 16, 48, 8, 40, 24, 56, 4, 36, 20, 52, 12, 44, 28, 60, + 2, 34, 18, 50, 10, 42, 26, 58, 6, 38, 22, 54, 14, 46, 30, 62, + 1, 33, 17, 49, 9, 41, 25, 57, 5, 37, 21, 53, 13, 45, 29, 61, + 3, 35, 19, 51, 11, 43, 27, 59, 7, 39, 23, 55, 15, 47, 31, 63 +}; + +/*@ -charint @*/ + +unsigned int isgps_parity(isgps30bits_t th) +{ +#define P_30_MASK 0x40000000u + +#define PARITY_25 0xbb1f3480u +#define PARITY_26 0x5d8f9a40u +#define PARITY_27 0xaec7cd00u +#define PARITY_28 0x5763e680u +#define PARITY_29 0x6bb1f340u +#define PARITY_30 0x8b7a89c0u + isgps30bits_t t; + unsigned int p; + + /* + * if (th & P_30_MASK) + * th ^= W_DATA_MASK; + */ + + /*@ +charint @*/ + t = th & PARITY_25; + p = parity_array[t & 0xff] ^ parity_array[(t >> 8) & 0xff] ^ + parity_array[(t >> 16) & 0xff] ^ parity_array[(t >> 24) & 0xff]; + t = th & PARITY_26; + p = (p << 1) | (parity_array[t & 0xff] ^ parity_array[(t >> 8) & 0xff] ^ + parity_array[(t >> 16) & 0xff] ^ parity_array[(t >> 24) & + 0xff]); + t = th & PARITY_27; + p = (p << 1) | (parity_array[t & 0xff] ^ parity_array[(t >> 8) & 0xff] ^ + parity_array[(t >> 16) & 0xff] ^ parity_array[(t >> 24) & + 0xff]); + t = th & PARITY_28; + p = (p << 1) | (parity_array[t & 0xff] ^ parity_array[(t >> 8) & 0xff] ^ + parity_array[(t >> 16) & 0xff] ^ parity_array[(t >> 24) & + 0xff]); + t = th & PARITY_29; + p = (p << 1) | (parity_array[t & 0xff] ^ parity_array[(t >> 8) & 0xff] ^ + parity_array[(t >> 16) & 0xff] ^ parity_array[(t >> 24) & + 0xff]); + t = th & PARITY_30; + p = (p << 1) | (parity_array[t & 0xff] ^ parity_array[(t >> 8) & 0xff] ^ + parity_array[(t >> 16) & 0xff] ^ parity_array[(t >> 24) & + 0xff]); + /*@ -charint @*/ + + gpsd_report(ISGPS_ERRLEVEL_BASE + 2, "ISGPS parity %u\n", p); + return (p); +} + +/* + * ESR found a doozy of a bug... + * + * Defining isgps_parityok as a function triggers an optimizer bug in gcc + * 3.4.2. The symptom is that parity computation is screwed up and the decoder + * never achieves sync lock. Something steps on the argument to + * isgpsparity(); the lossage appears to be related to the compiler's + * attempt to fold the isgps_parity() call into isgps_parityok() in some + * tail-recursion-like manner. This happens under -O2, but not -O1, on + * both i386 and amd64. Disabling all of the individual -O2 suboptions + * does *not* fix it. + * + * And the fun doesn't stop there! It turns out that even with this fix, bare + * -O2 generates bad code. It takes "-O2 -fschedule-insns" to generate good + * code under 3.4.[23]...which is weird because -O2 is supposed to *imply* + * -fschedule-insns. + * + * gcc 4.0 does not manifest these bugs. + */ +#define isgps_parityok(w) (isgps_parity(w) == ((w) & 0x3f)) + +void isgps_init( /*@out@*/ struct gps_packet_t *session) +{ + session->isgps.curr_word = 0; + session->isgps.curr_offset = 24; /* first word */ + session->isgps.locked = false; + session->isgps.bufindex = 0; +} + +/*@ -usereleased -compdef @*/ +enum isgpsstat_t isgps_decode(struct gps_packet_t *session, + bool(*preamble_match) (isgps30bits_t *), + bool(*length_check) (struct gps_packet_t *), + size_t maxlen, unsigned int c) +{ + enum isgpsstat_t res; + + /* ASCII characters 64-127, @ through DEL */ + if ((c & MAG_TAG_MASK) != MAG_TAG_DATA) { + gpsd_report(ISGPS_ERRLEVEL_BASE + 1, + "ISGPS word tag not correct, skipping byte\n"); + return ISGPS_SKIP; + } + + c = reverse_bits[c & 0x3f]; + + /*@ -shiftnegative @*/ + if (!session->isgps.locked) { + session->isgps.curr_offset = -5; + session->isgps.bufindex = 0; + + while (session->isgps.curr_offset <= 0) { + session->isgps.curr_word <<= 1; + if (session->isgps.curr_offset > 0) { + session->isgps.curr_word |= c << session->isgps.curr_offset; + } else { + session->isgps.curr_word |= + c >> -(session->isgps.curr_offset); + } + gpsd_report(ISGPS_ERRLEVEL_BASE + 2, + "ISGPS syncing at byte %lu: 0x%08x\n", + session->char_counter, session->isgps.curr_word); + + if (preamble_match(&session->isgps.curr_word)) { + if (isgps_parityok(session->isgps.curr_word)) { + gpsd_report(ISGPS_ERRLEVEL_BASE + 1, + "ISGPS preamble ok, parity ok -- locked\n"); + session->isgps.locked = true; + break; + } + gpsd_report(ISGPS_ERRLEVEL_BASE + 1, + "ISGPS preamble ok, parity fail\n"); + } + session->isgps.curr_offset++; + } /* end while */ + } + if (session->isgps.locked) { + res = ISGPS_SYNC; + + if (session->isgps.curr_offset > 0) { + session->isgps.curr_word |= c << session->isgps.curr_offset; + } else { + session->isgps.curr_word |= c >> -(session->isgps.curr_offset); + } + + if (session->isgps.curr_offset <= 0) { + /* weird-assed inversion */ + if (session->isgps.curr_word & P_30_MASK) + session->isgps.curr_word ^= W_DATA_MASK; + + if (isgps_parityok(session->isgps.curr_word)) { +#if 0 + /* + * Don't clobber the buffer just because we spot + * another preamble pattern in the data stream. -wsr + */ + if (preamble_match(&session->isgps.curr_word)) { + gpsd_report(ISGPS_ERRLEVEL_BASE + 2, + "ISGPS preamble spotted (index: %u)\n", + session->isgps.bufindex); + session->isgps.bufindex = 0; + } +#endif + gpsd_report(ISGPS_ERRLEVEL_BASE + 2, + "ISGPS processing word %u (offset %d)\n", + session->isgps.bufindex, + session->isgps.curr_offset); + { + /* + * Guard against a buffer overflow attack. Just wait for + * the next preamble match and go on from there. + */ + if (session->isgps.bufindex >= (unsigned)maxlen) { + session->isgps.bufindex = 0; + gpsd_report(ISGPS_ERRLEVEL_BASE + 1, + "ISGPS buffer overflowing -- resetting\n"); + return ISGPS_NO_SYNC; + } + + session->isgps.buf[session->isgps.bufindex] = + session->isgps.curr_word; + + /* *INDENT-OFF* */ + if ((session->isgps.bufindex == 0) && + !preamble_match((isgps30bits_t *) session->isgps.buf)) { + gpsd_report(ISGPS_ERRLEVEL_BASE + 1, + "ISGPS word 0 not a preamble- punting\n"); + return ISGPS_NO_SYNC; + } + /* *INDENT-ON* */ + session->isgps.bufindex++; + + if (length_check(session)) { + /* jackpot, we have a complete packet */ + session->isgps.bufindex = 0; + res = ISGPS_MESSAGE; + } + } + session->isgps.curr_word <<= 30; /* preserve the 2 low bits */ + session->isgps.curr_offset += 30; + if (session->isgps.curr_offset > 0) { + session->isgps.curr_word |= + c << session->isgps.curr_offset; + } else { + session->isgps.curr_word |= + c >> -(session->isgps.curr_offset); + } + } else { + gpsd_report(ISGPS_ERRLEVEL_BASE + 0, + "ISGPS parity failure, lost lock\n"); + session->isgps.locked = false; + } + } + session->isgps.curr_offset -= 6; + gpsd_report(ISGPS_ERRLEVEL_BASE + 2, "ISGPS residual %d\n", + session->isgps.curr_offset); + return res; + } + /*@ +shiftnegative @*/ + + /* never achieved lock */ + gpsd_report(ISGPS_ERRLEVEL_BASE + 1, "ISGPS lock never achieved\n"); + return ISGPS_NO_SYNC; +} + +/*@ +usereleased +compdef @*/ diff --git a/json.c b/json.c new file mode 100644 index 0000000..27f39a2 --- /dev/null +++ b/json.c @@ -0,0 +1,593 @@ +/**************************************************************************** + +NAME + json.c - parse JSON into fixed-extent data structures + +DESCRIPTION + This module parses a large subset of JSON (JavaScript Object +Notation). Unlike more general JSON parsers, it doesn't use malloc(3) +and doesn't support polymorphism; you need to give it a set of +template structures describing the expected shape of the incoming +JSON, and it will error out if that shape is not matched. When the +parse succeds, attribute values will be extracted into static +locations specified in the template structures. + + The "shape" of a JSON object in the type signature of its +attributes (and attribute values, and so on recursively down through +all nestings of objects and arrays). This parser is indifferent to +the order of attributes at any level, but you have to tell it in +advance what the type of each attribute value will be and where the +parsed value will be stored. The template structures may supply +default values to be used when an expected attribute is omitted. + + The dialect this parses has some limitations. First, it cannot +recognize the JSON "null" value. Secondly, arrays may only have +objects or strings - not reals or integers or floats - as elements +(this limitation could be easily removed if required). Third, all +elements of an array must be of the same type. + + There are separata entry points for beginning a parse of either +JSON object or a JSON array. JSON "float" quantities are actually +stored as doubles. + + This parser processes object arrays in one of two different ways, +defending on whether the array subtype is declared as object or +structobject. + + Object arrays take one base address per object subfield, and are +mapped into parallel C arrays (one per subfield). Strings are not +supported in this kind of array, as the don't have a "natural" size +to use as an offset multiplier. + + Structobjects arrays are a way to parse a list of objects to a set +of modifications to a corresponding array of C structs. The trick is +that the array object initialization has to specify both the C struct +array's base address and the stride length (the size of the C struct). +If you initialize the offset fields with the correct offsetof() calls, +everything will work. Strings are suppported but all string storage +has to be inline in the struct. + +PERMISSIONS + This file is Copyright (c) 2010 by the GPSD project + BSD terms apply: see the file COPYING in the distribution root for details. + +***************************************************************************/ +#include +#include +#include +#include + +#include "gpsd_config.h" /* for strlcpy() prototype */ +#include "json.h" + +#ifdef CLIENTDEBUG_ENABLE +static int debuglevel = 0; +static FILE *debugfp; + +void json_enable_debug(int level, FILE * fp) +/* control the level and destination of debug trace messages */ +{ + debuglevel = level; + debugfp = fp; +} + +static void json_trace(int errlevel, const char *fmt, ...) +/* assemble command in printf(3) style */ +{ + if (errlevel <= debuglevel) { + char buf[BUFSIZ]; + va_list ap; + + (void)strlcpy(buf, "json: ", BUFSIZ); + va_start(ap, fmt); + (void)vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, + ap); + va_end(ap); + + (void)fputs(buf, debugfp); + } +} + +# define json_debug_trace(args) (void) json_trace args +#else +# define json_debug_trace(args) /*@i1@*/do { } while (0) +#endif /* CLIENTDEBUG_ENABLE */ + +/*@-immediatetrans -dependenttrans -usereleased -compdef@*/ +static /*@null@*/ char *json_target_address(const struct json_attr_t *cursor, + /*@null@*/ + const struct json_array_t + *parent, int offset) +{ + char *targetaddr = NULL; + if (parent == NULL || parent->element_type != t_structobject) { + /* ordinary case - use the address in the cursor structure */ + switch (cursor->type) { + case t_integer: + targetaddr = (char *)&cursor->addr.integer[offset]; + break; + case t_uinteger: + targetaddr = (char *)&cursor->addr.uinteger[offset]; + break; + case t_real: + targetaddr = (char *)&cursor->addr.real[offset]; + break; + case t_string: + targetaddr = cursor->addr.string; + break; + case t_boolean: + targetaddr = (char *)&cursor->addr.boolean[offset]; + break; + case t_character: + targetaddr = (char *)&cursor->addr.character[offset]; + break; + default: + targetaddr = NULL; + break; + } + } else + /* tricky case - hacking a member in an array of structures */ + targetaddr = + parent->arr.objects.base + (offset * parent->arr.objects.stride) + + cursor->addr.offset; + json_debug_trace((1, "Target address for %s (offset %d) is %p\n", + cursor->attribute, offset, targetaddr)); + return targetaddr; +} + +/*@-immediatetrans -dependenttrans +usereleased +compdef@*/ + +static int json_internal_read_object(const char *cp, + const struct json_attr_t *attrs, + /*@null@*/ + const struct json_array_t *parent, + int offset, + /*@null@*/ const char **end) +{ + /*@ -nullstate -nullderef -mustfreefresh -nullpass -usedef @*/ + enum + { init, await_attr, in_attr, await_value, in_val_string, + in_escape, in_val_token, post_val, post_array + } state = 0; +#ifdef CLIENTDEBUG_ENABLE + char *statenames[] = { + "init", "await_attr", "in_attr", "await_value", "in_val_string", + "in_escape", "in_val_token", "post_val", "post_array", + }; +#endif /* CLIENTDEBUG_ENABLE */ + char attrbuf[JSON_ATTR_MAX + 1], *pattr = NULL; + char valbuf[JSON_VAL_MAX + 1], *pval = NULL; + bool value_quoted = false; + char uescape[5]; /* enough space for 4 hex digits and a NUL */ + const struct json_attr_t *cursor; + int substatus, n, maxlen = 0; + unsigned int u; + const struct json_enum_t *mp; + char *lptr; + +#ifdef S_SPLINT_S + /* prevents gripes about buffers not being completely defined */ + memset(valbuf, '\0', sizeof(valbuf)); + memset(attrbuf, '\0', sizeof(attrbuf)); +#endif /* S_SPLINT_S */ + + if (end != NULL) + *end = NULL; /* give it a well-defined value on parse failure */ + + /* stuff fields with defaults in case they're omitted in the JSON input */ + for (cursor = attrs; cursor->attribute != NULL; cursor++) + if (!cursor->nodefault) { + lptr = json_target_address(cursor, parent, offset); + if (lptr != NULL) + switch (cursor->type) { + case t_integer: + *((int *)lptr) = cursor->dflt.integer; + break; + case t_uinteger: + *((unsigned int *)lptr) = cursor->dflt.uinteger; + break; + case t_real: + *((double *)lptr) = cursor->dflt.real; + break; + case t_string: + if (parent != NULL + && parent->element_type != t_structobject + && offset > 0) + return JSON_ERR_NOPARSTR; + lptr[0] = '\0'; + break; + case t_boolean: + /* nullbool default says not to set the value at all */ + /*@+boolint@*/ + if (cursor->dflt.boolean != nullbool) + *((bool *) lptr) = cursor->dflt.boolean; + /*@-boolint@*/ + break; + case t_character: + lptr[0] = cursor->dflt.character; + break; + case t_object: /* silences a compiler warning */ + case t_structobject: + case t_array: + case t_check: + break; + } + } + + json_debug_trace((1, "JSON parse of '%s' begins.\n", cp)); + + /* parse input JSON */ + for (; *cp != '\0'; cp++) { + json_debug_trace((2, "State %-14s, looking at '%c' (%p)\n", + statenames[state], *cp, cp)); + switch (state) { + case init: + if (isspace(*cp)) + continue; + else if (*cp == '{') + state = await_attr; + else { + json_debug_trace((1, + "Non-WS when expecting object start.\n")); + return JSON_ERR_OBSTART; + } + break; + case await_attr: + if (isspace(*cp)) + continue; + else if (*cp == '"') { + state = in_attr; + pattr = attrbuf; + } else if (*cp == '}') + break; + else { + json_debug_trace((1, "Non-WS when expecting attribute.\n")); + return JSON_ERR_ATTRSTART; + } + break; + case in_attr: + if (*cp == '"') { + *pattr++ = '\0'; + json_debug_trace((1, "Collected attribute name %s\n", + attrbuf)); + for (cursor = attrs; cursor->attribute != NULL; cursor++) { + json_debug_trace((2, "Checking against %s\n", + cursor->attribute)); + if (strcmp(cursor->attribute, attrbuf) == 0) + break; + } + if (cursor->attribute == NULL) { + json_debug_trace((1, + "Unknown attribute name '%s' (attributes begin with '%s').\n", + attrbuf, attrs->attribute)); + return JSON_ERR_BADATTR; + } + state = await_value; + if (cursor->type == t_string) + maxlen = (int)cursor->len - 1; + else if (cursor->type == t_check) + maxlen = (int)strlen(cursor->dflt.check); + else if (cursor->map != NULL) + maxlen = (int)sizeof(valbuf) - 1; + pval = valbuf; + } else if (pattr >= attrbuf + JSON_ATTR_MAX - 1) { + json_debug_trace((1, "Attribute name too long.\n")); + return JSON_ERR_ATTRLEN; + } else + *pattr++ = *cp; + break; + case await_value: + if (isspace(*cp) || *cp == ':') + continue; + else if (*cp == '[') { + if (cursor->type != t_array) { + json_debug_trace((1, + "Saw [ when not expecting array.\n")); + return JSON_ERR_NOARRAY; + } + substatus = json_read_array(cp, &cursor->addr.array, &cp); + if (substatus != 0) + return substatus; + state = post_array; + } else if (cursor->type == t_array) { + json_debug_trace((1, + "Array element was specified, but no [.\n")); + return JSON_ERR_NOBRAK; + } else if (*cp == '"') { + value_quoted = true; + state = in_val_string; + pval = valbuf; + } else { + value_quoted = false; + state = in_val_token; + pval = valbuf; + *pval++ = *cp; + } + break; + case in_val_string: + if (*cp == '\\') + state = in_escape; + else if (*cp == '"') { + *pval++ = '\0'; + json_debug_trace((1, "Collected string value %s\n", valbuf)); + state = post_val; + } else if (pval > valbuf + JSON_VAL_MAX - 1 + || pval > valbuf + maxlen) { + json_debug_trace((1, "String value too long.\n")); + return JSON_ERR_STRLONG; /* */ + } else + *pval++ = *cp; + break; + case in_escape: + switch (*cp) { + case 'b': + *pval++ = '\b'; + break; + case 'f': + *pval++ = '\f'; + break; + case 'n': + *pval++ = '\n'; + break; + case 'r': + *pval++ = '\r'; + break; + case 't': + *pval++ = '\t'; + break; + case 'u': + for (n = 0; n < 4 && cp[n] != '\0'; n++) + uescape[n] = *cp++; + --cp; + (void)sscanf(uescape, "%04x", &u); + *pval++ = (char)u; /* will truncate values above 0xff */ + break; + default: /* handles double quote and solidus */ + *pval++ = *cp; + break; + } + state = in_val_string; + break; + case in_val_token: + if (isspace(*cp) || *cp == ',' || *cp == '}') { + *pval = '\0'; + json_debug_trace((1, "Collected token value %s.\n", valbuf)); + state = post_val; + if (*cp == '}' || *cp == ',') + --cp; + } else if (pval > valbuf + JSON_VAL_MAX - 1) { + json_debug_trace((1, "Token value too long.\n")); + return JSON_ERR_TOKLONG; + } else + *pval++ = *cp; + break; + case post_val: + if (value_quoted + && (cursor->type != t_string && cursor->type != t_character + && cursor->type != t_check && cursor->map == 0)) { + json_debug_trace((1, + "Saw quoted value when expecting non-string.\n")); + return JSON_ERR_QNONSTRING; + } + if (!value_quoted + && (cursor->type == t_string || cursor->type == t_check + || cursor->map != 0)) { + json_debug_trace((1, + "Didn't see quoted value when expecting string.\n")); + return JSON_ERR_NONQSTRING; + } + if (cursor->map != 0) { + for (mp = cursor->map; mp->name != NULL; mp++) + if (strcmp(mp->name, valbuf) == 0) { + goto foundit; + } + json_debug_trace((1, "Invalid enumerated value string %s.\n", + valbuf)); + return JSON_ERR_BADENUM; + foundit: + (void)snprintf(valbuf, sizeof(valbuf), "%d", mp->value); + } + lptr = json_target_address(cursor, parent, offset); + if (lptr != NULL) + switch (cursor->type) { + case t_integer: + *((int *)lptr) = atoi(valbuf); + break; + case t_uinteger: + *((unsigned int *)lptr) = (unsigned)atoi(valbuf); + break; + case t_real: + *((double *)lptr) = atof(valbuf); + break; + case t_string: + if (parent != NULL + && parent->element_type != t_structobject + && offset > 0) + return JSON_ERR_NOPARSTR; + (void)strncpy(lptr, valbuf, cursor->len); + break; + case t_boolean: + *((bool *) lptr) = (strcmp(valbuf, "true") == 0); + break; + case t_character: + if (strlen(valbuf) > 1) + return JSON_ERR_STRLONG; + else + lptr[0] = valbuf[0]; + break; + case t_object: /* silences a compiler warning */ + case t_structobject: + case t_array: + break; + case t_check: + if (strcmp(cursor->dflt.check, valbuf) != 0) { + json_debug_trace((1, + "Required attribute vakue %s not present.\n", + cursor->dflt.check)); + return JSON_ERR_CHECKFAIL; + } + break; + } + /*@fallthrough@*/ + case post_array: + if (isspace(*cp)) + continue; + else if (*cp == ',') + state = await_attr; + else if (*cp == '}') { + ++cp; + goto good_parse; + } else { + json_debug_trace((1, "Garbage while expecting comma or }\n")); + return JSON_ERR_BADTRAIL; + } + break; + } + } + + good_parse: + /* in case there's another object following, consune trailing WS */ + while (isspace(*cp)) + ++cp; + if (end != NULL) + *end = cp; + json_debug_trace((1, "JSON parse ends.\n")); + return 0; + /*@ +nullstate +nullderef +mustfreefresh +nullpass +usedef @*/ +} + +int json_read_array(const char *cp, const struct json_array_t *arr, + const char **end) +{ + /*@-nullstate -onlytrans@*/ + int substatus, offset; + char *tp; + + if (end != NULL) + *end = NULL; /* give it a well-defined value on parse failure */ + + json_debug_trace((1, "Entered json_read_array()\n")); + + while (isspace(*cp)) + cp++; + if (*cp != '[') { + json_debug_trace((1, "Didn't find expected array start\n")); + return JSON_ERR_ARRAYSTART; + } else + cp++; + + tp = arr->arr.strings.store; + if (arr->count != NULL) + *(arr->count) = 0; + for (offset = 0; offset < arr->maxlen; offset++) { + json_debug_trace((1, "Looking at %s\n", cp)); + switch (arr->element_type) { + case t_string: + if (isspace(*cp)) + cp++; + if (*cp != '"') + return JSON_ERR_BADSTRING; + else + ++cp; + arr->arr.strings.ptrs[offset] = tp; + for (; tp - arr->arr.strings.store < arr->arr.strings.storelen; + tp++) + if (*cp == '"') { + ++cp; + *tp++ = '\0'; + goto stringend; + } else if (*cp == '\0') { + json_debug_trace((1, + "Bad string syntax in string list.\n")); + return JSON_ERR_BADSTRING; + } else { + *tp = *cp++; + } + json_debug_trace((1, "Bad string syntax in string list.\n")); + return JSON_ERR_BADSTRING; + stringend: + break; + case t_object: + case t_structobject: + substatus = + json_internal_read_object(cp, arr->arr.objects.subtype, arr, + offset, &cp); + if (substatus != 0) + return substatus; + break; + case t_integer: + case t_uinteger: + case t_real: + case t_boolean: + case t_character: + case t_array: + case t_check: + json_debug_trace((1, "Invalid array subtype.\n")); + return JSON_ERR_SUBTYPE; + } + if (arr->count != NULL) + (*arr->count)++; + if (isspace(*cp)) + cp++; + if (*cp == ']') { + json_debug_trace((1, "End of array found.\n")); + goto breakout; + } else if (*cp == ',') + cp++; + else { + json_debug_trace((1, "Bad trailing syntax on array.\n")); + return JSON_ERR_BADSUBTRAIL; + } + } + json_debug_trace((1, "Too many elements in array.\n")); + return JSON_ERR_SUBTOOLONG; + breakout: + if (end != NULL) + *end = cp; + /*@ -nullderef @*/ + json_debug_trace((1, "leaving json_read_array() with %d elements\n", + *arr->count)); + /*@ +nullderef @*/ + return 0; + /*@+nullstate +onlytrans@*/ +} + +int json_read_object(const char *cp, const struct json_attr_t *attrs, + /*@null@*/ const char **end) +{ + json_debug_trace((1, "json_read_object() sees '%s'\n", cp)); + return json_internal_read_object(cp, attrs, NULL, 0, end); +} + +const /*@observer@*/ char *json_error_string(int err) +{ + const char *errors[] = { + "unknown error while parsing JSON", + "non-whitespace when expecting object start", + "non-whitespace when expecting attribute start", + "unknown attribute name", + "attribute name too long", + "saw [ when not expecting array", + "array element specified, but no [", + "string value too long", + "token value too long", + "garbage while expecting , or }", + "didn't find expected array start", + "error while parsing object array", + "too many array elements", + "garbage while expecting array comma", + "unsupported array element type", + "error while string parsing", + "check attribute not matched", + "can't support strings in parallel arrays", + "invalid enumerated value", + "saw quoted value when expecting nonstring", + "didn't see quoted value when expecting string", + "other data conversion error", + }; + + if (err <= 0 || err >= (int)(sizeof(errors) / sizeof(errors[0]))) + return errors[0]; + else + return errors[err]; +} diff --git a/json.h b/json.h new file mode 100644 index 0000000..6e48cdd --- /dev/null +++ b/json.h @@ -0,0 +1,123 @@ +/* Structures for JSON parsing using only fixed-extent memory + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#include +#include + +typedef enum {t_integer, t_uinteger, t_real, + t_string, t_boolean, t_character, + t_object, t_structobject, t_array, + t_check} json_type; + +#define nullbool -1 /* not true, not false */ + +struct json_enum_t { + char *name; + int value; +}; + +struct json_array_t { + json_type element_type; + union { + struct { + const struct json_attr_t *subtype; + char *base; + size_t stride; + } objects; + struct { + char **ptrs; + char *store; + int storelen; + } strings; + } arr; + int *count, maxlen; +}; + +struct json_attr_t { + char *attribute; + json_type type; + union { + int *integer; + unsigned int *uinteger; + double *real; + char *string; + bool *boolean; + char *character; + struct json_array_t array; + size_t offset; + } addr; + union { + int integer; + unsigned int uinteger; + double real; + bool boolean; + char character; + char *check; + } dflt; + size_t len; + const struct json_enum_t *map; + bool nodefault; +}; + +#define JSON_ATTR_MAX 31 /* max chars in JSON attribute name */ +#define JSON_VAL_MAX 120 /* max chars in JSON value part */ + +#ifdef __cplusplus +extern "C" { +#endif +int json_read_object(const char *, const struct json_attr_t *, + /*@null@*/const char **); +int json_read_array(const char *, const struct json_array_t *, + /*@null@*/const char **); +const /*@observer@*/char *json_error_string(int); + +void json_enable_debug(int, FILE *); +#ifdef __cplusplus +} +#endif + +#define JSON_ERR_OBSTART 1 /* non-WS when expecting object start */ +#define JSON_ERR_ATTRSTART 2 /* non-WS when expecting attrib start */ +#define JSON_ERR_BADATTR 3 /* unknown attribute name */ +#define JSON_ERR_ATTRLEN 4 /* attribute name too long */ +#define JSON_ERR_NOARRAY 5 /* saw [ when not expecting array */ +#define JSON_ERR_NOBRAK 6 /* array element specified, but no [ */ +#define JSON_ERR_STRLONG 7 /* string value too long */ +#define JSON_ERR_TOKLONG 8 /* token value too long */ +#define JSON_ERR_BADTRAIL 9 /* garbage while expecting , or } */ +#define JSON_ERR_ARRAYSTART 10 /* didn't find expected array start */ +#define JSON_ERR_OBJARR 11 /* error while parsing object array */ +#define JSON_ERR_SUBTOOLONG 12 /* too many array elements */ +#define JSON_ERR_BADSUBTRAIL 13 /* garbage while expecting array comma */ +#define JSON_ERR_SUBTYPE 14 /* unsupported array element type */ +#define JSON_ERR_BADSTRING 15 /* error while string parsing */ +#define JSON_ERR_CHECKFAIL 16 /* check attribute not matched */ +#define JSON_ERR_NOPARSTR 17 /* can't support strings in parallel arrays */ +#define JSON_ERR_BADENUM 18 /* invalid enumerated value */ +#define JSON_ERR_QNONSTRING 19 /* saw quoted value when expecting nonstring */ +#define JSON_ERR_NONQSTRING 19 /* didn't see quoted value when expecting string */ +#define JSON_ERR_MISC 20 /* other data conversion error */ + +/* + * Use the following macros to declare template initializers for structobject + * arrays. Writing the equivalents out by hand is error-prone. + * + * STRUCTOBJECT takes a structure name s, and a fieldname f in s. + * + * STRUCTARRAY takes the name of a structure array, a pointer to a an + * initializer defining the subobject type, and the address of an integer to + * store the length in. + */ +#define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f) +#define STRUCTARRAY(a, e, n) \ + .addr.array.element_type = t_structobject, \ + .addr.array.arr.objects.subtype = e, \ + .addr.array.arr.objects.base = (char*)a, \ + .addr.array.arr.objects.stride = sizeof(a[0]), \ + .addr.array.count = n, \ + .addr.array.maxlen = NITEMS(a) + +/* json.h ends here */ diff --git a/jsongen.py.in b/jsongen.py.in new file mode 100644 index 0000000..02795b8 --- /dev/null +++ b/jsongen.py.in @@ -0,0 +1,534 @@ +#!@PYTHON@ +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# Never hand-hack what you can generate... +# +# This code generates template declarations for AIS-JSON parsing from a +# declarative specification of a JSON structure - and generates those +# declarative specification from the Python format strings for +# dumping the structures +# +import sys, getopt + +# +# Here is the information that makes it all work - attribute, type, and +# defult information for all fields. We can generate either a JSON +# parser template spec or the C code for the correspondong dump functio +# from this information. Doing it this way guarantees consistency. +# +ais_specs = ( + { + "initname" : "json_ais1", + "header": "\tAIS_HEADER,", + "structname": "ais->type1", + "fieldmap":( + # fieldname type default + ('status', 'uinteger', '0'), + ('turn', 'integer', 'AIS_TURN_NOT_AVAILABLE'), + ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'), + ('accuracy', 'boolean', 'false'), + ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), + ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), + ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'), + ('heading', 'uinteger', 'AIS_HEADING_NOT_AVAILABLE'), + ('second', 'uinteger', 'AIS_SEC_NOT_AVAILABLE'), + ('maneuver', 'uinteger', 'AIS_SEC_INOPERATIVE'), + ('raim', 'boolean', 'false'), + ('radio', 'uinteger', '0'), + ), + }, + # Message types 2 and 3 duplicate 1 + { + "initname" : "json_ais4", + "header": "\tAIS_HEADER,", + "structname": "ais->type4", + "fieldmap":( + # fieldname type default + ('timestamp', 'string', None), + ('accuracy', 'boolean', "true"), + ('lon', 'integer', "AIS_LON_NOT_AVAILABLE"), + ('lat', 'integer', "AIS_LAT_NOT_AVAILABLE"), + ('epfd', 'uinteger', "0"), + ('raim', 'boolean', "false"), + ('radio', 'uinteger', "0"), + ), + "stringbuffered":("timestamp",), + }, + { + "initname" : "json_ais5", + "header": "\tAIS_HEADER,", + "structname": "ais->type5", + "fieldmap":( + # fieldname type default + ('imo', 'uinteger', '0'), + ('ais_version', 'uinteger', '0'), + ('callsign', 'string', None), + ('shipname', 'string', None), + ('shiptype', 'uinteger', '0'), + ('to_bow', 'uinteger', '0'), + ('to_stern', 'uinteger', '0'), + ('to_port', 'uinteger', '0'), + ('to_starboard', 'uinteger', '0'), + ('epfd', 'uinteger', '0'), + ('eta', 'string', None), + ('draught', 'uinteger', '0'), + ('destination', 'string', None), + ('dte', 'uinteger', '1'), + ), + "stringbuffered":("eta",), + }, + { + "initname" : "json_ais6", + "header": "\tAIS_HEADER,", + "structname": "ais->type6", + "fieldmap":( + # fieldname type default + ('seqno', 'uinteger', '0'), + ('dest_mmsi', 'uinteger', '0'), + ('retransmit', 'boolean', 'false'), + ('dac', 'uinteger', '0'), + ('fid', 'uinteger', '0'), + ('data', 'string', None), + ), + "stringbuffered":("data",), + }, + { + "initname" : "json_ais7", + "header": "\tAIS_HEADER,", + "structname": "ais->type7", + "fieldmap":( + # fieldname type default + ('mmsi1', 'uinteger', '0'), + ('mmsi2', 'uinteger', '0'), + ('mmsi3', 'uinteger', '0'), + ('mmsi4', 'uinteger', '0'), + ), + }, + { + "initname" : "json_ais8", + "header": "\tAIS_HEADER,", + "structname": "ais->type8", + "fieldmap":( + # fieldname type default + ('dac', 'uinteger', '0'), + ('fid', 'uinteger', '0'), + ('data', 'string', None), + ), + "stringbuffered":("data",), + }, + { + "initname" : "json_ais9", + "header": "\tAIS_HEADER,", + "structname": "ais->type9", + "fieldmap":( + # fieldname type default + ('alt', 'uinteger', 'AIS_ALT_NOT_AVAILABLE'), + ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'), + ('accuracy', 'boolean', 'false'), + ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), + ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), + ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'), + ('second', 'uinteger', 'AIS_SEC_NOT_AVAILABLE'), + ('regional', 'uinteger', '0'), + ('dte', 'uinteger', '1'), + ('raim', 'boolean', 'false'), + ('radio', 'uinteger', '0'), + ), + }, + { + "initname" : "json_ais10", + "header": "\tAIS_HEADER,", + "structname": "ais->type10", + "fieldmap":( + # fieldname type default + ('dest_mmsi', 'uinteger', '0'), + ), + }, + # Message type 11 duplicates 4 + { + "initname" : "json_ais12", + "header": "\tAIS_HEADER,", + "structname": "ais->type12", + "fieldmap":( + # fieldname type default + ('seqno', 'uinteger', '0'), + ('dest_mmsi', 'uinteger', '0'), + ('retransmit', 'boolean', '0'), + ('text', 'string', None), + ), + }, + # Message type 13 duplicates 7 + { + "initname" : "json_ais14", + "header": "\tAIS_HEADER,", + "structname": "ais->type14", + "fieldmap":( + # fieldname type default + ('text', 'string', None), + ), + }, + { + "initname" : "json_ais15", + "header": "\tAIS_HEADER,", + "structname": "ais->type15", + "fieldmap":( + # fieldname type default + ('mmsi1', 'uinteger', '0'), + ('type1_1', 'uinteger', '0'), + ('offset1_1', 'uinteger', '0'), + ('type1_2', 'uinteger', '0'), + ('offset1_2', 'uinteger', '0'), + ('mmsi2', 'uinteger', '0'), + ('type2_1', 'uinteger', '0'), + ('offset2_1', 'uinteger', '0'), + ), + }, + { + "initname" : "json_ais16", + "header": "\tAIS_HEADER,", + "structname": "ais->type16", + "fieldmap":( + # fieldname type default + ('mmsi1', 'uinteger', '0'), + ('offset1', 'uinteger', '0'), + ('increment1', 'uinteger', '0'), + ('mmsi2', 'uinteger', '0'), + ('offset2', 'uinteger', '0'), + ('increment2', 'uinteger', '0'), + ), + }, + { + "initname" : "json_ais17", + "header": "\tAIS_HEADER,", + "structname": "ais->type17", + "fieldmap":( + # fieldname type default + ('lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), + ('lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), + ('data', 'string', None), + ), + "stringbuffered":("data",), + }, + { + "initname" : "json_ais18", + "header": "\tAIS_HEADER,", + "structname": "ais->type18", + "fieldmap":( + # fieldname type default + ('reserved', 'uinteger', '0'), + ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'), + ('accuracy', 'boolean', 'false'), + ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), + ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), + ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'), + ('heading', 'uinteger', 'AIS_HEADING_NOT_AVAILABLE'), + ('second', 'uinteger', 'AIS_SEC_NOT_AVAILABLE'), + ('regional', 'uinteger', '0'), + ('cs', 'boolean', 'false'), + ('display', 'boolean', 'false'), + ('dsc', 'boolean', 'false'), + ('band', 'boolean', 'false'), + ('msg22', 'boolean', 'false'), + ('raim', 'boolean', 'false'), + ('radio', 'uinteger', '0'), + ), + }, + { + "initname" : "json_ais19", + "header": "\tAIS_HEADER,", + "structname": "ais->type19", + "fieldmap":( + # fieldname type default + ('reserved', 'uinteger', '0'), + ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'), + ('accuracy', 'boolean', 'false'), + ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), + ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), + ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'), + ('heading', 'uinteger', 'AIS_HEADING_NOT_AVAILABLE'), + ('second', 'uinteger', 'AIS_SEC_NOT_AVAILABLE'), + ('regional', 'uinteger', '0'), + ('shipname', 'string', None), + ('shiptype', 'uinteger', '0'), + ('to_bow', 'uinteger', '0'), + ('to_stern', 'uinteger', '0'), + ('to_port', 'uinteger', '0'), + ('to_starboard', 'uinteger', '0'), + ('epfd', 'uinteger', '0'), + ('raim', 'boolean', 'false'), + ('dte', 'uinteger', '1'), + ('assigned', 'boolean', 'false'), + ), + }, + { + "initname" : "json_ais20", + "header": "\tAIS_HEADER,", + "structname": "ais->type20", + "fieldmap":( + # fieldname type default + ('offset1', 'uinteger', '0'), + ('number1', 'uinteger', '0'), + ('timeout1', 'uinteger', '0'), + ('increment1', 'uinteger', '0'), + ('offset2', 'uinteger', '0'), + ('number2', 'uinteger', '0'), + ('timeout2', 'uinteger', '0'), + ('increment2', 'uinteger', '0'), + ('offset3', 'uinteger', '0'), + ('number3', 'uinteger', '0'), + ('timeout3', 'uinteger', '0'), + ('increment3', 'uinteger', '0'), + ('offset4', 'uinteger', '0'), + ('number4', 'uinteger', '0'), + ('timeout4', 'uinteger', '0'), + ('increment4', 'uinteger', '0'), + ), + }, + { + "initname" : "json_ais21", + "header": "\tAIS_HEADER,", + "structname": "ais->type21", + "fieldmap":( + # fieldname type default + ('aid_type', 'uinteger', '0'), + ('name', 'string', None), + ('accuracy', 'boolean', 'false'), + ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), + ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), + ('to_bow', 'uinteger', '0'), + ('to_stern', 'uinteger', '0'), + ('to_port', 'uinteger', '0'), + ('to_starboard', 'uinteger', '0'), + ('epfd', 'uinteger', '0'), + ('second', 'uinteger', '0'), + ('regional', 'uinteger', '0'), + ('off_position', 'boolean', 'false'), + ('raim', 'boolean', 'false'), + ('virtual_aid', 'boolean', 'false'), + ), + }, + { + "initname" : "json_ais22", + "header": "\tAIS_HEADER,", + "structname": "ais->type22", + "fieldmap":( + # fieldname type default + ('channel_a', 'uinteger', '0'), + ('channel_b', 'uinteger', '0'), + ('txrx', 'uinteger', '0'), + ('power', 'boolean', 'false'), + ('area.ne_lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), + ('area.ne_lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), + ('area.sw_lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), + ('area.sw_lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), + ('mmsi.dest1', 'uinteger', '0'), + ('mmsi.dest2', 'uinteger', '0'), + ('addressed', 'boolean', 'false'), + ('band_a', 'boolean', 'false'), + ('band_b', 'boolean', 'false'), + ('zonesize', 'uinteger', '0'), + ), + }, + { + "initname" : "json_ais23", + "header": "\tAIS_HEADER,", + "structname": "ais->type23", + "fieldmap":( + # fieldname type default + ('ne_lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), + ('ne_lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), + ('sw_lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), + ('sw_lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), + ('stationtype', 'uinteger', '0'), + ('shiptype', 'uinteger', '0'), + ('txrx', 'uinteger', '0'), + ('interval', 'uinteger', '0'), + ('quiet', 'uinteger', '0'), + ), + }, + { + "initname" : "json_ais24", + "header": "\tAIS_HEADER,", + "structname": "ais->type24", + "fieldmap":( + # fieldname type default + ('shipname', 'string', None), # Part A + ('shiptype', 'uinteger', '0'), # Part B + ('vendorid', 'string', None), # Part B + ('callsign', 'string', None), # Part B + ('mothership_mmsi', 'uinteger', '0'), # Part B + ('dim.to_bow', 'uinteger', '0'), # Part B + ('dim.to_stern', 'uinteger', '0'), # Part B + ('dim.to_port', 'uinteger', '0'), # Part B + ('dim.to_starboard', 'uinteger', '0'), # Part B + ), + }, + { + "initname" : "json_ais25", + "header": "\tAIS_HEADER,", + "structname": "ais->type25", + "fieldmap":( + # fieldname type default + ('addressed', 'boolean', 'false'), + ('structured', 'boolean', 'false'), + ('dest_mmsi', 'uinteger', '0'), + ('app_id', 'uinteger', '0'), + ('data', 'string', None), + ), + "stringbuffered":("data",), + }, + { + "initname" : "json_ais26", + "header": "\tAIS_HEADER,", + "structname": "ais->type26", + "fieldmap":( + # fieldname type default + ('addressed', 'boolean', 'false'), + ('structured', 'boolean', 'false'), + ('dest_mmsi', 'uinteger', '0'), + ('app_id', 'uinteger', '0'), + ('data', 'string', None), + ('radio', 'uinteger', '0'), + ), + "stringbuffered":("data",), + }, +) + + +# Give this global the string spec you need to convert with -g +# We do it this mildly odd way only because passing Python multiline +# string literals on the command line is inconvenient. +stringspec = "" + +# You should not need to modify anything below this line. + +def generate(spec): + global outboard + report = "" + for (attr, itype, default) in spec["fieldmap"]: + if attr in spec.get("stringbuffered", []): + if attr not in outboard: + report += " char %s[JSON_VAL_MAX+1];\n" % attr + outboard.append(attr) + report += " const struct json_attr_t %s[] = {\n" % spec["initname"] + if "header" in spec: + report += spec["header"] + "\n" + for (attr, itype, default) in spec["fieldmap"]: + structname = spec["structname"] + if itype == "string": + deref = "" + else: + deref = "&" + if attr in spec.get("stringbuffered", []): + target = attr + else: + target = structname + "." + attr + if "." in attr: + attr = attr[attr.rfind(".")+1:] + report += '\t{"%s",%st_%s,%s.addr.%s = %s%s,\n' % \ + (attr, " "*(14-len(attr)), itype, " "*(10-len(itype)), itype, deref, target) + leader = " " * 39 + if itype == "string": + report += leader + ".len = sizeof(%s)},\n" % target + else: + report += leader + ".dflt.%s = %s},\n" % (itype, default) + + report += """\ + {NULL} + }; +""" + print report + +# No code for generating dump functions yet. +# When we do this, remembeer that we have to suppress dump function +# generation from any spec with a union dot in the field names; +# those will have to be coded by hand. + +def string_to_specifier(strspec): + "Compile a Python-style format string to an attribute-type fieldmap." + # Map C and Python-type format letters to JSON parser datatypes + fmtmap = { + "d": "integer", + "u": "uinteger", + "f": "real", + "s": "boolean", # Only booleans print as unquoted strings + "\"": "string", + } + dftmap = { + "integer": "0", + "uinteger": "0", + "real": "0.0", + "string": None, + "boolean": "false" + } + strspec = strspec.strip() + if strspec[-1] == "}": + strspec = strspec[:-1] + else: + print "Missing terminating }" + sys.exit(1) + print ' "fieldmap":(' + for item in strspec.split(","): + itype = fmtmap[item[-1]] + attr = item[:item.find(":")] + if attr[0] == '"': + attr = attr[1:] + if attr[-1] == '"': + attr = attr[:-1] + dflt = dftmap[itype] + if dflt is not None: + dflt = `dflt` + print " ('%s',%s'%s',%s%s)," % (attr, " "*(14-len(attr)), itype, " "*(14-len(itype)), dflt) + print " )" + + +if __name__ == '__main__': + try: + # The --ais and --target= options are (required) placeho;lders. + # In the future, this script will generate more different kinds + # of code. + (options, arguments) = getopt.getopt(sys.argv[1:], "g", ["ais", "target="]) + except getopt.GetoptError, msg: + print "jsongen.py: " + str(msg) + raise SystemExit, 1 + + specify = False + spec = None + target = None + for (switch, val) in options: + if switch == '-g': + specify = True + elif switch == '--ais': + spec = ais_specs + elif switch == '--target': + target = val + + if not specify and (not target or not spec): + print "jsongen.py: must specify type and target." + sys,exit(1) + + + if specify: + string_to_specifier(stringspec) + else: + print """/* + * This is code generated by jsongen.py. Do not hand-hack it! + */ + +/*@ -fullinitblock */ + +""" + outboard = [] + for description in spec: + generate(description) + print """ +/*@ +fullinitblock */ + +/* Generated code ends. */ +""" +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:python +# End: diff --git a/lcdgps.c b/lcdgps.c new file mode 100644 index 0000000..3b7627c --- /dev/null +++ b/lcdgps.c @@ -0,0 +1,547 @@ +/* + * Copyright (c) 2005 Jeff Francis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + Jeff Francis + jeff@gritch.org + + A client that passes gpsd data to lcdproc, turning your car computer + into a very expensive feature-free GPS receiver ;^). Currently + assumes a 4x40 LCD and writes data formatted to fit that size + screen. Also displays 4- or 6-character Maidenhead grid square + output for the hams among us. + + This program assumes that LCDd (lcdproc) is running locally on the + default (13666) port. The #defines LCDDHOST and LCDDPORT can be + changed to talk to a different host and TCP port. +*/ + +#define LCDDHOST "localhost" +#define LCDDPORT 13666 + +#define CLIMB 3 + +#include +#include "gpsd_config.h" +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#ifdef HAVE_SYS_SELECT_H + #include +#endif /* HAVE_SYS_SELECT_H */ +#ifndef S_SPLINT_S + #ifdef HAVE_SYS_SOCKET_H + #include + #endif /* HAVE_SYS_SOCKET_H */ +#endif /* S_SPLINT_S */ + +#include /* select() */ +#include +#include +#ifdef HAVE_TERMIOS_H + #include +#endif /* HAVE_TERMIOS_H */ + +#ifndef S_SPLINT_S + #ifdef HAVE_NETINET_IN_H + #include + #endif /* HAVE_NETINET_IN_H */ + #ifdef HAVE_ARPA_INET_H + #include + #endif /* HAVE_ARPA_INET_H */ + #ifdef HAVE_NETDB_H + #include + #endif /* HAVE_NETDB_H */ +#endif /* S_SPLINT_S */ +#include + +#include + +#include "gps.h" +#include "gpsdclient.h" +#include "revision.h" + +/* Macro for declaring function arguments unused. */ +#if defined(__GNUC__) +# define UNUSED __attribute__((unused)) /* Flag variable as unused */ +#else /* not __GNUC__ */ +# define UNUSED +#endif + +/* Prototypes. */ +void latlon2maidenhead(char *st,float n,float e); +static void daemonize(void); +ssize_t sockreadline(int sockd,void *vptr,size_t maxlen); +ssize_t sockwriteline(int sockd,const void *vptr,size_t n); +int send_lcd(char *buf); + +static struct fixsource_t source; +static struct gps_data_t gpsdata; +static float altfactor = METERS_TO_FEET; +static float speedfactor = MPS_TO_MPH; +static char *altunits = "ft"; +static char *speedunits = "mph"; + +#ifdef CLIMB +double avgclimb, climb[CLIMB]; +#endif + +/* Global socket descriptor for LCDd. */ +int sd; + +/* Convert lat/lon to Maidenhead. Lifted from QGrid - + http://users.pandora.be/on4qz/qgrid/ */ +void latlon2maidenhead(char *st,float n,float e) +{ + int t1; + e=e+180.0; + t1=(int)(e/20); + st[0]=t1+'A'; + e-=(float)t1*20.0; + t1=(int)e/2; + st[2]=t1+'0'; + e-=(float)t1*2; +#ifndef CLIMB + st[4]=(int)(e*12.0+0.5)+'A'; +#endif + + n=n+90.0; + t1=(int)(n/10.0); + st[1]=t1+'A'; + n-=(float)t1*10.0; + st[3]=(int)n+'0'; + n-=(int)n; + n*=24; // convert to 24 division +#ifndef CLIMB + st[5]=(int)(n+0.5)+'A'; +#endif +} + +/* Daemonize me. */ +static void daemonize(void) { + int i, ignore; + + /* Run as my child. */ + i=fork(); + if (i == -1) exit(1); /* fork error */ + if (i > 0) exit(0); /* parent exits */ + + /* Obtain a new process group. */ + setsid(); + + /* Close all open descriptors. */ + for(i=getdtablesize();i>=0;--i) + close(i); + + /* Reopen STDIN, STDOUT, STDERR to /dev/null. */ + i=open("/dev/null",O_RDWR); /* STDIN */ + ignore=dup(i); /* STDOUT */ + ignore=dup(i); /* STDERR */ + + /* Know thy mask. */ + umask(027); + + /* Run from a known location. */ + ignore=chdir("/"); + + /* Catch child sig */ + signal(SIGCHLD,SIG_IGN); + + /* Ignore tty signals */ + signal(SIGTSTP,SIG_IGN); + signal(SIGTTOU,SIG_IGN); + signal(SIGTTIN,SIG_IGN); +} + +/* Read a line from a socket */ +ssize_t sockreadline(int sockd,void *vptr,size_t maxlen) { + ssize_t n,rc; + char c,*buffer; + + buffer=vptr; + + for (n = 1; n < (ssize_t)maxlen; n++) { + + if((rc=read(sockd,&c,1))==1) { + *buffer++=c; + if(c=='\n') + break; + } + else if(rc==0) { + if(n==1) + return(0); + else + break; + } + else { + if(errno==EINTR) + continue; + return(-1); + } + } + + *buffer=0; + return(n); +} + +/* Write a line to a socket */ +ssize_t sockwriteline(int sockd,const void *vptr,size_t n) { + size_t nleft; + ssize_t nwritten; + const char *buffer; + + buffer=vptr; + nleft=n; + + while(nleft>0) { + if((nwritten= write(sockd,buffer,nleft))<=0) { + if(errno==EINTR) + nwritten=0; + else + return(-1); + } + nleft-=nwritten; + buffer+=nwritten; + } + + return(n); +} + +/* send a command to the LCD */ +int send_lcd(char *buf) { + + int res; + char rcvbuf[256]; + size_t outlen; + + /* Limit the size of outgoing strings. */ + outlen = strlen(buf); + if(outlen > 255) { + outlen = 256; + } + + /* send the command */ + res=sockwriteline(sd,buf,outlen); + + /* TODO: check return status */ + + /* read the data */ + res=sockreadline(sd,rcvbuf,255); + + /* null-terminate the string before printing */ + /* rcvbuf[res-1]=0; FIX-ME: not using this at the moment... */ + + /* return the result */ + return(res); +} + +/* reset the LCD */ +static void reset_lcd(void) { + + /* Initialize. In theory, we should look at what's returned, as it + tells us info on the attached LCD module. TODO. */ + send_lcd("hello\n"); + + /* Set up the screen */ + send_lcd("client_set name {GPSD test}\n"); + send_lcd("screen_add gpsd\n"); + send_lcd("widget_add gpsd one string\n"); + send_lcd("widget_add gpsd two string\n"); + send_lcd("widget_add gpsd three string\n"); + send_lcd("widget_add gpsd four string\n"); +} + +static enum deg_str_type deg_type = deg_dd; + +/* This gets called once for each new sentence. */ +static void update_lcd(struct gps_data_t *gpsdata, + char *message UNUSED, + size_t len UNUSED) +{ + char tmpbuf[255]; +#ifdef CLIMB + char maidenhead[5]; + maidenhead[4]=0; + int n; +#else + char maidenhead[7]; + maidenhead[6]=0; +#endif + char *s; + int track; + + /* this is where we implement source-device filtering */ + if (gpsdata->dev.path[0] && source.device!=NULL && strcmp(source.device, gpsdata->dev.path) != 0) + return; + + /* Get our location in Maidenhead. */ + latlon2maidenhead(maidenhead,gpsdata->fix.latitude,gpsdata->fix.longitude); + + /* Fill in the latitude and longitude. */ + if (gpsdata->fix.mode >= MODE_2D) { + + s = deg_to_str(deg_type, fabs(gpsdata->fix.latitude)); + snprintf(tmpbuf, 254, "widget_set gpsd one 1 1 {Lat: %s %c}\n", s, (gpsdata->fix.latitude < 0) ? 'S' : 'N'); + send_lcd(tmpbuf); + + s = deg_to_str(deg_type, fabs(gpsdata->fix.longitude)); + snprintf(tmpbuf, 254, "widget_set gpsd two 1 2 {Lon: %s %c}\n", s, (gpsdata->fix.longitude < 0) ? 'W' : 'E'); + send_lcd(tmpbuf); + + /* As a pilot, a heading of "0" gives me the heebie-jeebies (ie, 0 + == "invalid heading data", 360 == "North"). */ + track=(int)(gpsdata->fix.track); + if(track == 0) track = 360; + + snprintf(tmpbuf, 254, "widget_set gpsd three 1 3 {%.1f %s %d deg}\n", + gpsdata->fix.speed*speedfactor, speedunits, + track); + send_lcd(tmpbuf); + + } else { + + send_lcd("widget_set gpsd one 1 1 {Lat: n/a}\n"); + send_lcd("widget_set gpsd two 1 2 {Lon: n/a}\n"); + send_lcd("widget_set gpsd three 1 3 {n/a}\n"); + } + + /* Fill in the altitude and fix status. */ + if (gpsdata->fix.mode == MODE_3D) { +#ifdef CLIMB + for(n=0;nfix.climb; + avgclimb=0.0; + for(n=0;nfix.altitude*altfactor), altunits, maidenhead, (int)(avgclimb * METERS_TO_FEET * 60)); +#else + snprintf(tmpbuf, 254, "widget_set gpsd four 1 4 {%.1f %s %s}\n", + gpsdata->fix.altitude*altfactor, altunits, maidenhead); +#endif + } else { + snprintf(tmpbuf, 254, "widget_set gpsd four 1 4 {n/a}\n"); + } + send_lcd(tmpbuf); +} + +static void usage( char *prog) +{ + (void)fprintf(stderr, + "Usage: %s [-h] [-v] [-V] [-s] [-l {d|m|s}] [-u {i|m|n}] [server[:port:[device]]]\n\n" + " -h Show this help, then exit\n" + " -V Show version, then exit\n" + " -s Sleep for 10 seconds before starting\n" + " -j Turn on anti-jitter buffering\n" + " -l {d|m|s} Select lat/lon format\n" + " d = DD.dddddd (default)\n" + " m = DD MM.mmmm'\n" + " s = DD MM' SS.sss\"\n" + " -u {i|m|n} Select Units\n" + " i = Imperial (default)\n" + " m = Metric'\n" + " n = Nautical\"\n" + , prog); + + exit(1); +} + +int main(int argc, char *argv[]) +{ + int option, rc; + struct sockaddr_in localAddr, servAddr; + struct hostent *h; + + struct timeval timeout; + fd_set rfds; + int data; + +#ifdef CLIMB + int n; + for(n=0;nh_addrtype; + memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length); + servAddr.sin_port = htons(LCDDPORT); + + /* create socket */ + sd = socket(AF_INET, SOCK_STREAM, 0); + if(sd == -1) { + perror("cannot open socket "); + exit(1); + } + + /* bind any port number */ + localAddr.sin_family = AF_INET; + localAddr.sin_addr.s_addr = htonl(INADDR_ANY); + localAddr.sin_port = htons(0); + + rc = bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr)); + if(rc == -1) { + printf("%s: cannot bind port TCP %u\n",argv[0],LCDDPORT); + perror("error "); + exit(1); + } + + /* connect to server */ + rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr)); + if(rc == -1) { + perror("cannot connect "); + exit(1); + } + + /* Do the initial field label setup. */ + reset_lcd(); + + /* Here's where updates go. */ + gps_set_raw_hook(&gpsdata, update_lcd); + gps_stream(&gpsdata, WATCH_ENABLE, NULL); + + for (;;) { /* heart of the client */ + + /* watch to see when it has input */ + FD_ZERO(&rfds); + FD_SET(gpsdata.gps_fd, &rfds); + + /* wait up to five seconds. */ + timeout.tv_sec = 5; + timeout.tv_usec = 0; + + /* check if we have new information */ + data = select(gpsdata.gps_fd + 1, &rfds, NULL, NULL, &timeout); + + if (data == -1) { + fprintf( stderr, "cgps: socket error\n"); + exit(2); + } + else if (data) { + (void)gps_read(&gpsdata); + } + + } +} diff --git a/libQgpsmm/gpsutils.cpp b/libQgpsmm/gpsutils.cpp new file mode 100644 index 0000000..5b43016 --- /dev/null +++ b/libQgpsmm/gpsutils.cpp @@ -0,0 +1,3 @@ +/* Simple C++ wrapper around gpsutils.c */ + +#include "gpsutils.c" diff --git a/libQgpsmm/libQgpsmm.pro b/libQgpsmm/libQgpsmm.pro new file mode 100644 index 0000000..13a33fd --- /dev/null +++ b/libQgpsmm/libQgpsmm.pro @@ -0,0 +1,98 @@ +# ------------------------------------------------- +# Project created by QtCreator 2010-03-26T10:37:44 +# ------------------------------------------------- +QT += network +QT -= gui +TARGET = Qgpsmm +TEMPLATE = lib +DEFINES += LIBQGPSMM_LIBRARY +DEFINES += USE_QT +DESTDIR = binaries +INCLUDEPATH += $$PWD \ + .. + +isEmpty( MAKE ) { + MAKE = make +} + +SOURCES += \ + gpsutils.cpp \ + libgps_core.cpp \ + ../libgpsmm.cpp \ + ../libgps_json.c \ + ../hex.c \ + ../gpsd_report.c \ + ../strl.c \ + ../shared_json.c \ + ../rtcm2_json.c \ + ../ais_json.c \ + ../json.c +HEADERS += libQgpsmm_global.h \ + ../gps.h \ + ../libgpsmm.h \ + ../gps_json.h \ + ../json.h + +!win32 { + + isEmpty( VERSION ) { + VERSION = $$system($${MAKE} -s -C .. print_libgps_VERSION) + } + HEADERS += \ + ../gpsd.h \ + ../ais_json.i + + # Prefix: base instalation directory + isEmpty( PREFIX ) { + PREFIX = /usr/local + } + isEmpty( EXEC_PREFIX ) { + EXEC_PREFIX = $${PREFIX} + } + isEmpty( LIBDIR ) { + LIBDIR = /lib + } + isEmpty( INCLUDEDIR ) { + INCLUDEDIR = /include + } + + # TARGET_LIBDIR and TARGET_INCLUDEDIR allow to override + # the library and header install paths. + # This is mainly a workaround as QT was not able to use the proper + # path on some platforms. Both TARGET_ variables will be + # set from the autotools generated Makefile. + # There should be a better way to handle this, though. + isEmpty( TARGET_LIBDIR ) { + TARGET_LIBDIR = $${EXEC_PREFIX}$${LIBDIR} + } + isEmpty( TARGET_INCLUDEDIR ) { + TARGET_INCLUDEDIR = $${PREFIX}$${INCLUDEDIR} + } + target.path = $${TARGET_LIBDIR} + INSTALLS += target + + header.path = $${TARGET_INCLUDEDIR} + header.files = ../libgpsmm.h ../gps.h + INSTALLS += header + + QMAKE_CFLAGS += -D_GNU_SOURCE + +} + +win32 { + + include( mingw/version.pri ) + HEADERS += \ + gpsd.h \ + mingw/ais_json.i + + INCLUDEPATH = $$PWD/mingw $${INCLUDEPATH} + + gpsdhcreate.target = gpsd.h + gpsdhcreate.commands = "copy /Y /B ..\gpsd.h-head + mingw\gpsd_config.h + ..\gpsd.h-tail gpsd.h" + gpsdhcreate.depends = FORCE + + PRE_TARGETDEPS += gpsd.h + QMAKE_EXTRA_TARGETS += gpsdhcreate + +} diff --git a/libQgpsmm/libQgpsmm_global.h b/libQgpsmm/libQgpsmm_global.h new file mode 100644 index 0000000..450db5a --- /dev/null +++ b/libQgpsmm/libQgpsmm_global.h @@ -0,0 +1,12 @@ +#ifndef LIBQGPSMM_GLOBAL_H +#define LIBQGPSMM_GLOBAL_H + +#include + +#if defined(LIBQGPSMM_LIBRARY) +# define LIBQGPSMMSHARED_EXPORT Q_DECL_EXPORT +#else +# define LIBQGPSMMSHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // LIBQGPSMM_GLOBAL_H diff --git a/libQgpsmm/libgps_core.cpp b/libQgpsmm/libgps_core.cpp new file mode 100644 index 0000000..e3a3782 --- /dev/null +++ b/libQgpsmm/libgps_core.cpp @@ -0,0 +1,3 @@ +/* Simple C++ wrapper around libgps_core.c */ + +#include "libgps_core.c" diff --git a/libQgpsmm/mingw/ais_json.i b/libQgpsmm/mingw/ais_json.i new file mode 100644 index 0000000..e5f18b5 --- /dev/null +++ b/libQgpsmm/mingw/ais_json.i @@ -0,0 +1,503 @@ +/* + * This is code generated by jsongen.py. Do not hand-hack it! + */ + +/*@ -fullinitblock */ + + + const struct json_attr_t json_ais1[] = { + AIS_HEADER, + {"status", t_uinteger, .addr.uinteger = &ais->type1.status, + .dflt.uinteger = 0}, + {"turn", t_integer, .addr.integer = &ais->type1.turn, + .dflt.integer = AIS_TURN_NOT_AVAILABLE}, + {"speed", t_uinteger, .addr.uinteger = &ais->type1.speed, + .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE}, + {"accuracy", t_boolean, .addr.boolean = &ais->type1.accuracy, + .dflt.boolean = false}, + {"lon", t_integer, .addr.integer = &ais->type1.lon, + .dflt.integer = AIS_LON_NOT_AVAILABLE}, + {"lat", t_integer, .addr.integer = &ais->type1.lat, + .dflt.integer = AIS_LAT_NOT_AVAILABLE}, + {"course", t_uinteger, .addr.uinteger = &ais->type1.course, + .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE}, + {"heading", t_uinteger, .addr.uinteger = &ais->type1.heading, + .dflt.uinteger = AIS_HEADING_NOT_AVAILABLE}, + {"second", t_uinteger, .addr.uinteger = &ais->type1.second, + .dflt.uinteger = AIS_SEC_NOT_AVAILABLE}, + {"maneuver", t_uinteger, .addr.uinteger = &ais->type1.maneuver, + .dflt.uinteger = AIS_SEC_INOPERATIVE}, + {"raim", t_boolean, .addr.boolean = &ais->type1.raim, + .dflt.boolean = false}, + {"radio", t_uinteger, .addr.uinteger = &ais->type1.radio, + .dflt.uinteger = 0}, + {NULL} + }; + + char timestamp[JSON_VAL_MAX+1]; + const struct json_attr_t json_ais4[] = { + AIS_HEADER, + {"timestamp", t_string, .addr.string = timestamp, + .len = sizeof(timestamp)}, + {"accuracy", t_boolean, .addr.boolean = &ais->type4.accuracy, + .dflt.boolean = true}, + {"lon", t_integer, .addr.integer = &ais->type4.lon, + .dflt.integer = AIS_LON_NOT_AVAILABLE}, + {"lat", t_integer, .addr.integer = &ais->type4.lat, + .dflt.integer = AIS_LAT_NOT_AVAILABLE}, + {"epfd", t_uinteger, .addr.uinteger = &ais->type4.epfd, + .dflt.uinteger = 0}, + {"raim", t_boolean, .addr.boolean = &ais->type4.raim, + .dflt.boolean = false}, + {"radio", t_uinteger, .addr.uinteger = &ais->type4.radio, + .dflt.uinteger = 0}, + {NULL} + }; + + char eta[JSON_VAL_MAX+1]; + const struct json_attr_t json_ais5[] = { + AIS_HEADER, + {"imo", t_uinteger, .addr.uinteger = &ais->type5.imo, + .dflt.uinteger = 0}, + {"ais_version", t_uinteger, .addr.uinteger = &ais->type5.ais_version, + .dflt.uinteger = 0}, + {"callsign", t_string, .addr.string = ais->type5.callsign, + .len = sizeof(ais->type5.callsign)}, + {"shipname", t_string, .addr.string = ais->type5.shipname, + .len = sizeof(ais->type5.shipname)}, + {"shiptype", t_uinteger, .addr.uinteger = &ais->type5.shiptype, + .dflt.uinteger = 0}, + {"to_bow", t_uinteger, .addr.uinteger = &ais->type5.to_bow, + .dflt.uinteger = 0}, + {"to_stern", t_uinteger, .addr.uinteger = &ais->type5.to_stern, + .dflt.uinteger = 0}, + {"to_port", t_uinteger, .addr.uinteger = &ais->type5.to_port, + .dflt.uinteger = 0}, + {"to_starboard", t_uinteger, .addr.uinteger = &ais->type5.to_starboard, + .dflt.uinteger = 0}, + {"epfd", t_uinteger, .addr.uinteger = &ais->type5.epfd, + .dflt.uinteger = 0}, + {"eta", t_string, .addr.string = eta, + .len = sizeof(eta)}, + {"draught", t_uinteger, .addr.uinteger = &ais->type5.draught, + .dflt.uinteger = 0}, + {"destination", t_string, .addr.string = ais->type5.destination, + .len = sizeof(ais->type5.destination)}, + {"dte", t_uinteger, .addr.uinteger = &ais->type5.dte, + .dflt.uinteger = 1}, + {NULL} + }; + + char data[JSON_VAL_MAX+1]; + const struct json_attr_t json_ais6[] = { + AIS_HEADER, + {"seqno", t_uinteger, .addr.uinteger = &ais->type6.seqno, + .dflt.uinteger = 0}, + {"dest_mmsi", t_uinteger, .addr.uinteger = &ais->type6.dest_mmsi, + .dflt.uinteger = 0}, + {"retransmit", t_boolean, .addr.boolean = &ais->type6.retransmit, + .dflt.boolean = false}, + {"dac", t_uinteger, .addr.uinteger = &ais->type6.dac, + .dflt.uinteger = 0}, + {"fid", t_uinteger, .addr.uinteger = &ais->type6.fid, + .dflt.uinteger = 0}, + {"data", t_string, .addr.string = data, + .len = sizeof(data)}, + {NULL} + }; + + const struct json_attr_t json_ais7[] = { + AIS_HEADER, + {"mmsi1", t_uinteger, .addr.uinteger = &ais->type7.mmsi1, + .dflt.uinteger = 0}, + {"mmsi2", t_uinteger, .addr.uinteger = &ais->type7.mmsi2, + .dflt.uinteger = 0}, + {"mmsi3", t_uinteger, .addr.uinteger = &ais->type7.mmsi3, + .dflt.uinteger = 0}, + {"mmsi4", t_uinteger, .addr.uinteger = &ais->type7.mmsi4, + .dflt.uinteger = 0}, + {NULL} + }; + + const struct json_attr_t json_ais8[] = { + AIS_HEADER, + {"dac", t_uinteger, .addr.uinteger = &ais->type8.dac, + .dflt.uinteger = 0}, + {"fid", t_uinteger, .addr.uinteger = &ais->type8.fid, + .dflt.uinteger = 0}, + {"data", t_string, .addr.string = data, + .len = sizeof(data)}, + {NULL} + }; + + const struct json_attr_t json_ais9[] = { + AIS_HEADER, + {"alt", t_uinteger, .addr.uinteger = &ais->type9.alt, + .dflt.uinteger = AIS_ALT_NOT_AVAILABLE}, + {"speed", t_uinteger, .addr.uinteger = &ais->type9.speed, + .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE}, + {"accuracy", t_boolean, .addr.boolean = &ais->type9.accuracy, + .dflt.boolean = false}, + {"lon", t_integer, .addr.integer = &ais->type9.lon, + .dflt.integer = AIS_LON_NOT_AVAILABLE}, + {"lat", t_integer, .addr.integer = &ais->type9.lat, + .dflt.integer = AIS_LAT_NOT_AVAILABLE}, + {"course", t_uinteger, .addr.uinteger = &ais->type9.course, + .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE}, + {"second", t_uinteger, .addr.uinteger = &ais->type9.second, + .dflt.uinteger = AIS_SEC_NOT_AVAILABLE}, + {"regional", t_uinteger, .addr.uinteger = &ais->type9.regional, + .dflt.uinteger = 0}, + {"dte", t_uinteger, .addr.uinteger = &ais->type9.dte, + .dflt.uinteger = 1}, + {"raim", t_boolean, .addr.boolean = &ais->type9.raim, + .dflt.boolean = false}, + {"radio", t_uinteger, .addr.uinteger = &ais->type9.radio, + .dflt.uinteger = 0}, + {NULL} + }; + + const struct json_attr_t json_ais10[] = { + AIS_HEADER, + {"dest_mmsi", t_uinteger, .addr.uinteger = &ais->type10.dest_mmsi, + .dflt.uinteger = 0}, + {NULL} + }; + + const struct json_attr_t json_ais12[] = { + AIS_HEADER, + {"seqno", t_uinteger, .addr.uinteger = &ais->type12.seqno, + .dflt.uinteger = 0}, + {"dest_mmsi", t_uinteger, .addr.uinteger = &ais->type12.dest_mmsi, + .dflt.uinteger = 0}, + {"retransmit", t_boolean, .addr.boolean = &ais->type12.retransmit, + .dflt.boolean = 0}, + {"text", t_string, .addr.string = ais->type12.text, + .len = sizeof(ais->type12.text)}, + {NULL} + }; + + const struct json_attr_t json_ais14[] = { + AIS_HEADER, + {"text", t_string, .addr.string = ais->type14.text, + .len = sizeof(ais->type14.text)}, + {NULL} + }; + + const struct json_attr_t json_ais15[] = { + AIS_HEADER, + {"mmsi1", t_uinteger, .addr.uinteger = &ais->type15.mmsi1, + .dflt.uinteger = 0}, + {"type1_1", t_uinteger, .addr.uinteger = &ais->type15.type1_1, + .dflt.uinteger = 0}, + {"offset1_1", t_uinteger, .addr.uinteger = &ais->type15.offset1_1, + .dflt.uinteger = 0}, + {"type1_2", t_uinteger, .addr.uinteger = &ais->type15.type1_2, + .dflt.uinteger = 0}, + {"offset1_2", t_uinteger, .addr.uinteger = &ais->type15.offset1_2, + .dflt.uinteger = 0}, + {"mmsi2", t_uinteger, .addr.uinteger = &ais->type15.mmsi2, + .dflt.uinteger = 0}, + {"type2_1", t_uinteger, .addr.uinteger = &ais->type15.type2_1, + .dflt.uinteger = 0}, + {"offset2_1", t_uinteger, .addr.uinteger = &ais->type15.offset2_1, + .dflt.uinteger = 0}, + {NULL} + }; + + const struct json_attr_t json_ais16[] = { + AIS_HEADER, + {"mmsi1", t_uinteger, .addr.uinteger = &ais->type16.mmsi1, + .dflt.uinteger = 0}, + {"offset1", t_uinteger, .addr.uinteger = &ais->type16.offset1, + .dflt.uinteger = 0}, + {"increment1", t_uinteger, .addr.uinteger = &ais->type16.increment1, + .dflt.uinteger = 0}, + {"mmsi2", t_uinteger, .addr.uinteger = &ais->type16.mmsi2, + .dflt.uinteger = 0}, + {"offset2", t_uinteger, .addr.uinteger = &ais->type16.offset2, + .dflt.uinteger = 0}, + {"increment2", t_uinteger, .addr.uinteger = &ais->type16.increment2, + .dflt.uinteger = 0}, + {NULL} + }; + + const struct json_attr_t json_ais17[] = { + AIS_HEADER, + {"lon", t_integer, .addr.integer = &ais->type17.lon, + .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE}, + {"lat", t_integer, .addr.integer = &ais->type17.lat, + .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE}, + {"data", t_string, .addr.string = data, + .len = sizeof(data)}, + {NULL} + }; + + const struct json_attr_t json_ais18[] = { + AIS_HEADER, + {"reserved", t_uinteger, .addr.uinteger = &ais->type18.reserved, + .dflt.uinteger = 0}, + {"speed", t_uinteger, .addr.uinteger = &ais->type18.speed, + .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE}, + {"accuracy", t_boolean, .addr.boolean = &ais->type18.accuracy, + .dflt.boolean = false}, + {"lon", t_integer, .addr.integer = &ais->type18.lon, + .dflt.integer = AIS_LON_NOT_AVAILABLE}, + {"lat", t_integer, .addr.integer = &ais->type18.lat, + .dflt.integer = AIS_LAT_NOT_AVAILABLE}, + {"course", t_uinteger, .addr.uinteger = &ais->type18.course, + .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE}, + {"heading", t_uinteger, .addr.uinteger = &ais->type18.heading, + .dflt.uinteger = AIS_HEADING_NOT_AVAILABLE}, + {"second", t_uinteger, .addr.uinteger = &ais->type18.second, + .dflt.uinteger = AIS_SEC_NOT_AVAILABLE}, + {"regional", t_uinteger, .addr.uinteger = &ais->type18.regional, + .dflt.uinteger = 0}, + {"cs", t_boolean, .addr.boolean = &ais->type18.cs, + .dflt.boolean = false}, + {"display", t_boolean, .addr.boolean = &ais->type18.display, + .dflt.boolean = false}, + {"dsc", t_boolean, .addr.boolean = &ais->type18.dsc, + .dflt.boolean = false}, + {"band", t_boolean, .addr.boolean = &ais->type18.band, + .dflt.boolean = false}, + {"msg22", t_boolean, .addr.boolean = &ais->type18.msg22, + .dflt.boolean = false}, + {"raim", t_boolean, .addr.boolean = &ais->type18.raim, + .dflt.boolean = false}, + {"radio", t_uinteger, .addr.uinteger = &ais->type18.radio, + .dflt.uinteger = 0}, + {NULL} + }; + + const struct json_attr_t json_ais19[] = { + AIS_HEADER, + {"reserved", t_uinteger, .addr.uinteger = &ais->type19.reserved, + .dflt.uinteger = 0}, + {"speed", t_uinteger, .addr.uinteger = &ais->type19.speed, + .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE}, + {"accuracy", t_boolean, .addr.boolean = &ais->type19.accuracy, + .dflt.boolean = false}, + {"lon", t_integer, .addr.integer = &ais->type19.lon, + .dflt.integer = AIS_LON_NOT_AVAILABLE}, + {"lat", t_integer, .addr.integer = &ais->type19.lat, + .dflt.integer = AIS_LAT_NOT_AVAILABLE}, + {"course", t_uinteger, .addr.uinteger = &ais->type19.course, + .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE}, + {"heading", t_uinteger, .addr.uinteger = &ais->type19.heading, + .dflt.uinteger = AIS_HEADING_NOT_AVAILABLE}, + {"second", t_uinteger, .addr.uinteger = &ais->type19.second, + .dflt.uinteger = AIS_SEC_NOT_AVAILABLE}, + {"regional", t_uinteger, .addr.uinteger = &ais->type19.regional, + .dflt.uinteger = 0}, + {"shipname", t_string, .addr.string = ais->type19.shipname, + .len = sizeof(ais->type19.shipname)}, + {"shiptype", t_uinteger, .addr.uinteger = &ais->type19.shiptype, + .dflt.uinteger = 0}, + {"to_bow", t_uinteger, .addr.uinteger = &ais->type19.to_bow, + .dflt.uinteger = 0}, + {"to_stern", t_uinteger, .addr.uinteger = &ais->type19.to_stern, + .dflt.uinteger = 0}, + {"to_port", t_uinteger, .addr.uinteger = &ais->type19.to_port, + .dflt.uinteger = 0}, + {"to_starboard", t_uinteger, .addr.uinteger = &ais->type19.to_starboard, + .dflt.uinteger = 0}, + {"epfd", t_uinteger, .addr.uinteger = &ais->type19.epfd, + .dflt.uinteger = 0}, + {"raim", t_boolean, .addr.boolean = &ais->type19.raim, + .dflt.boolean = false}, + {"dte", t_uinteger, .addr.uinteger = &ais->type19.dte, + .dflt.uinteger = 1}, + {"assigned", t_boolean, .addr.boolean = &ais->type19.assigned, + .dflt.boolean = false}, + {NULL} + }; + + const struct json_attr_t json_ais20[] = { + AIS_HEADER, + {"offset1", t_uinteger, .addr.uinteger = &ais->type20.offset1, + .dflt.uinteger = 0}, + {"number1", t_uinteger, .addr.uinteger = &ais->type20.number1, + .dflt.uinteger = 0}, + {"timeout1", t_uinteger, .addr.uinteger = &ais->type20.timeout1, + .dflt.uinteger = 0}, + {"increment1", t_uinteger, .addr.uinteger = &ais->type20.increment1, + .dflt.uinteger = 0}, + {"offset2", t_uinteger, .addr.uinteger = &ais->type20.offset2, + .dflt.uinteger = 0}, + {"number2", t_uinteger, .addr.uinteger = &ais->type20.number2, + .dflt.uinteger = 0}, + {"timeout2", t_uinteger, .addr.uinteger = &ais->type20.timeout2, + .dflt.uinteger = 0}, + {"increment2", t_uinteger, .addr.uinteger = &ais->type20.increment2, + .dflt.uinteger = 0}, + {"offset3", t_uinteger, .addr.uinteger = &ais->type20.offset3, + .dflt.uinteger = 0}, + {"number3", t_uinteger, .addr.uinteger = &ais->type20.number3, + .dflt.uinteger = 0}, + {"timeout3", t_uinteger, .addr.uinteger = &ais->type20.timeout3, + .dflt.uinteger = 0}, + {"increment3", t_uinteger, .addr.uinteger = &ais->type20.increment3, + .dflt.uinteger = 0}, + {"offset4", t_uinteger, .addr.uinteger = &ais->type20.offset4, + .dflt.uinteger = 0}, + {"number4", t_uinteger, .addr.uinteger = &ais->type20.number4, + .dflt.uinteger = 0}, + {"timeout4", t_uinteger, .addr.uinteger = &ais->type20.timeout4, + .dflt.uinteger = 0}, + {"increment4", t_uinteger, .addr.uinteger = &ais->type20.increment4, + .dflt.uinteger = 0}, + {NULL} + }; + + const struct json_attr_t json_ais21[] = { + AIS_HEADER, + {"aid_type", t_uinteger, .addr.uinteger = &ais->type21.aid_type, + .dflt.uinteger = 0}, + {"name", t_string, .addr.string = ais->type21.name, + .len = sizeof(ais->type21.name)}, + {"accuracy", t_boolean, .addr.boolean = &ais->type21.accuracy, + .dflt.boolean = false}, + {"lon", t_integer, .addr.integer = &ais->type21.lon, + .dflt.integer = AIS_LON_NOT_AVAILABLE}, + {"lat", t_integer, .addr.integer = &ais->type21.lat, + .dflt.integer = AIS_LAT_NOT_AVAILABLE}, + {"to_bow", t_uinteger, .addr.uinteger = &ais->type21.to_bow, + .dflt.uinteger = 0}, + {"to_stern", t_uinteger, .addr.uinteger = &ais->type21.to_stern, + .dflt.uinteger = 0}, + {"to_port", t_uinteger, .addr.uinteger = &ais->type21.to_port, + .dflt.uinteger = 0}, + {"to_starboard", t_uinteger, .addr.uinteger = &ais->type21.to_starboard, + .dflt.uinteger = 0}, + {"epfd", t_uinteger, .addr.uinteger = &ais->type21.epfd, + .dflt.uinteger = 0}, + {"second", t_uinteger, .addr.uinteger = &ais->type21.second, + .dflt.uinteger = 0}, + {"regional", t_uinteger, .addr.uinteger = &ais->type21.regional, + .dflt.uinteger = 0}, + {"off_position", t_boolean, .addr.boolean = &ais->type21.off_position, + .dflt.boolean = false}, + {"raim", t_boolean, .addr.boolean = &ais->type21.raim, + .dflt.boolean = false}, + {"virtual_aid", t_boolean, .addr.boolean = &ais->type21.virtual_aid, + .dflt.boolean = false}, + {NULL} + }; + + const struct json_attr_t json_ais22[] = { + AIS_HEADER, + {"channel_a", t_uinteger, .addr.uinteger = &ais->type22.channel_a, + .dflt.uinteger = 0}, + {"channel_b", t_uinteger, .addr.uinteger = &ais->type22.channel_b, + .dflt.uinteger = 0}, + {"txrx", t_uinteger, .addr.uinteger = &ais->type22.txrx, + .dflt.uinteger = 0}, + {"power", t_boolean, .addr.boolean = &ais->type22.power, + .dflt.boolean = false}, + {"ne_lon", t_integer, .addr.integer = &ais->type22.area.ne_lon, + .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE}, + {"ne_lat", t_integer, .addr.integer = &ais->type22.area.ne_lat, + .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE}, + {"sw_lon", t_integer, .addr.integer = &ais->type22.area.sw_lon, + .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE}, + {"sw_lat", t_integer, .addr.integer = &ais->type22.area.sw_lat, + .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE}, + {"dest1", t_uinteger, .addr.uinteger = &ais->type22.mmsi.dest1, + .dflt.uinteger = 0}, + {"dest2", t_uinteger, .addr.uinteger = &ais->type22.mmsi.dest2, + .dflt.uinteger = 0}, + {"addressed", t_boolean, .addr.boolean = &ais->type22.addressed, + .dflt.boolean = false}, + {"band_a", t_boolean, .addr.boolean = &ais->type22.band_a, + .dflt.boolean = false}, + {"band_b", t_boolean, .addr.boolean = &ais->type22.band_b, + .dflt.boolean = false}, + {"zonesize", t_uinteger, .addr.uinteger = &ais->type22.zonesize, + .dflt.uinteger = 0}, + {NULL} + }; + + const struct json_attr_t json_ais23[] = { + AIS_HEADER, + {"ne_lon", t_integer, .addr.integer = &ais->type23.ne_lon, + .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE}, + {"ne_lat", t_integer, .addr.integer = &ais->type23.ne_lat, + .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE}, + {"sw_lon", t_integer, .addr.integer = &ais->type23.sw_lon, + .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE}, + {"sw_lat", t_integer, .addr.integer = &ais->type23.sw_lat, + .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE}, + {"stationtype", t_uinteger, .addr.uinteger = &ais->type23.stationtype, + .dflt.uinteger = 0}, + {"shiptype", t_uinteger, .addr.uinteger = &ais->type23.shiptype, + .dflt.uinteger = 0}, + {"txrx", t_uinteger, .addr.uinteger = &ais->type23.txrx, + .dflt.uinteger = 0}, + {"interval", t_uinteger, .addr.uinteger = &ais->type23.interval, + .dflt.uinteger = 0}, + {"quiet", t_uinteger, .addr.uinteger = &ais->type23.quiet, + .dflt.uinteger = 0}, + {NULL} + }; + + const struct json_attr_t json_ais24[] = { + AIS_HEADER, + {"shipname", t_string, .addr.string = ais->type24.shipname, + .len = sizeof(ais->type24.shipname)}, + {"shiptype", t_uinteger, .addr.uinteger = &ais->type24.shiptype, + .dflt.uinteger = 0}, + {"vendorid", t_string, .addr.string = ais->type24.vendorid, + .len = sizeof(ais->type24.vendorid)}, + {"callsign", t_string, .addr.string = ais->type24.callsign, + .len = sizeof(ais->type24.callsign)}, + {"mothership_mmsi",t_uinteger, .addr.uinteger = &ais->type24.mothership_mmsi, + .dflt.uinteger = 0}, + {"to_bow", t_uinteger, .addr.uinteger = &ais->type24.dim.to_bow, + .dflt.uinteger = 0}, + {"to_stern", t_uinteger, .addr.uinteger = &ais->type24.dim.to_stern, + .dflt.uinteger = 0}, + {"to_port", t_uinteger, .addr.uinteger = &ais->type24.dim.to_port, + .dflt.uinteger = 0}, + {"to_starboard", t_uinteger, .addr.uinteger = &ais->type24.dim.to_starboard, + .dflt.uinteger = 0}, + {NULL} + }; + + const struct json_attr_t json_ais25[] = { + AIS_HEADER, + {"addressed", t_boolean, .addr.boolean = &ais->type25.addressed, + .dflt.boolean = false}, + {"structured", t_boolean, .addr.boolean = &ais->type25.structured, + .dflt.boolean = false}, + {"dest_mmsi", t_uinteger, .addr.uinteger = &ais->type25.dest_mmsi, + .dflt.uinteger = 0}, + {"app_id", t_uinteger, .addr.uinteger = &ais->type25.app_id, + .dflt.uinteger = 0}, + {"data", t_string, .addr.string = data, + .len = sizeof(data)}, + {NULL} + }; + + const struct json_attr_t json_ais26[] = { + AIS_HEADER, + {"addressed", t_boolean, .addr.boolean = &ais->type26.addressed, + .dflt.boolean = false}, + {"structured", t_boolean, .addr.boolean = &ais->type26.structured, + .dflt.boolean = false}, + {"dest_mmsi", t_uinteger, .addr.uinteger = &ais->type26.dest_mmsi, + .dflt.uinteger = 0}, + {"app_id", t_uinteger, .addr.uinteger = &ais->type26.app_id, + .dflt.uinteger = 0}, + {"data", t_string, .addr.string = data, + .len = sizeof(data)}, + {"radio", t_uinteger, .addr.uinteger = &ais->type26.radio, + .dflt.uinteger = 0}, + {NULL} + }; + + +/*@ +fullinitblock */ + +/* Generated code ends. */ + diff --git a/libQgpsmm/mingw/gpsd_config.h b/libQgpsmm/mingw/gpsd_config.h new file mode 100644 index 0000000..6d13bc6 --- /dev/null +++ b/libQgpsmm/mingw/gpsd_config.h @@ -0,0 +1,260 @@ +/* Stripped down verison of gpsd_config.h to build the QT bindings with mingw */ + +#include "version.h" + +/* AIVDM protocol support) */ +#define AIVDM_ENABLE 1 + +/* client debugging support) */ +#define CLIENTDEBUG_ENABLE 1 + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define if you have the external 'daylight' variable. */ +#define HAVE_DAYLIGHT 1 + +/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. + */ +/* #undef HAVE_DECL_TZNAME */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* pthread libraries are present */ +#define HAVE_LIBPTHREAD /**/ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NCURSES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_SYSTM_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NETINET_IP_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PYTHON_H 1 + +/* Define to 1 if you have the `round' function. */ +/* #undef HAVE_ROUND */ + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcat' function. */ +/* #undef HAVE_STRLCAT */ + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef HAVE_STRLCPY */ + +/* Define to 1 if you have the `strtonum' function. */ +/* #undef HAVE_STRTONUM */ + +/* Define to 1 if `tm_zone' is member of `struct tm'. */ +#define HAVE_STRUCT_TM_TM_ZONE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IPC_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MODEM_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SHM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STAT_H 1 */ + +/* Define to 1 if you have the header file. */ +/*#undef HAVE_SYS_TERMIOS_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TERMIOS_H 1 */ + +/* Have timezone variable */ +#define HAVE_TIMEZONE /**/ + +/* struct tm has tm_gmtoff */ +/* #undef HAVE_TM_GMTOFF */ + +/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use + `HAVE_STRUCT_TM_TM_ZONE' instead. */ +#define HAVE_TM_ZONE 1 + +/* Define to 1 if you don't have `tm_zone' but do have the external array + `tzname'. */ +/* #undef HAVE_TZNAME */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 + +/* IPv6 support */ +#define IPV6_ENABLE 1 + +/* C++ support */ +#define LIBGPSMM_ENABLE 1 + +/* oldstyle (pre-JSON) protocol support */ +#define OLDSTYLE_ENABLE 1 + +/* Name of package */ +#define PACKAGE "gpsd" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + + +/* Raw Measurement support */ +#define RAW_ENABLE 1 + +/* rtcm104v2 binary support */ +#define RTCM104V2_ENABLE 1 + +/* rtcm104v3 binary support */ +#define RTCM104V3_ENABLE 1 + +/* Squelch logging and hexdumps */ +/* #undef SQUELCH_ENABLE */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* latency timing support) */ +#define TIMING_ENABLE 1 + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* True North Technologies support */ +/* #undef TNT_ENABLE */ + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Define to 1 if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + +/* Some libc's don't have strlcat/strlcpy. Local copies are provided */ +#ifndef HAVE_STRLCAT +# ifdef __cplusplus +extern "C" { +# endif +size_t strlcat(/*@out@*/char *dst, /*@in@*/const char *src, size_t size); +# ifdef __cplusplus +} +# endif +#endif +#ifndef HAVE_STRLCPY +# ifdef __cplusplus +extern "C" { +# endif +size_t strlcpy(/*@out@*/char *dst, /*@in@*/const char *src, size_t size); +# ifdef __cplusplus +} +# endif +#endif + +#define GPSD_CONFIG_H + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ diff --git a/libQgpsmm/mingw/test_qgpsmm.pro b/libQgpsmm/mingw/test_qgpsmm.pro new file mode 100644 index 0000000..0b304ca --- /dev/null +++ b/libQgpsmm/mingw/test_qgpsmm.pro @@ -0,0 +1,18 @@ +QT += network +QT -= gui +TARGET = test_qgpsmm +DESTDIR = ../binaries +TEMPLATE = app + +INCLUDEPATH += $$PWD \ + .. \ + ../.. + +SOURCES = ../../test_gpsmm.cpp +LIBS += -L../binaries -lQgpsmm + +# just in case sombody runs this on !win32: + +!win32 { + LIBS += -Wl,-rpath,$$PWD/../binaries +} diff --git a/libQgpsmm/mingw/version.h b/libQgpsmm/mingw/version.h new file mode 100644 index 0000000..4ca22d9 --- /dev/null +++ b/libQgpsmm/mingw/version.h @@ -0,0 +1 @@ +#define VERSION "2.95" diff --git a/libQgpsmm/mingw/version.pri b/libQgpsmm/mingw/version.pri new file mode 100644 index 0000000..43373ae --- /dev/null +++ b/libQgpsmm/mingw/version.pri @@ -0,0 +1 @@ +VERSION=19.0.0 diff --git a/libgps.pc.in b/libgps.pc.in new file mode 100644 index 0000000..8a501d5 --- /dev/null +++ b/libgps.pc.in @@ -0,0 +1,9 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: GPSD +Description: GPS Daemon communication library +Version: @VERSION@ +Libs: -L${libdir} -lgps diff --git a/libgps.xml b/libgps.xml new file mode 100644 index 0000000..3d6b006 --- /dev/null +++ b/libgps.xml @@ -0,0 +1,343 @@ + + + + +14 Aug 2004 + +3 +3 +The GPSD Project +GPSD Documentation + + +libgps +C service library for communicating with the GPS daemon + + + + + +C: + +#include <gps.h> + + + +struct gps_data_t *gps_open + intaf + char *server + char * port + + +int gps_open_r + char *server + char * port + struct gps_data_t *gpsdata + + +int gps_send + struct gps_data_t *gpsdata + char *fmt... + + +void gps_set_raw_hook + struct gps_data_t *gpsdata + void (*hook)(struct gps_data_t *, + char *buf, size_t len) + + +int gps_poll + struct gps_data_t *gpsdata + + +bool gps_waiting + struct gps_data_t *gpsdata + + +void gps_close + struct gps_data_t *gpsdata + + +int gps_stream + struct gps_data_t *gpsdata + unsigned intflags + void *data + + +char *gps_errstr + int err + + + +Python: + +import gps + +session = gps.gps(host="localhost", port="2947") + +session.set_raw_hook(raw_hook) + +session.stream(flags=WATCH_JSON) + +for report in session: + process(report) + +del session + + + + + +DESCRIPTION + +libgps is a service library which +supports communicating with an instance of the +gpsd8; link it with the linker option -lgps. + +Take care to conditionalize your code on the major and +minor API version symbols in gps.h; ideally, +force a compilation failure if GPSD_API_MAJOR_VERSION is not a version +you recognize. See the GPSD project website for more information on +the protocol and API changes. + +Calling gps_open() initializes a GPS-data +structure to hold the data collected by the GPS, and returns a socket +attached to +gpsd1. +gps_open() returns NULL on errors. errno is +set depending on the error returned from the the socket layer; see +gps.h for values and explanations. The host +address may be a DNS name, an IPv4 dotted quad, or an IPV6 address; +the library will do the right thing for any of these. + +gps_open_r() is a reentrent-friendly +version that puts the session storage where you wish to allocate it. +It returns 0 on success and -1 on failure, with errno set +appropriately. + +gps_close() ends the session. + +gps_send() writes a command to the daemon. +The second argument must be a format string containing elements from +the command set documented at +gpsd1. +It may have % elements as for +sprintf3, +which will be filled in from any following arguments. This function +returns a -1 if there was a Unix-level write error, otherwise +0. Please read the LIMITATIONS section for additional information and +cautions. + +gps_poll() accepts a response, or sequence +of responses, from the daemon and interprets it as though it were a +query response (the return value is as for a query). +gps_poll() returns the validity mask of the +received structure. This function does a blocking read waiting for +data from the daemon; it returns 0 for success, -1 with errno set on a +Unix-level read error, -1 with errno not set if the socket to +the daemon has closed. + +gps_waiting() can be used to check +whether there is data from the daemon. It returns true if there is, +false on no data waiting or error condition. It does not block +waiting for input. + +gps_stream() asks +gpsd to stream the reports it has at you, +to be made available whenn you poll. It is preferable to the +older-style (pre-2.90) way of doing this, +gps_query() with a "w+" argument, because it +insulates your code from whether your client library and your +gpsd are using old or new protocol. +The second argument is a flag mask that sets various policy bits; +see trhe list below. Calling gps_stream() +more than once with different flag masks is allowed. + + + +WATCH_DISABLE + +Disable the reporting modes specified by the other WATCH_ flags. +Cannot be used to disable POLL_NONBLOCK. + + + +WATCH_ENABLE + +Disable the reporting modes specified by the other WATCH_ flags. +This is the default. + + + +WATCH_JSON + +Enable JSON reporting of data. If WATCH_ENABLE is set, and no +other WATCH flags are set, this is the default. + + + +WATCH_NMEA + +Enable generated pseudo-NMEA reporting on binary devices. + + + +WATCH_RARE + +Enable reporting of binary packets in encoded hex. + + + +WATCH_RAW + +Enable literal passtrough of binary packets. + + + +WATCH_SCALED + +When reporting AIS data, scale integer quantities to floats if +they have a divisor or rendering formula assosiated with them. + + + +WATCH_NEWSTYLE + +Force issuing a JSON initialization and getting new-style +responses. This will become the default in a future release. + + + +WATCH_OLDSTYLE + +Force issuing a W or R command and getting old-style +responses. This is now the default behavior, but will be removed +in a future release. + + + +WATCH_DEVICE + +Restrict watching to a speciied device, patch given as second +argument. + + + +POLL_NONBLOCK + +Normally gps_poll() blocks until +either there is a read error or some data is received from tha +daemon. In this mode, gps_poll() returns +immediately with a value of 0 if there is no input waiting. + + + + +gps_set_raw_hook() takes a function you +specify and run it (synchronously) on the raw data pulled by a +gps_query() or gps_poll() +call. The arguments passed to this hook will be a pointer to a +structure containing parsed data, and a buffer containining the +raw gpsd response. + +gps_errstr() returns an ASCII string (in +English) describing the error indicated by a nonzero return value from +gps_open(). + +Consult gps.h to learn more about the data members +and associated timestamps. Note that information will accumulate +in the session structure over time, and the 'valid' field is not +automatically zeroed by each poll. It is up to the client to +zero that field when appropriate and to keep an eye on the fix +and sentence timestamps. + +The Python implementation supports the same facilities as the C +library. gps_open() is replaced by the +initialization of a gps session object; the other calls are methods of +that object, and have the same names as the corresponding C functions. +Resources within the session object will be properly released when it +is garbage-collected. Note one limitation: POLL_NOBLOCK is not yet +supported in Python; use the waiting() method instead. + + +CODE EXAMPLE + +The following is an excerpted and simplified version of the +libgps interface code from +xgps1. +The function handle_input() is a trivial piece of +code that calls gps_poll(gpsdata). + + + + gpsdata = gps_open(server, port); + + build_gui(toplevel); + + gps_set_raw_hook(gpsdata, update_panel); + + (void)gps_stream(gpsdata, WATCH_ENABLE, NULL); + + (void)XtAppAddInput(app, gpsdata->gps_fd, + (XtPointer)XtInputReadMask, handle_input, NULL); + (void)XtAppMainLoop(app); + + (void)gps_close(gpsdata); + + + + +LIMITATIONS + +In the C API, incautious use of gps_send() +may lead to subtle bugs. In order to not bloat struct +gps_data_t with space used by responses that are not +expected to be shipped in close sequence with each other, the storage +for fields associated with certain responses are combined in a +union. + +The risky set of responses includes VERSION, DEVICELIST, RTCM2, +RTCM3, and AIS; it may not be limited to that set. The logic of the +daemon's watcher mode is careful to avoid dangerous sequences, but +you should read and understand the layout of struct +gps_data_t before using gps_send() +to request any of these responses. + + + +COMPATIBILITY + +The gps_query() supported in major versions +1 and 2 of this library has been removed. With the new +streaming-oriented wire protocol behind this library, it is extremely +unwise to assume that the first transmission from the damon after a +command is shipped to it will be the reponse to command. + +If you must send commands to the daemon explicity, use +gps_send() but beware that this ties your code to +the GPSD wire protocol. It is not recommended. + +This API has been stable since GPSD 2.90, except that +gps_waiting() was added in 2.91. + + +SEE ALSO + +gpsd8, +gps1, +libgpsd3. +libgpsmm3. + + + +AUTHOR +Eric S. Raymond <esr@thyrsus.com>, Thread-callback methods +in the C binding added by Alfredo Pironti +<alfredo@users.sourceforge.net>. + + + diff --git a/libgps_core.c b/libgps_core.c new file mode 100644 index 0000000..996b42f --- /dev/null +++ b/libgps_core.c @@ -0,0 +1,851 @@ +/* libgps.c -- client interface library for the gpsd daemon + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "gps_json.h" + +#ifndef USE_QT +#ifndef S_SPLINT_S +#ifdef HAVE_SYS_SOCKET_H +#include +#else +#define AF_UNSPEC 0 +#endif +#endif +#if defined (HAVE_SYS_SELECT_H) +#include +#endif +#else +#include +#endif /* USE_QT */ + +#ifdef S_SPLINT_S +extern char *strtok_r(char *, const char *, char **); +#endif /* S_SPLINT_S */ + +#if defined(TESTMAIN) || defined(CLIENTDEBUG_ENABLE) +#define LIBGPS_DEBUG +#endif /* defined(TESTMAIN) || defined(CLIENTDEBUG_ENABLE) */ + +struct privdata_t +{ + bool newstyle; + ssize_t waiting; + char buffer[GPS_JSON_RESPONSE_MAX * 2]; +}; +#define PRIVATE(gpsdata) ((struct privdata_t *)gpsdata->privdata) + +#ifdef LIBGPS_DEBUG +static int debuglevel = 0; +static int waitcount = 0; +static FILE *debugfp; + +void gps_enable_debug(int level, FILE * fp) +/* control the level and destination of debug trace messages */ +{ + debuglevel = level; + debugfp = fp; +#ifdef CLIENTDEBUG_ENABLE + json_enable_debug(level - 2, fp); +#endif +} + +static void gps_trace(int errlevel, const char *fmt, ...) +/* assemble command in printf(3) style */ +{ + if (errlevel <= debuglevel) { + char buf[BUFSIZ]; + va_list ap; + + (void)strlcpy(buf, "libgps: ", BUFSIZ); + va_start(ap, fmt); + (void)vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, + ap); + va_end(ap); + + (void)fputs(buf, debugfp); + } +} + +# define libgps_debug_trace(args) (void) gps_trace args +#else +# define libgps_debug_trace(args) /*@i1@*/do { } while (0) +#endif /* LIBGPS_DEBUG */ + +/*@-nullderef@*/ +int gps_open_r(/*@null@*/const char *host, /*@null@*/const char *port, + /*@out@*/ struct gps_data_t *gpsdata) +{ + /*@ -branchstate @*/ + if (!gpsdata) + return -1; + if (!host) + host = "localhost"; + if (!port) + port = DEFAULT_GPSD_PORT; + + libgps_debug_trace((1, "gps_open_r(%s, %s)\n", host, port)); + +#ifndef USE_QT + if ((gpsdata->gps_fd = + netlib_connectsock(AF_UNSPEC, host, port, "tcp")) < 0) { + errno = gpsdata->gps_fd; + return -1; + } +#else + QTcpSocket *sock = new QTcpSocket(); + gpsdata->gps_fd = sock; + sock->connectToHost(host, QString(port).toInt()); + if (!sock->waitForConnected()) + qDebug() << "libgps::connect error: " << sock->errorString(); + else + qDebug() << "libgps::connected!"; +#endif + + gpsdata->set = 0; + gpsdata->status = STATUS_NO_FIX; + gps_clear_fix(&gpsdata->fix); + + /* set up for line-buffered I/O over the daemon socket */ + gpsdata->privdata = (void *)malloc(sizeof(struct privdata_t)); + if (gpsdata->privdata == NULL) + return -1; + PRIVATE(gpsdata)->newstyle = false; + PRIVATE(gpsdata)->waiting = 0; + /*@i2@*/ PRIVATE(gpsdata)->buffer[0] = '\0'; + + return 0; + /*@ +branchstate @*/ +} + +/*@-compmempass -immediatetrans@*/ +struct gps_data_t *gps_open(const char *host, const char *port) +/* open a connection to a gpsd daemon */ +{ + static struct gps_data_t gpsdata; + if (gps_open_r(host, port, &gpsdata) == -1) + return NULL; + else + return &gpsdata; +} + +/*@+compmempass +immediatetrans@*/ + +/*@-compdef -usereleased@*/ +int gps_close(struct gps_data_t *gpsdata) +/* close a gpsd connection */ +{ + libgps_debug_trace((1, "gps_close()\n")); +#ifndef USE_QT + free(PRIVATE(gpsdata)); + (void)close(gpsdata->gps_fd); + gpsdata->gps_fd = -1; +#else + QTcpSocket *sock = (QTcpSocket *) gpsdata->gps_fd; + sock->disconnectFromHost(); + delete sock; + gpsdata->gps_fd = NULL; +#endif + + return 0; +} + +/*@+compdef +usereleased@*/ + +void gps_set_raw_hook(struct gps_data_t *gpsdata, + void (*hook) (struct gps_data_t *, char *, size_t len)) +{ + gpsdata->raw_hook = hook; +} + +#ifdef LIBGPS_DEBUG +static void libgps_dump_state(struct gps_data_t *collect, time_t now) +{ + char *status_values[] = { "NO_FIX", "FIX", "DGPS_FIX" }; + char *mode_values[] = { "", "NO_FIX", "MODE_2D", "MODE_3D" }; + + /* no need to dump the entire state, this is a sanity check */ +#ifndef USE_QT + (void)fprintf(debugfp, "flags: (0x%04x) %s\n", + collect->set, gps_maskdump(collect->set)); +#endif + if (collect->set & ONLINE_SET) + (void)fprintf(debugfp, "ONLINE: %lf\n", collect->online); + if (collect->set & TIME_SET) + (void)fprintf(debugfp, "TIME: %lf\n", collect->fix.time); + if (collect->set & LATLON_SET) + (void)fprintf(debugfp, "LATLON: lat/lon: %lf %lf\n", + collect->fix.latitude, collect->fix.longitude); + if (collect->set & ALTITUDE_SET) + (void)fprintf(debugfp, "ALTITUDE: altitude: %lf U: climb: %lf\n", + collect->fix.altitude, collect->fix.climb); + if (collect->set & SPEED_SET) + (void)fprintf(debugfp, "SPEED: %lf\n", collect->fix.speed); + if (collect->set & TRACK_SET) + (void)fprintf(debugfp, "TRACK: track: %lf\n", collect->fix.track); + if (collect->set & CLIMB_SET) + (void)fprintf(debugfp, "CLIMB: climb: %lf\n", collect->fix.climb); + if (collect->set & STATUS_SET) + (void)fprintf(debugfp, "STATUS: status: %d (%s)\n", + collect->status, status_values[collect->status]); + if (collect->set & MODE_SET) + (void)fprintf(debugfp, "MODE: mode: %d (%s)\n", + collect->fix.mode, mode_values[collect->fix.mode]); + if (collect->set & DOP_SET) + (void)fprintf(debugfp, + "DOP: satellites %d, pdop=%lf, hdop=%lf, vdop=%lf\n", + collect->satellites_used, collect->dop.pdop, + collect->dop.hdop, collect->dop.vdop); + if (collect->set & VERSION_SET) + (void)fprintf(debugfp, "VERSION: release=%s rev=%s proto=%d.%d\n", + collect->version.release, + collect->version.rev, + collect->version.proto_major, + collect->version.proto_minor); + if (collect->set & POLICY_SET) + (void)fprintf(debugfp, + "POLICY: watcher=%s nmea=%s raw=%d scaled=%s timing=%s, devpath=%s\n", + collect->policy.watcher ? "true" : "false", + collect->policy.nmea ? "true" : "false", + collect->policy.raw, + collect->policy.scaled ? "true" : "false", + collect->policy.timing ? "true" : "false", + collect->policy.devpath); + if (collect->set & SATELLITE_SET) { + int i; + + (void)fprintf(debugfp, "SKY: satellites in view: %d\n", + collect->satellites_visible); + for (i = 0; i < collect->satellites_visible; i++) { + (void)fprintf(debugfp, " %2.2d: %2.2d %3.3d %3.0f %c\n", + collect->PRN[i], collect->elevation[i], + collect->azimuth[i], collect->ss[i], + collect->used[i] ? 'Y' : 'N'); + } + } + if (collect->set & DEVICE_SET) + (void)fprintf(debugfp, "DEVICE: Device is '%s', driver is '%s'\n", + collect->dev.path, collect->dev.driver); +#ifdef OLDSTYLE_ENABLE + if (collect->set & DEVICEID_SET) + (void)fprintf(debugfp, "GPSD ID is %s\n", collect->dev.subtype); +#endif /* OLDSTYLE_ENABLE */ + if (collect->set & DEVICELIST_SET) { + int i; + (void)fprintf(debugfp, "DEVICELIST:%d devices:\n", + collect->devices.ndevices); + for (i = 0; i < collect->devices.ndevices; i++) { + (void)fprintf(debugfp, "%d: path='%s' driver='%s'\n", + collect->devices.ndevices, + collect->devices.list[i].path, + collect->devices.list[i].driver); + } + } + +} +#endif /* LIBGPS_DEBUG */ + + +/*@ -branchstate -usereleased -mustfreefresh -nullstate -usedef @*/ +int gps_unpack(char *buf, struct gps_data_t *gpsdata) +/* unpack a gpsd response into a status structure, buf must be writeable */ +{ + libgps_debug_trace((1, "gps_unpack(%s)\n", buf)); + + /* detect and process a JSON response */ + if (buf[0] == '{') { + const char *jp = buf, **next = &jp; + while (next != NULL && *next != NULL && next[0][0] != '\0') { + libgps_debug_trace((1, + "gps_unpack() segment parse '%s'\n", *next)); + if (libgps_json_unpack(*next, gpsdata, next) == -1) + break; +#ifdef LIBGPS_DEBUG + if (debuglevel >= 1) + libgps_dump_state(gpsdata, time(NULL)); +#endif /* LIBGPS_DEBUG */ + + } +#ifdef OLDSTYLE_ENABLE + if (PRIVATE(gpsdata) != NULL) + PRIVATE(gpsdata)->newstyle = true; +#endif /* OLDSTYLE_ENABLE */ + } +#ifdef OLDSTYLE_ENABLE + else { + /* + * Get the decimal separator for the current application locale. + * This looks thread-unsafe, but it's not. The key is that + * character assignment is atomic. + */ + char *ns, *sp, *tp; + + static char decimal_point = '\0'; + if (decimal_point == '\0') { + struct lconv *locale_data = localeconv(); + if (locale_data != NULL && locale_data->decimal_point[0] != '.') + decimal_point = locale_data->decimal_point[0]; + } + + for (ns = buf; ns; ns = strstr(ns + 1, "GPSD")) { + if ( /*@i1@*/ strncmp(ns, "GPSD", 4) == 0) { + bool eol = false; + /* the following should execute each time we have a good next sp */ + for (sp = ns + 5; *sp != '\0'; sp = tp + 1) { + tp = sp + strcspn(sp, ",\r\n"); + eol = *tp == '\r' || *tp == '\n'; + if (*tp == '\0') + tp--; + else + *tp = '\0'; + + /* + * The daemon always emits the Anglo-American and SI + * decimal point. Hack these into whatever the + * application locale requires if it's not the same. + * This has to happen *after* we grab the next + * comma-delimited response, or we'll lose horribly + * in locales where the decimal separator is comma. + */ + if (decimal_point != '\0') { + char *cp; + for (cp = sp; cp < tp; cp++) + if (*cp == '.') + *cp = decimal_point; + } + + /* note, there's a bit of skip logic after the switch */ + + switch (*sp) { + case 'F': /*@ -mustfreeonly */ + if (sp[2] == '?') + gpsdata->dev.path[0] = '\0'; + else { + /*@ -mayaliasunique @*/ + strncpy(gpsdata->dev.path, sp + 2, + sizeof(gpsdata->dev.path)); + /*@ +mayaliasunique @*/ + gpsdata->set |= DEVICE_SET; + } + /*@ +mustfreeonly */ + break; + case 'I': + /*@ -mustfreeonly */ + if (sp[2] == '?') + gpsdata->dev.subtype[0] = '\0'; + else { + (void)strlcpy(gpsdata->dev.subtype, sp + 2, + sizeof(gpsdata->dev.subtype)); + gpsdata->set |= DEVICEID_SET; + } + /*@ +mustfreeonly */ + break; + case 'O': + if (sp[2] == '?') { + gpsdata->set = MODE_SET | STATUS_SET; + gpsdata->status = STATUS_NO_FIX; + gps_clear_fix(&gpsdata->fix); + } else { + struct gps_fix_t nf; + char tag[MAXTAGLEN + 1], alt[20]; + char eph[20], epv[20], track[20], speed[20], + climb[20]; + char epd[20], eps[20], epc[20], mode[2]; + char timestr[20], ept[20], lat[20], lon[20]; + int st = sscanf(sp + 2, + "%8s %19s %19s %19s %19s %19s %19s %19s %19s %19s %19s %19s %19s %19s %1s", + tag, timestr, ept, lat, lon, + alt, eph, epv, track, speed, + climb, + epd, eps, epc, mode); + if (st >= 14) { +#define DEFAULT(val) (val[0] == '?') ? NAN : atof(val) + /*@ +floatdouble @*/ + nf.time = DEFAULT(timestr); + nf.latitude = DEFAULT(lat); + nf.longitude = DEFAULT(lon); + nf.ept = DEFAULT(ept); + nf.altitude = DEFAULT(alt); + /* designed before we split eph into epx+epy */ + nf.epx = nf.epy = DEFAULT(eph) / sqrt(2); + nf.epv = DEFAULT(epv); + nf.track = DEFAULT(track); + nf.speed = DEFAULT(speed); + nf.climb = DEFAULT(climb); + nf.epd = DEFAULT(epd); + nf.eps = DEFAULT(eps); + nf.epc = DEFAULT(epc); + /*@ -floatdouble @*/ +#undef DEFAULT + if (st >= 15) + nf.mode = + (mode[0] == + '?') ? MODE_NOT_SEEN : atoi(mode); + else + nf.mode = + (alt[0] == '?') ? MODE_2D : MODE_3D; + if (alt[0] != '?') + gpsdata->set |= ALTITUDE_SET | CLIMB_SET; + if (isnan(nf.epx) == 0 && isnan(nf.epy) == 0) + gpsdata->set |= HERR_SET; + if (isnan(nf.epv) == 0) + gpsdata->set |= VERR_SET; + if (isnan(nf.track) == 0) + gpsdata->set |= TRACK_SET | SPEED_SET; + if (isnan(nf.eps) == 0) + gpsdata->set |= SPEEDERR_SET; + if (isnan(nf.epc) == 0) + gpsdata->set |= CLIMBERR_SET; + gpsdata->fix = nf; + (void)strlcpy(gpsdata->tag, tag, + MAXTAGLEN + 1); + gpsdata->set |= + TIME_SET | TIMERR_SET | LATLON_SET | + MODE_SET; + gpsdata->status = STATUS_FIX; + gpsdata->set |= STATUS_SET; + } + } + break; + case 'X': + if (sp[2] == '?') + gpsdata->online = -1; + else { + (void)sscanf(sp, "X=%lf", &gpsdata->online); + gpsdata->set |= ONLINE_SET; + } + break; + case 'Y': + if (sp[2] == '?') { + gpsdata->satellites_visible = 0; + } else { + int j, i1, i2, i3, i5; + int PRN[MAXCHANNELS]; + int elevation[MAXCHANNELS], azimuth[MAXCHANNELS]; + int used[MAXCHANNELS]; + double ss[MAXCHANNELS], f4; + char tag[MAXTAGLEN + 1], timestamp[21]; + + (void)sscanf(sp, "Y=%8s %20s %d ", + tag, timestamp, + &gpsdata->satellites_visible); + (void)strncpy(gpsdata->tag, tag, MAXTAGLEN); + if (timestamp[0] != '?') { + gpsdata->set |= TIME_SET; + } + for (j = 0; j < gpsdata->satellites_visible; j++) { + PRN[j] = elevation[j] = azimuth[j] = used[j] = + 0; + ss[j] = 0.0; + } + for (j = 0, gpsdata->satellites_used = 0; + j < gpsdata->satellites_visible; j++) { + if ((sp != NULL) + && ((sp = strchr(sp, ':')) != NULL)) { + sp++; + (void)sscanf(sp, "%d %d %d %lf %d", &i1, + &i2, &i3, &f4, &i5); + PRN[j] = i1; + elevation[j] = i2; + azimuth[j] = i3; + ss[j] = f4; + used[j] = i5; + if (i5 == 1) + gpsdata->satellites_used++; + } + } + /*@ -compdef @*/ + memcpy(gpsdata->PRN, PRN, sizeof(PRN)); + memcpy(gpsdata->elevation, elevation, + sizeof(elevation)); + memcpy(gpsdata->azimuth, azimuth, + sizeof(azimuth)); + memcpy(gpsdata->ss, ss, sizeof(ss)); + memcpy(gpsdata->used, used, sizeof(used)); + /*@ +compdef @*/ + } + gpsdata->set |= SATELLITE_SET; + break; + } + +#ifdef LIBGPS_DEBUG + if (debuglevel >= 1) + libgps_dump_state(gpsdata, time(NULL)); +#endif /* LIBGPS_DEBUG */ + + /* + * Skip to next GPSD when we see \r or \n; + * we don't want to try interpreting stuff + * in between that might be raw mode data. + */ + if (eol) + break; + } + } + } + } +#endif /* OLDSTYLE_ENABLE */ + +/*@ -compdef @*/ + if (gpsdata->raw_hook) { + //libgps_debug_trace((stderr, "libgps: raw hook called on '%s'\n", buf)); + gpsdata->raw_hook(gpsdata, buf, strlen(buf)); + } +#ifndef USE_QT + libgps_debug_trace((1, "final flags: (0x%04x) %s\n", gpsdata->set, + gps_maskdump(gpsdata->set))); +#endif + return 0; +} + +/*@ +compdef @*/ +/*@ -branchstate +usereleased +mustfreefresh +nullstate +usedef @*/ + +bool gps_waiting(struct gps_data_t * gpsdata) +/* is there input waiting from the GPS? */ +{ +#ifndef USE_QT + fd_set rfds; + struct timeval tv; + + libgps_debug_trace((1, "gps_waiting(): %d\n", waitcount++)); + if (PRIVATE(gpsdata)->waiting > 0) + return true; + + FD_ZERO(&rfds); + FD_SET(gpsdata->gps_fd, &rfds); + tv.tv_sec = 0; + tv.tv_usec = 1; + /* all error conditions return "not waiting" -- crude but effective */ + return (select(gpsdata->gps_fd + 1, &rfds, NULL, NULL, &tv) == 1); +#else + return ((QTcpSocket *) (gpsdata->gps_fd))->waitForReadyRead(250); +#endif +} + +/*@-compdef -usedef -uniondef@*/ +int gps_read(/*@out@*/struct gps_data_t *gpsdata) +/* wait for and read data being streamed from the daemon */ +{ + char *eol; + double received = 0; + ssize_t response_length; + int status = -1; + struct privdata_t *priv = PRIVATE(gpsdata); + + gpsdata->set &= ~PACKET_SET; + for (eol = priv->buffer; + *eol != '\n' && eol < priv->buffer + priv->waiting; eol++) + continue; + if (*eol != '\n') + eol = NULL; + + if (eol == NULL) { +#ifndef USE_QT + /* read data: return -1 if no data waiting or buffered, 0 otherwise */ + status = (int)recv(gpsdata->gps_fd, + priv->buffer + priv->waiting, + sizeof(priv->buffer) - priv->waiting, 0); +#else + status = + ((QTcpSocket *) (gpsdata->gps_fd))->read(priv->buffer + + priv->waiting, + sizeof(priv->buffer) - + priv->waiting); +#endif + + /* if we just received data from the socket, it's in the buffer */ + if (status > -1) + priv->waiting += status; + /* buffer is empty - implies no data was read */ + if (priv->waiting == 0) { + /* + * If we received 0 bytes, other side of socket is closing. + * Return -1 as end-of-data indication. + */ + if (status == 0) + return -1; +#ifndef USE_QT + /* count transient errors as success, we'll retry later */ + else if (errno == EINTR || errno == EAGAIN + || errno == EWOULDBLOCK) + return 0; +#endif + /* hard error return of -1, pass it along */ + else + return -1; + } + /* there's buffered data waiting to be returned */ + for (eol = priv->buffer; + *eol != '\n' && eol < priv->buffer + priv->waiting; eol++) + continue; + if (*eol != '\n') + eol = NULL; + if (eol == NULL) + return 0; + } + + assert(eol != NULL); + *eol = '\0'; + response_length = eol - priv->buffer + 1; + received = gpsdata->online = timestamp(); + status = gps_unpack(priv->buffer, gpsdata); + /*@+matchanyintegral@*/ + memmove(priv->buffer, + priv->buffer + response_length, priv->waiting - response_length); + /*@-matchanyintegral@*/ + priv->waiting -= response_length; + gpsdata->set |= PACKET_SET; + + return status; +} +/*@+compdef -usedef +uniondef@*/ + +int gps_poll(/*@out@*/struct gps_data_t *gpsdata) +/* for backwards compatibility */ +{ + int status = gps_read(gpsdata); + + if (status > 0) + status = 0; + + return status; +} + +int gps_send(struct gps_data_t *gpsdata, const char *fmt, ...) +/* send a command to the gpsd instance */ +{ + char buf[BUFSIZ]; + va_list ap; + + va_start(ap, fmt); + (void)vsnprintf(buf, sizeof(buf) - 2, fmt, ap); + va_end(ap); + if (buf[strlen(buf) - 1] != '\n') + (void)strlcat(buf, "\n", BUFSIZ); +#ifndef USE_QT + if (write(gpsdata->gps_fd, buf, strlen(buf)) == (ssize_t) strlen(buf)) + return 0; + else + return -1; +#else + QTcpSocket *sock = (QTcpSocket *) gpsdata->gps_fd; + sock->write(buf, strlen(buf)); + if (sock->waitForBytesWritten()) + return 0; + else { + qDebug() << "libgps::send error: " << sock->errorString(); + return -1; + } +#endif +} + +int gps_stream(struct gps_data_t *gpsdata, unsigned int flags, + /*@null@*/ void *d) +/* ask gpsd to stream reports at you, hiding the command details */ +{ + char buf[GPS_JSON_COMMAND_MAX]; + + if ((flags & (WATCH_JSON | WATCH_OLDSTYLE | WATCH_NMEA | WATCH_RAW)) == 0) { + flags |= WATCH_JSON; + } +#ifndef USE_QT + if (flags & POLL_NONBLOCK) + (void)fcntl(gpsdata->gps_fd, F_SETFL, O_NONBLOCK); +#endif + if ((flags & WATCH_DISABLE) != 0) { + if ((flags & WATCH_OLDSTYLE) != 0) { + (void)strlcpy(buf, "w-", sizeof(buf)); + if (gpsdata->raw_hook != NULL || (flags & WATCH_NMEA) != 0) + (void)strlcat(buf, "r-", sizeof(buf)); + } else { + (void)strlcpy(buf, "?WATCH={\"enable\":false,", sizeof(buf)); + if (flags & WATCH_JSON) + (void)strlcat(buf, "\"json\":false,", sizeof(buf)); + if (flags & WATCH_NMEA) + (void)strlcat(buf, "\"nmea\":false,", sizeof(buf)); + if (flags & WATCH_RAW) + (void)strlcat(buf, "\"raw\":1,", sizeof(buf)); + if (flags & WATCH_RARE) + (void)strlcat(buf, "\"raw\":0,", sizeof(buf)); + if (flags & WATCH_SCALED) + (void)strlcat(buf, "\"scaled\":false,", sizeof(buf)); + if (buf[strlen(buf) - 1] == ',') + buf[strlen(buf) - 1] = '\0'; + (void)strlcat(buf, "};", sizeof(buf)); + } + libgps_debug_trace((1, "gps_stream() disable command: %s\n", buf)); + return gps_send(gpsdata, buf); + } else { /* if ((flags & WATCH_ENABLE) != 0) */ + + if ((flags & WATCH_OLDSTYLE) != 0) { + (void)strlcpy(buf, "w+x", sizeof(buf)); + if (gpsdata->raw_hook != NULL || (flags & WATCH_NMEA) != 0) + (void)strlcat(buf, "r+", sizeof(buf)); + } else { + (void)strlcpy(buf, "?WATCH={\"enable\":true,", sizeof(buf)); + if (flags & WATCH_JSON) + (void)strlcat(buf, "\"json\":true,", sizeof(buf)); + if (flags & WATCH_NMEA) + (void)strlcat(buf, "\"nmea\":true,", sizeof(buf)); + if (flags & WATCH_RARE) + (void)strlcat(buf, "\"raw\":1,", sizeof(buf)); + if (flags & WATCH_RAW) + (void)strlcat(buf, "\"raw\":2,", sizeof(buf)); + if (flags & WATCH_SCALED) + (void)strlcat(buf, "\"scaled\":true,", sizeof(buf)); + /*@-nullpass@*//* shouldn't be needed, splint has a bug */ + if (flags & WATCH_DEVICE) + (void)snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "\"device\":%s,", (char *)d); + /*@+nullpass@*/ + if (buf[strlen(buf) - 1] == ',') + buf[strlen(buf) - 1] = '\0'; + (void)strlcat(buf, "};", sizeof(buf)); + } + libgps_debug_trace((1, "gps_stream() enable command: %s\n", buf)); + return gps_send(gpsdata, buf); + } +} + +extern char /*@observer@*/ *gps_errstr(const int err) +{ + /* + * We might add our own error codes in the future, e.g for + * protocol compatibility checks + */ +#ifndef USE_QT + return netlib_errstr(err); +#else + return ""; +#endif +} + +#ifdef TESTMAIN +/* + * A simple command-line exerciser for the library. + * Not really useful for anything but debugging. + */ + +static void dumpline(struct gps_data_t *ud UNUSED, + char *buf, size_t ulen UNUSED) +{ + puts(buf); +} + +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include + +static void onsig(int sig) +{ + (void)fprintf(stderr, "libgps: died with signal %d\n", sig); + exit(1); +} + +/* must start zeroed, otherwise the unit test will try to chase garbage pointer fields. */ +static struct gps_data_t gpsdata; + +int main(int argc, char *argv[]) +{ + struct gps_data_t *collect; + char buf[BUFSIZ]; + int option; + bool batchmode = false; + int debug = 0; + + (void)signal(SIGSEGV, onsig); + (void)signal(SIGBUS, onsig); + + while ((option = getopt(argc, argv, "bhsD:?")) != -1) { + switch (option) { + case 'b': + batchmode = true; + break; + case 's': + (void) + printf + ("Sizes: gpsdata=%zd rtcm2=%zd rtcm3=%zd ais=%zd compass=%zd raw=%zd devices=%zd policy=%zd version=%zd\n", + sizeof(struct gps_data_t), sizeof(struct rtcm2_t), + sizeof(struct rtcm3_t), sizeof(struct ais_t), + sizeof(struct attitude_t), sizeof(struct rawdata_t), + sizeof(collect->devices), sizeof(struct policy_t), + sizeof(struct version_t)); + exit(0); + case 'D': + debug = atoi(optarg); + break; + case '?': + case 'h': + default: + (void)fputs("usage: libgps [-b] [-d lvl] [-s]\n", stderr); + exit(1); + } + } + + gps_enable_debug(debug, stdout); + if (batchmode) { + while (fgets(buf, sizeof(buf), stdin) != NULL) { + if (buf[0] == '{' || isalpha(buf[0])) { + gps_unpack(buf, &gpsdata); + libgps_dump_state(&gpsdata, time(NULL)); + } + } + } else if ((collect = gps_open(NULL, 0)) == NULL) { + (void)fputs("Daemon is not running.\n", stdout); + exit(1); + } else if (optind < argc) { + gps_set_raw_hook(collect, dumpline); + (void)strlcpy(buf, argv[optind], BUFSIZ); + (void)strlcat(buf, "\n", BUFSIZ); + (void)gps_send(collect, buf); + (void)gps_read(collect); + libgps_dump_state(collect, time(NULL)); + (void)gps_close(collect); + } else { + int tty = isatty(0); + + gps_set_raw_hook(collect, dumpline); + if (tty) + (void)fputs("This is the gpsd exerciser.\n", stdout); + for (;;) { + if (tty) + (void)fputs("> ", stdout); + if (fgets(buf, sizeof(buf), stdin) == NULL) { + if (tty) + putchar('\n'); + break; + } + collect->set = 0; + (void)gps_send(collect, buf); + (void)gps_read(collect); + libgps_dump_state(collect, time(NULL)); + } + (void)gps_close(collect); + } + + return 0; +} + +/*@-nullderef@*/ + +#endif /* TESTMAIN */ diff --git a/libgps_json.c b/libgps_json.c new file mode 100644 index 0000000..eaa056c --- /dev/null +++ b/libgps_json.c @@ -0,0 +1,411 @@ +/**************************************************************************** + +NAME + libgps_json.c - deserialize gpsd data coming from the server + +DESCRIPTION + This module uses the generic JSON parser to get data from JSON +representations to libgps structures. + +PERMISSIONS + Written by Eric S. Raymond, 2009 + This file is Copyright (c) 2010 by the GPSD project + BSD terms apply: see the file COPYING in the distribution root for details. + +***************************************************************************/ + +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "gps_json.h" + +/* + * There's a splint limitation that parameters can be declared + * @out@ or @null@ but not, apparently, both. This collides with + * the (admittedly tricky) way we use endptr. The workaround is to + * declare it @null@ and use -compdef around the JSON reader calls. + */ +/*@-compdef@*/ + +static int json_tpv_read(const char *buf, struct gps_data_t *gpsdata, + /*@null@*/ const char **endptr) +{ + int status; + /*@ -fullinitblock @*/ + const struct json_attr_t json_attrs_1[] = { + /* *INDENT-OFF* */ + {"class", t_check, .dflt.check = "TPV"}, + {"device", t_string, .addr.string = gpsdata->dev.path, + .len = sizeof(gpsdata->dev.path)}, + {"tag", t_string, .addr.string = gpsdata->tag, + .len = sizeof(gpsdata->tag)}, + {"time", t_real, .addr.real = &gpsdata->fix.time, + .dflt.real = NAN}, + {"ept", t_real, .addr.real = &gpsdata->fix.ept, + .dflt.real = NAN}, + {"lon", t_real, .addr.real = &gpsdata->fix.longitude, + .dflt.real = NAN}, + {"lat", t_real, .addr.real = &gpsdata->fix.latitude, + .dflt.real = NAN}, + {"alt", t_real, .addr.real = &gpsdata->fix.altitude, + .dflt.real = NAN}, + {"epx", t_real, .addr.real = &gpsdata->fix.epx, + .dflt.real = NAN}, + {"epy", t_real, .addr.real = &gpsdata->fix.epy, + .dflt.real = NAN}, + {"epv", t_real, .addr.real = &gpsdata->fix.epv, + .dflt.real = NAN}, + {"track", t_real, .addr.real = &gpsdata->fix.track, + .dflt.real = NAN}, + {"speed", t_real, .addr.real = &gpsdata->fix.speed, + .dflt.real = NAN}, + {"climb", t_real, .addr.real = &gpsdata->fix.climb, + .dflt.real = NAN}, + {"epd", t_real, .addr.real = &gpsdata->fix.epd, + .dflt.real = NAN}, + {"eps", t_real, .addr.real = &gpsdata->fix.eps, + .dflt.real = NAN}, + {"epc", t_real, .addr.real = &gpsdata->fix.epc, + .dflt.real = NAN}, + {"mode", t_integer, .addr.integer = &gpsdata->fix.mode, + .dflt.integer = MODE_NOT_SEEN}, + {NULL}, + /* *INDENT-ON* */ + }; + /*@ +fullinitblock @*/ + + status = json_read_object(buf, json_attrs_1, endptr); + + if (status == 0) { + gpsdata->status = STATUS_FIX; + gpsdata->set = STATUS_SET; + if (isnan(gpsdata->fix.time) == 0) + gpsdata->set |= TIME_SET; + if (isnan(gpsdata->fix.ept) == 0) + gpsdata->set |= TIMERR_SET; + if (isnan(gpsdata->fix.longitude) == 0) + gpsdata->set |= LATLON_SET; + if (isnan(gpsdata->fix.altitude) == 0) + gpsdata->set |= ALTITUDE_SET; + if (isnan(gpsdata->fix.epx) == 0 && isnan(gpsdata->fix.epy) == 0) + gpsdata->set |= HERR_SET; + if (isnan(gpsdata->fix.epv) == 0) + gpsdata->set |= VERR_SET; + if (isnan(gpsdata->fix.track) == 0) + gpsdata->set |= TRACK_SET; + if (isnan(gpsdata->fix.speed) == 0) + gpsdata->set |= SPEED_SET; + if (isnan(gpsdata->fix.climb) == 0) + gpsdata->set |= CLIMB_SET; + if (isnan(gpsdata->fix.epd) == 0) + gpsdata->set |= TRACKERR_SET; + if (isnan(gpsdata->fix.eps) == 0) + gpsdata->set |= SPEEDERR_SET; + if (isnan(gpsdata->fix.epc) == 0) + gpsdata->set |= CLIMBERR_SET; + if (isnan(gpsdata->fix.epc) == 0) + gpsdata->set |= CLIMBERR_SET; + if (gpsdata->fix.mode != MODE_NOT_SEEN) + gpsdata->set |= MODE_SET; + } + return status; +} + +static int json_sky_read(const char *buf, struct gps_data_t *gpsdata, + /*@null@*/ const char **endptr) +{ + bool usedflags[MAXCHANNELS]; + /*@ -fullinitblock @*/ + const struct json_attr_t json_attrs_2_1[] = { + /* *INDENT-OFF* */ + {"PRN", t_integer, .addr.integer = gpsdata->PRN}, + {"el", t_integer, .addr.integer = gpsdata->elevation}, + {"az", t_integer, .addr.integer = gpsdata->azimuth}, + {"ss", t_real, .addr.real = gpsdata->ss}, + {"used", t_boolean, .addr.boolean = usedflags}, + /* *INDENT-ON* */ + {NULL}, + }; + const struct json_attr_t json_attrs_2[] = { + /* *INDENT-OFF* */ + {"class", t_check, .dflt.check = "SKY"}, + {"device", t_string, .addr.string = gpsdata->dev.path, + .len = sizeof(gpsdata->dev.path)}, + {"tag", t_string, .addr.string = gpsdata->tag, + .len = sizeof(gpsdata->tag)}, + {"time", t_real, .addr.real = &gpsdata->fix.time, + .nodefault = true}, + {"hdop", t_real, .addr.real = &gpsdata->dop.hdop, + .dflt.real = NAN}, + {"xdop", t_real, .addr.real = &gpsdata->dop.xdop, + .dflt.real = NAN}, + {"ydop", t_real, .addr.real = &gpsdata->dop.ydop, + .dflt.real = NAN}, + {"vdop", t_real, .addr.real = &gpsdata->dop.vdop, + .dflt.real = NAN}, + {"tdop", t_real, .addr.real = &gpsdata->dop.tdop, + .dflt.real = NAN}, + {"pdop", t_real, .addr.real = &gpsdata->dop.pdop, + .dflt.real = NAN}, + {"gdop", t_real, .addr.real = &gpsdata->dop.gdop, + .dflt.real = NAN}, + {"satellites", t_array, .addr.array.element_type = t_object, + .addr.array.arr.objects.subtype=json_attrs_2_1, + .addr.array.maxlen = MAXCHANNELS, + .addr.array.count = &gpsdata->satellites_visible}, + {NULL}, + /* *INDENT-ON* */ + }; + /*@ +fullinitblock @*/ + int status, i, j; + + for (i = 0; i < MAXCHANNELS; i++) + usedflags[i] = false; + + status = json_read_object(buf, json_attrs_2, endptr); + if (status != 0) + return status; + + gpsdata->satellites_used = 0; + for (i = j = 0; i < MAXCHANNELS; i++) { + if (usedflags[i]) { + gpsdata->used[j++] = gpsdata->PRN[i]; + gpsdata->satellites_used++; + } + } + + gpsdata->set |= SATELLITE_SET; + return 0; +} + +static int json_att_read(const char *buf, struct gps_data_t *gpsdata, + /*@null@*/ const char **endptr) +{ + /*@ -fullinitblock @*/ + const struct json_attr_t json_attrs_1[] = { + /* *INDENT-OFF* */ + {"class", t_check, .dflt.check = "ATT"}, + {"device", t_string, .addr.string = gpsdata->dev.path, + .len = sizeof(gpsdata->dev.path)}, + {"tag", t_string, .addr.string = gpsdata->tag, + .len = sizeof(gpsdata->tag)}, + {"heading", t_real, .addr.real = &gpsdata->attitude.heading, + .dflt.real = NAN}, + {"mag_st", t_character, .addr.character = &gpsdata->attitude.mag_st}, + {"pitch", t_real, .addr.real = &gpsdata->attitude.pitch, + .dflt.real = NAN}, + {"pitch_st", t_character, .addr.character = &gpsdata->attitude.pitch_st}, + {"roll", t_real, .addr.real = &gpsdata->attitude.roll, + .dflt.real = NAN}, + {"roll_st", t_character, .addr.character = &gpsdata->attitude.roll_st}, + {"yaw", t_real, .addr.real = &gpsdata->attitude.yaw, + .dflt.real = NAN}, + {"yaw_st", t_character, .addr.character = &gpsdata->attitude.yaw_st}, + + {"mag_len", t_real, .addr.real = &gpsdata->attitude.mag_len, + .dflt.real = NAN}, + {"mag_x", t_real, .addr.real = &gpsdata->attitude.mag_x, + .dflt.real = NAN}, + {"mag_y", t_real, .addr.real = &gpsdata->attitude.mag_y, + .dflt.real = NAN}, + {"mag_z", t_real, .addr.real = &gpsdata->attitude.mag_z, + .dflt.real = NAN}, + {"acc_len", t_real, .addr.real = &gpsdata->attitude.acc_len, + .dflt.real = NAN}, + {"acc_x", t_real, .addr.real = &gpsdata->attitude.acc_x, + .dflt.real = NAN}, + {"acc_y", t_real, .addr.real = &gpsdata->attitude.acc_y, + .dflt.real = NAN}, + {"acc_z", t_real, .addr.real = &gpsdata->attitude.acc_z, + .dflt.real = NAN}, + {"gyro_x", t_real, .addr.real = &gpsdata->attitude.gyro_x, + .dflt.real = NAN}, + {"gyro_y", t_real, .addr.real = &gpsdata->attitude.gyro_y, + .dflt.real = NAN}, + + {"temp", t_real, .addr.real = &gpsdata->attitude.temp, + .dflt.real = NAN}, + {"depth", t_real, .addr.real = &gpsdata->attitude.depth, + .dflt.real = NAN}, + {NULL}, + /* *INDENT-ON* */ + }; + /*@ +fullinitblock @*/ + + return json_read_object(buf, json_attrs_1, endptr); +} + +static int json_devicelist_read(const char *buf, struct gps_data_t *gpsdata, + /*@null@*/ const char **endptr) +{ + /*@ -fullinitblock @*/ + const struct json_attr_t json_attrs_subdevices[] = { + /* *INDENT-OFF* */ + {"class", t_check, .dflt.check = "DEVICE"}, + {"path", t_string, STRUCTOBJECT(struct devconfig_t, path), + .len = sizeof(gpsdata->devices.list[0].path)}, + {"activated", t_real, STRUCTOBJECT(struct devconfig_t, activated)}, + {"flags", t_integer, STRUCTOBJECT(struct devconfig_t, flags)}, + {"driver", t_string, STRUCTOBJECT(struct devconfig_t, driver), + .len = sizeof(gpsdata->devices.list[0].driver)}, + {"subtype", t_string, STRUCTOBJECT(struct devconfig_t, subtype), + .len = sizeof(gpsdata->devices.list[0].subtype)}, + {"native", t_integer, STRUCTOBJECT(struct devconfig_t, driver_mode), + .dflt.integer = -1}, + {"bps", t_integer, STRUCTOBJECT(struct devconfig_t, baudrate), + .dflt.integer = -1}, + {"parity", t_character, STRUCTOBJECT(struct devconfig_t, parity), + .dflt.character = 'N'}, + {"stopbits", t_integer, STRUCTOBJECT(struct devconfig_t, stopbits), + .dflt.integer = -1}, + {"cycle", t_real, STRUCTOBJECT(struct devconfig_t, cycle), + .dflt.real = NAN}, + {"mincycle", t_real, STRUCTOBJECT(struct devconfig_t, mincycle), + .dflt.real = NAN}, + {NULL}, + /* *INDENT-ON* */ + }; + /*@-type@*//* STRUCTARRAY confuses splint */ + const struct json_attr_t json_attrs_devices[] = { + {"class", t_check,.dflt.check = "DEVICES"}, + {"devices", t_array, STRUCTARRAY(gpsdata->devices.list, + json_attrs_subdevices, + &gpsdata->devices.ndevices)}, + {NULL}, + }; + /*@+type@*/ + /*@ +fullinitblock @*/ + int status; + + memset(&gpsdata->devices, '\0', sizeof(gpsdata->devices)); + status = json_read_object(buf, json_attrs_devices, endptr); + if (status != 0) { + return status; + } + + gpsdata->devices.time = timestamp(); + gpsdata->set &= ~UNION_SET; + gpsdata->set |= DEVICELIST_SET; + return 0; +} + +static int json_version_read(const char *buf, struct gps_data_t *gpsdata, + /*@null@*/ const char **endptr) +{ + /*@ -fullinitblock @*/ + const struct json_attr_t json_attrs_version[] = { + /* *INDENT-OFF* */ + {"class", t_check, .dflt.check = "VERSION"}, + {"release", t_string, .addr.string = gpsdata->version.release, + .len = sizeof(gpsdata->version.release)}, + {"rev", t_string, .addr.string = gpsdata->version.rev, + .len = sizeof(gpsdata->version.rev)}, + {"proto_major", t_integer, .addr.integer = &gpsdata->version.proto_major}, + {"proto_minor", t_integer, .addr.integer = &gpsdata->version.proto_minor}, + {NULL}, + /* *INDENT-ON* */ + }; + /*@ +fullinitblock @*/ + int status; + + memset(&gpsdata->version, '\0', sizeof(gpsdata->version)); + status = json_read_object(buf, json_attrs_version, endptr); + if (status != 0) + return status; + + gpsdata->set &= ~UNION_SET; + gpsdata->set |= VERSION_SET; + return 0; +} + +static int json_error_read(const char *buf, struct gps_data_t *gpsdata, + /*@null@*/ const char **endptr) +{ + /*@ -fullinitblock @*/ + const struct json_attr_t json_attrs_error[] = { + /* *INDENT-OFF* */ + {"class", t_check, .dflt.check = "ERROR"}, + {"message", t_string, .addr.string = gpsdata->error, + .len = sizeof(gpsdata->error)}, + {NULL}, + /* *INDENT-ON* */ + }; + /*@ +fullinitblock @*/ + int status; + + memset(&gpsdata->error, '\0', sizeof(gpsdata->error)); + status = json_read_object(buf, json_attrs_error, endptr); + if (status != 0) + return status; + + gpsdata->set &= ~UNION_SET; + gpsdata->set |= ERROR_SET; + return 0; +} + +int libgps_json_unpack(const char *buf, + struct gps_data_t *gpsdata, const char **end) +/* the only entry point - unpack a JSON object into gpsdata_t substructures */ +{ + int status; + char *classtag = strstr(buf, "\"class\":"); + + if (classtag == NULL) + return -1; +#define STARTSWITH(str, prefix) strncmp(str, prefix, sizeof(prefix)-1)==0 + if (STARTSWITH(classtag, "\"class\":\"TPV\"")) { + return json_tpv_read(buf, gpsdata, end); + } else if (STARTSWITH(classtag, "\"class\":\"SKY\"")) { + return json_sky_read(buf, gpsdata, end); + } else if (STARTSWITH(classtag, "\"class\":\"ATT\"")) { + return json_att_read(buf, gpsdata, end); + } else if (STARTSWITH(classtag, "\"class\":\"DEVICES\"")) { + return json_devicelist_read(buf, gpsdata, end); + } else if (STARTSWITH(classtag, "\"class\":\"DEVICE\"")) { + status = json_device_read(buf, &gpsdata->dev, end); + if (status == 0) + gpsdata->set |= DEVICE_SET; + return status; + } else if (STARTSWITH(classtag, "\"class\":\"WATCH\"")) { + status = json_watch_read(buf, &gpsdata->policy, end); + if (status == 0) + gpsdata->set |= POLICY_SET; + return status; + } else if (STARTSWITH(classtag, "\"class\":\"VERSION\"")) { + return json_version_read(buf, gpsdata, end); +#ifdef RTCM104V2_ENABLE + } else if (STARTSWITH(classtag, "\"class\":\"RTCM2\"")) { + status = json_rtcm2_read(buf, + gpsdata->dev.path, sizeof(gpsdata->dev.path), + &gpsdata->rtcm2, end); + if (status == 0) { + gpsdata->set &= ~UNION_SET; + gpsdata->set |= RTCM2_SET; + } + return status; +#endif /* RTCM104V2_ENABLE */ +#ifdef AIVDM_ENABLE + } else if (STARTSWITH(classtag, "\"class\":\"AIS\"")) { + status = json_ais_read(buf, + gpsdata->dev.path, sizeof(gpsdata->dev.path), + &gpsdata->ais, end); + if (status == 0) { + gpsdata->set &= ~UNION_SET; + gpsdata->set |= AIS_SET; + } + return status; +#endif /* AIVDM_ENABLE */ + } else if (STARTSWITH(classtag, "\"class\":\"ERROR\"")) { + return json_error_read(buf, gpsdata, end); + } else + return -1; +#undef STARTSWITH +} + +/*@+compdef@*/ + +/* libgps_json.c ends here */ diff --git a/libgpsd.pc.in b/libgpsd.pc.in new file mode 100644 index 0000000..afd67eb --- /dev/null +++ b/libgpsd.pc.in @@ -0,0 +1,9 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: libgpsd +Description: Lowlevel GPSD control library +Version: @VERSION@ +Libs: -L${libdir} -lgpsd diff --git a/libgpsd.xml b/libgpsd.xml new file mode 100644 index 0000000..0e7956b --- /dev/null +++ b/libgpsd.xml @@ -0,0 +1,167 @@ + + + + +14 Aug 2004 + +3 +3 +The GPSD Project +GPSD Documentation + + +libgpsd +service library for GPS applications + + + + +C: + +#include <gpsd.h> + + + + + +int gpsd_open_dgps + char * dgpsserver + + +void gpsd_init + struct gps_device_t *session + struct * gps_context_t * + char * device + + +int gpsd_activate + struct gps_device_t *session + + +void gpsd_deactivate + struct gps_device_t * session + + +gps_mask_t gpsd_poll + struct gps_device_t * session + + +void gpsd_wrap + struct gps_device_t * session + + + +void gpsd_report + int d + const char * fmt + ... + + + + +DESCRIPTION +libgpsd +is a service library which supports querying GPS devices; link it with +the linker option -lgpsd. It is a set of low-level +device-handling calls, which +gpsd1 +itself uses. See +gpsd3 +for a description of the high-level interface, which is almost +certainly what you want. + +Calling +gpsd_init() +initializes a session structure to hold the data collected by the GPS. + +The second argument must be a context structure. The library +will use it for information that need to be shared between sessions; +presently this includes the leap-second correction and possibly a +pointer to a shared-memory segment used to communicate with the +Network Time Protocol daemon. + +After the session structure has been set up, you may modify some +of its members. + + + +gpsd_device + +This member should hold the path name of the device. + + + +baudrate + +Communication speed in bits per second. For NMEA or SiRF devices, the +library automatically hunts through all plausible baud rates, stopping +on the one where it sees valid packets. By setting this field you can +designate a speed to be tried at the front of the hunt queue + + + +raw_hook + +A hook function to be executed on each NMEA +sentence or as it is read from the GPS. The data from non-NMEA GPSes like +the EarthMate will be translated to an NMEA sentence before being +passed to the hook. Parameters are a pointer to a gps_data structure +full of parsed data, the sentence, and the length of the sentene.. + + + + +gpsd_activate() +initializes the connection to the GPS. +gpsd_deactivate() +closes the connection. These functions are provided so that +long-running programs can release a connection when there is no +activity requiring the GPS, and re-acquire it later. + +gpsd_poll() +queries the GPS and updates the part of the session structure that +holds position, speed, GPS signal quality, and other data returned +by the GPS. It returns a mask describing which fields have changed. + +gpsd_wrap() +ends the session, implicitly performing a +gpsd_deactivate(). + +The calling application must define one additional function: +gpsd_report(). +The library will use this to issue ordinary status messages. Use +first argument of 0 for errors, 1 for ordinary status messages, +and 2 or higher for debugging messages. + +The low-level functions do not allocate or free any dynamic +storage. They can thus be used in a long-running application (such as +gpsd8 +itself) with a guarantee that they won't cause memory leaks. + + + +BUGS + +Writes to the context structure members are not guarded by +a mutex. + + + +SEE ALSO + +gpsd8, +gps1, +libgps3. + + + +AUTHOR +Eric S. Raymond <esr@thyrsus.com> based partly on earlier work by +Remco Treffkorn, Derrick Brashear, and Russ Nelson. + + + diff --git a/libgpsd_core.c b/libgpsd_core.c new file mode 100644 index 0000000..0ef5cac --- /dev/null +++ b/libgpsd_core.c @@ -0,0 +1,850 @@ +/* libgpsd_core.c -- direct access to GPSes on serial or USB devices. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include "gpsd_config.h" +#include +#ifdef HAVE_SYS_IOCTL_H +#include +#endif /* HAVE_SYS_IOCTL_H */ +#ifndef S_SPLINT_S +#ifdef HAVE_SYS_SOCKET_H +#include +#else +#define AF_UNSPEC 0 +#endif /* HAVE_SYS_SOCKET_H */ +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#ifndef S_SPLINT_S +#ifdef HAVE_NETDB_H +#include +#endif /* HAVE_NETDB_H */ +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd.h" + +#if defined(PPS_ENABLE) && defined(TIOCMIWAIT) +#ifndef S_SPLINT_S +#include /* pacifies OpenBSD's compiler */ +#endif +#endif + +int gpsd_switch_driver(struct gps_device_t *session, char *type_name) +{ + const struct gps_type_t **dp; + bool identified = (session->device_type != NULL); + + gpsd_report(LOG_PROG, "switch_driver(%s) called...\n", type_name); + if (identified && strcmp(session->device_type->type_name, type_name) == 0) + return 0; + + /*@ -compmempass @*/ + for (dp = gpsd_drivers; *dp; dp++) + if (strcmp((*dp)->type_name, type_name) == 0) { + gpsd_report(LOG_PROG, "selecting %s driver...\n", + (*dp)->type_name); + gpsd_assert_sync(session); + /*@i@*/ session->device_type = *dp; +#ifdef ALLOW_RECONFIGURE + session->gpsdata.dev.mincycle = session->device_type->min_cycle; +#endif /* ALLOW_RECONFIGURE */ + /* reconfiguration might be required */ + if (identified && session->device_type->event_hook != NULL) + session->device_type->event_hook(session, + event_driver_switch); + /* clients should be notified */ + session->notify_clients = true; + return 1; + } + gpsd_report(LOG_ERROR, "invalid GPS type \"%s\".\n", type_name); + return 0; + /*@ +compmempass @*/ +} + + +void gpsd_init(struct gps_device_t *session, struct gps_context_t *context, + char *device) +/* initialize GPS polling */ +{ + /*@ -mayaliasunique @*/ + if (device != NULL) + (void)strlcpy(session->gpsdata.dev.path, device, + sizeof(session->gpsdata.dev.path)); + /*@ -mustfreeonly @*/ + session->device_type = NULL; /* start by hunting packets */ + session->observed = 0; + session->rtcmtime = 0; + session->is_serial = false; /* gpsd_open() sets this */ + session->sourcetype = source_unknown; /* gpsd_open() sets this */ + /*@ -temptrans @*/ + session->context = context; + /*@ +temptrans @*/ + /*@ +mayaliasunique @*/ + /*@ +mustfreeonly @*/ + gps_clear_fix(&session->gpsdata.fix); + gps_clear_fix(&session->newdata); + gps_clear_fix(&session->oldfix); + session->gpsdata.set = 0; + session->gpsdata.dop.hdop = NAN; + session->gpsdata.dop.vdop = NAN; + session->gpsdata.dop.pdop = NAN; + session->gpsdata.dop.tdop = NAN; + session->gpsdata.dop.gdop = NAN; + session->gpsdata.epe = NAN; + session->mag_var = NAN; + session->gpsdata.dev.cycle = session->gpsdata.dev.mincycle = 1; + + /* tty-level initialization */ + gpsd_tty_init(session); + /* necessary in case we start reading in the middle of a GPGSV sequence */ + gpsd_zero_satellites(&session->gpsdata); + + /* initialize things for the packet parser */ + packet_reset(&session->packet); +} + +void gpsd_deactivate(struct gps_device_t *session) +/* temporarily release the GPS device */ +{ +#ifdef NTPSHM_ENABLE + (void)ntpshm_free(session->context, session->shmindex); + session->shmindex = -1; +# ifdef PPS_ENABLE + (void)ntpshm_free(session->context, session->shmTimeP); + session->shmTimeP = -1; +# endif /* PPS_ENABLE */ +#endif /* NTPSHM_ENABLE */ +#ifdef ALLOW_RECONFIGURE + if (!session->context->readonly + && session->device_type != NULL + && session->device_type->event_hook != NULL) { + session->device_type->event_hook(session, event_deactivate); + } + if (session->device_type != NULL) { + if (session->back_to_nmea + && session->device_type->mode_switcher != NULL) + session->device_type->mode_switcher(session, 0); + } +#endif /* ALLOW_RECONFIGURE */ + gpsd_report(LOG_INF, "closing GPS=%s (%d)\n", + session->gpsdata.dev.path, session->gpsdata.gps_fd); + (void)gpsd_close(session); +} + +#if defined(PPS_ENABLE) && defined(TIOCMIWAIT) +static /*@null@*/ void *gpsd_ppsmonitor(void *arg) +{ + struct gps_device_t *session = (struct gps_device_t *)arg; + int cycle, duration, state = 0, laststate = -1, unchanged = 0; + struct timeval tv; + struct timeval pulse[2] = { {0, 0}, {0, 0} }; + +#if defined(PPS_ON_CTS) + int pps_device = TIOCM_CTS; +#define pps_device_str "CTS" +#else + int pps_device = TIOCM_CAR; +#define pps_device_str "DCD" +#endif + + gpsd_report(LOG_PROG, "PPS Create Thread gpsd_ppsmonitor\n"); + + /* wait for status change on the device's carrier-detect line */ + while (ioctl(session->gpsdata.gps_fd, TIOCMIWAIT, pps_device) == 0) { + int ok = 0; + char *log = NULL; + + (void)gettimeofday(&tv, NULL); + + ok = 0; + log = NULL; + + /*@ +ignoresigns */ + if (ioctl(session->gpsdata.gps_fd, TIOCMGET, &state) != 0) + break; + /*@ -ignoresigns */ + + state = (int)((state & pps_device) != 0); + /*@ +boolint @*/ +#define timediff(x, y) (int)((x.tv_sec-y.tv_sec)*1000000+x.tv_usec-y.tv_usec) + cycle = timediff(tv, pulse[state]); + duration = timediff(tv, pulse[(int)(state == 0)]); +#undef timediff + /*@ -boolint @*/ + + if (state == laststate) { + /* some pulses may be so short that state never changes */ + if (999000 < cycle && 1001000 > cycle) { + duration = 0; + unchanged = 0; + gpsd_report(LOG_RAW, + "PPS pps-detect (%s) on %s invisible pulse\n", + pps_device_str, session->gpsdata.dev.path); + } else if (++unchanged == 10) { + unchanged = 1; + gpsd_report(LOG_WARN, + "PPS TIOCMIWAIT returns unchanged state, ppsmonitor sleeps 10\n"); + (void)sleep(10); + } + } else { + gpsd_report(LOG_RAW, "PPS pps-detect (%s) on %s changed to %d\n", + pps_device_str, session->gpsdata.dev.path, state); + laststate = state; + unchanged = 0; + } + pulse[state] = tv; + if (unchanged) { + // strange, try again + continue; + } + gpsd_report(LOG_INF, "PPS cycle: %d, duration: %d @ %lu.%06lu\n", + cycle, duration, + (unsigned long)tv.tv_sec, (unsigned long)tv.tv_usec); + + /*@ +boolint @*/ + if (3 < session->context->fixcnt) { + /* Garmin doc says PPS is valid after four good fixes. */ + /* + * The PPS pulse is normally a short pulse with a frequency of + * 1 Hz, and the UTC second is defined by the front edge. But we + * don't know the polarity of the pulse (different receivers + * emit different polarities). The duration variable is used to + * determine which way the pulse is going. The code assumes + * that the UTC second is changing when the signal has not + * been changing for at least 800ms, i.e. it assumes the duty + * cycle is at most 20%. + * + * Some GPS instead output a square wave that is 0.5 Hz and each + * edge denotes the start of a second. + * + * Some GPS, like the Globalsat MR-350P, output a 1uS pulse. + * The pulse is so short that TIOCMIWAIT sees a state change + * but by the time TIOCMGET is called the pulse is gone. + * + * A few stupid GPS, like the Furuno GPSClock, output a 1.0 Hz + * square wave where the leading edge is the start of a second + * + * 5Hz GPS (Garmin 18-5Hz) pulses at 5Hz. Set the pulse length to + * 40ms which gives a 160ms pulse before going high. + * + */ + + if (199000 > cycle) { + // too short to even be a 5Hz pulse + log = "Too short for 5Hz\n"; + } else if (201000 > cycle) { + /* 5Hz cycle */ + /* looks like 5hz PPS pulse */ + if (100000 > duration) { + /* BUG: how does the code know to tell ntpd + * which 1/5 of a second to use?? */ + ok = 1; + log = "5Hz PPS pulse\n"; + } + } else if (999000 > cycle) { + log = "Too long for 5Hz, too short for 1Hz\n"; + } else if (1001000 > cycle) { + /* looks like PPS pulse or square wave */ + if (0 == duration) { + ok = 1; + log = "PPS invisible pulse\n"; + } else if (499000 > duration) { + /* end of the short "half" of the cycle */ + /* aka the trailing edge */ + log = "PPS 1Hz trailing edge\n"; + } else if (501000 > duration) { + /* looks like 1.0 Hz square wave, ignore trailing edge */ + if (state == 1) { + ok = 1; + log = "PPS square\n"; + } + } else { + /* end of the long "half" of the cycle */ + /* aka the leading edge */ + ok = 1; + log = "PPS 1Hz leading edge\n"; + } + } else if (1999000 > cycle) { + log = "Too long for 1Hz, too short for 2Hz\n"; + } else if (2001000 > cycle) { + /* looks like 0.5 Hz square wave */ + if (999000 > duration) { + log = "PPS 0.5 Hz square too short duration\n"; + } else if (1001000 > duration) { + ok = 1; + log = "PPS 0.5 Hz square wave\n"; + } else { + log = "PPS 0.5 Hz square too long duration\n"; + } + } else { + log = "Too long for 0.5Hz\n"; + } + } else { + /* not a good fix, but a test for an otherwise good PPS + * would go here */ + log = "PPS no fix.\n"; + } + /*@ -boolint @*/ + if (NULL != log) { + gpsd_report(LOG_RAW, "%s\n", log); + } + if (0 != ok) { + (void)ntpshm_pps(session, &tv); + } else { + gpsd_report(LOG_INF, "PPS pulse rejected\n"); + } + + } + + return NULL; +} +#endif /* PPS_ENABLE */ + +/*@ -branchstate @*/ +int gpsd_activate(struct gps_device_t *session) +/* acquire a connection to the GPS device */ +{ + /* special case: source may be a URI to a remote GNSS or DGPS service */ + if (netgnss_uri_check(session->gpsdata.dev.path)) { + session->gpsdata.gps_fd = netgnss_uri_open(session->context, + session->gpsdata.dev.path); + session->sourcetype = source_tcp; + gpsd_report(LOG_SPIN, + "netgnss_uri_open(%s) returns socket on fd %d\n", + session->gpsdata.dev.path, session->gpsdata.gps_fd); + /* otherwise, could be an TCP data feed */ + } else if (strncmp(session->gpsdata.dev.path, "tcp://", 6) == 0) { + char server[GPS_PATH_MAX], *port; + socket_t dsock; + (void)strlcpy(server, session->gpsdata.dev.path + 6, sizeof(server)); + session->gpsdata.gps_fd = -1; + port = strchr(server, ':'); + if (port == NULL) { + gpsd_report(LOG_ERROR, "Missing colon in TCP feed spec.\n"); + return -1; + } + *port++ = '\0'; + gpsd_report(LOG_INF, "opening TCP feed at %s, port %s.\n", server, + port); + if ((dsock = netlib_connectsock(AF_UNSPEC, server, port, "tcp")) < 0) { + gpsd_report(LOG_ERROR, "TCP device open error %s.\n", + netlib_errstr(dsock)); + return -1; + } + session->gpsdata.gps_fd = dsock; + session->sourcetype = source_tcp; + } else if (strncmp(session->gpsdata.dev.path, "udp://", 6) == 0) { + char server[GPS_PATH_MAX], *port; + socket_t dsock; + (void)strlcpy(server, session->gpsdata.dev.path + 6, sizeof(server)); + session->gpsdata.gps_fd = -1; + port = strchr(server, ':'); + if (port == NULL) { + gpsd_report(LOG_ERROR, "Missing colon in UDP feed spec.\n"); + return -1; + } + *port++ = '\0'; + gpsd_report(LOG_INF, "opening UDP feed at %s, port %s.\n", server, + port); + if ((dsock = netlib_connectsock(AF_UNSPEC, server, port, "udp")) < 0) { + gpsd_report(LOG_ERROR, "UDP device open error %s.\n", + netlib_errstr(dsock)); + return -1; + } + session->gpsdata.gps_fd = dsock; + session->sourcetype = source_udp; + } + /* otherwise, ordinary serial device */ + else + session->gpsdata.gps_fd = gpsd_open(session); + + if (session->gpsdata.gps_fd < 0) + return -1; + else { +#ifdef NON_NMEA_ENABLE + const struct gps_type_t **dp; + + /*@ -mustfreeonly @*/ + for (dp = gpsd_drivers; *dp; dp++) { + (void)tcflush(session->gpsdata.gps_fd, TCIOFLUSH); /* toss stale data */ + if ((*dp)->probe_detect != NULL + && (*dp)->probe_detect(session) != 0) { + gpsd_report(LOG_PROG, "probe found %s driver...\n", + (*dp)->type_name); + session->device_type = *dp; + gpsd_assert_sync(session); + goto foundit; + } + } + /*@ +mustfreeonly @*/ + gpsd_report(LOG_PROG, "no probe matched...\n"); + foundit: +#endif /* NON_NMEA_ENABLE */ + session->gpsdata.online = timestamp(); +#ifdef SIRF_ENABLE + session->driver.sirf.satcounter = 0; +#endif /* SIRF_ENABLE */ + packet_init(&session->packet); + gpsd_report(LOG_INF, + "gpsd_activate(): opened GPS (fd %d)\n", + session->gpsdata.gps_fd); + // session->gpsdata.online = 0; + session->gpsdata.fix.mode = MODE_NOT_SEEN; + session->gpsdata.status = STATUS_NO_FIX; + session->gpsdata.fix.track = NAN; + session->gpsdata.separation = NAN; + session->mag_var = NAN; + session->releasetime = 0; + session->getcount = 0; + + /* clear the private data union */ + memset(&session->driver, '\0', sizeof(session->driver)); + /* + * We might know the device's type, but we shoudn't assume it has + * retained its settings. A revert hook might well have undone + * them on the previous close. Fire a reactivate event so drivers + * can do something about this if they choose. + */ + if (session->device_type != NULL + && session->device_type->event_hook != NULL) + session->device_type->event_hook(session, event_reactivate); + } + + session->opentime = timestamp(); + return session->gpsdata.gps_fd; +} + +/*@ +branchstate @*/ + +void ntpd_link_activate(struct gps_device_t *session) +{ +#if defined(PPS_ENABLE) && defined(TIOCMIWAIT) + pthread_t pt; +#endif /* defined(PPS_ENABLE) && defined(TIOCMIWAIT) */ + +#ifdef NTPSHM_ENABLE + /* If we are talking to ntpd, allocate a shared-memory segment for "NMEA" time data */ + if (session->context->enable_ntpshm) + session->shmindex = ntpshm_alloc(session->context); + + if (0 > session->shmindex) { + gpsd_report(LOG_INF, "NTPD ntpshm_alloc() failed\n"); +#if defined(PPS_ENABLE) && defined(TIOCMIWAIT) + } else if (session->context->shmTimePPS) { + /* We also have the 1pps capability, allocate a shared-memory segment + * for the 1pps time data and launch a thread to capture the 1pps + * transitions + */ + if ((session->shmTimeP = ntpshm_alloc(session->context)) >= 0) { + /*@-unrecog@*/ + (void)pthread_create(&pt, NULL, gpsd_ppsmonitor, (void *)session); + /*@+unrecog@*/ + } else { + gpsd_report(LOG_INF, "NTPD ntpshm_alloc(1) failed\n"); + } + +#endif /* defined(PPS_ENABLE) && defined(TIOCMIWAIT) */ + } +#endif /* NTPSHM_ENABLE */ +} + +char /*@observer@*/ *gpsd_id( /*@in@ */ struct gps_device_t *session) +/* full ID of the device for reports, including subtype */ +{ + static char buf[128]; + if ((session == NULL) || (session->device_type == NULL) || + (session->device_type->type_name == NULL)) + return "unknown,"; + (void)strlcpy(buf, session->device_type->type_name, sizeof(buf)); + if (session->subtype[0] != '\0') { + (void)strlcat(buf, " ", sizeof(buf)); + (void)strlcat(buf, session->subtype, sizeof(buf)); + } + return (buf); +} + +static void gpsd_error_model(struct gps_device_t *session, + struct gps_fix_t *fix, struct gps_fix_t *oldfix) +/* compute errors and derived quantities */ +{ + /* + * Now we compute derived quantities. This is where the tricky error- + * modeling stuff goes. Presently we don't know how to derive + * time error. + * + * Some drivers set the position-error fields. Only the Zodiacs + * report speed error. Nobody reports track error or climb error. + * + * The UERE constants are our assumption about the base error of + * GPS fixes in different directions. + */ +#define H_UERE_NO_DGPS 15.0 /* meters, 95% confidence */ +#define H_UERE_WITH_DGPS 3.75 /* meters, 95% confidence */ +#define V_UERE_NO_DGPS 23.0 /* meters, 95% confidence */ +#define V_UERE_WITH_DGPS 5.75 /* meters, 95% confidence */ +#define P_UERE_NO_DGPS 19.0 /* meters, 95% confidence */ +#define P_UERE_WITH_DGPS 4.75 /* meters, 95% confidence */ + double h_uere, v_uere, p_uere; + + if (NULL == session) + return; + + h_uere = + (session->gpsdata.status == + STATUS_DGPS_FIX ? H_UERE_WITH_DGPS : H_UERE_NO_DGPS); + v_uere = + (session->gpsdata.status == + STATUS_DGPS_FIX ? V_UERE_WITH_DGPS : V_UERE_NO_DGPS); + p_uere = + (session->gpsdata.status == + STATUS_DGPS_FIX ? P_UERE_WITH_DGPS : P_UERE_NO_DGPS); + + /* + * OK, this is not an error computation, but we're at the right + * place in the architecture for it. Compute speed over ground + * and climb/sink in the simplest possible way. + */ + if (fix->mode >= MODE_2D && oldfix->mode >= MODE_2D + && isnan(fix->speed) != 0) { + if (fix->time == oldfix->time) + fix->speed = 0; + else + fix->speed = + earth_distance(fix->latitude, fix->longitude, + oldfix->latitude, oldfix->longitude) + / (fix->time - oldfix->time); + } + if (fix->mode >= MODE_3D && oldfix->mode >= MODE_3D + && isnan(fix->climb) != 0) { + if (fix->time == oldfix->time) + fix->climb = 0; + else if (isnan(fix->altitude) == 0 && isnan(oldfix->altitude) == 0) { + fix->climb = + (fix->altitude - oldfix->altitude) / (fix->time - + oldfix->time); + } + } + + /* + * Field reports match the theoretical prediction that + * expected time error should be half the resolution of + * the GPS clock, so we put the bound of the error + * in as a constant pending getting it from each driver. + */ + if (isnan(fix->time) == 0 && isnan(fix->ept) != 0) + fix->ept = 0.005; + /* Other error computations depend on having a valid fix */ + gpsd_report(LOG_DATA, "modeling errors: mode=%d, masks=%s\n", + fix->mode, gpsd_maskdump(session->gpsdata.set)); + if (fix->mode >= MODE_2D) { + if (isnan(fix->epx) != 0 && finite(session->gpsdata.dop.hdop) != 0) + fix->epx = session->gpsdata.dop.xdop * h_uere; + + if (isnan(fix->epy) != 0 && finite(session->gpsdata.dop.hdop) != 0) + fix->epy = session->gpsdata.dop.ydop * h_uere; + + if ((fix->mode >= MODE_3D) + && isnan(fix->epv) != 0 && finite(session->gpsdata.dop.vdop) != 0) + fix->epv = session->gpsdata.dop.vdop * v_uere; + + if (isnan(session->gpsdata.epe) != 0 + && finite(session->gpsdata.dop.pdop) != 0) + session->gpsdata.epe = session->gpsdata.dop.pdop * p_uere; + else + session->gpsdata.epe = NAN; + + /* + * If we have a current fix and an old fix, and the packet handler + * didn't set the speed error and climb error members itself, + * try to compute them now. + */ + if (isnan(fix->eps) != 0) { + if (oldfix->mode > MODE_NO_FIX && fix->mode > MODE_NO_FIX + && isnan(oldfix->epx) == 0 && isnan(oldfix->epy) == 0 + && isnan(oldfix->time) == 0 && isnan(oldfix->time) == 0 + && fix->time > oldfix->time) { + double t = fix->time - oldfix->time; + double e = + EMIX(oldfix->epx, oldfix->epy) + EMIX(fix->epx, fix->epy); + fix->eps = e / t; + } else + fix->eps = NAN; + } + if ((fix->mode >= MODE_3D) + && isnan(fix->epc) != 0 && fix->time > oldfix->time) { + if (oldfix->mode > MODE_3D && fix->mode > MODE_3D) { + double t = fix->time - oldfix->time; + double e = oldfix->epv + fix->epv; + /* if vertical uncertainties are zero this will be too */ + fix->epc = e / t; + } + /* + * We compute a track error estimate solely from the + * position of this fix and the last one. The maximum + * track error, as seen from the position of last fix, is + * the angle subtended by the two most extreme possible + * error positions of the current fix; the expected track + * error is half that. Let the position of the old fix be + * A and of the new fix B. We model the view from A as + * two right triangles ABC and ABD with BC and BD both + * having the length of the new fix's estimated error. + * adj = len(AB), opp = len(BC) = len(BD), hyp = len(AC) = + * len(AD). This leads to spurious uncertainties + * near 180 when we're moving slowly; to avoid reporting + * garbage, throw back NaN if the distance from the previous + * fix is less than the error estimate. + */ + fix->epd = NAN; + if (oldfix->mode >= MODE_2D) { + double adj = + earth_distance(oldfix->latitude, oldfix->longitude, + fix->latitude, fix->longitude); + if (isnan(adj) == 0 && adj > EMIX(fix->epx, fix->epy)) { + double opp = EMIX(fix->epx, fix->epy); + double hyp = sqrt(adj * adj + opp * opp); + fix->epd = RAD_2_DEG * 2 * asin(opp / hyp); + } + } + } + } + + /* save old fix for later error computations */ + /*@ -mayaliasunique @*/ + if (fix->mode >= MODE_2D) + (void)memcpy(oldfix, fix, sizeof(struct gps_fix_t)); + /*@ +mayaliasunique @*/ +} + +gps_mask_t gpsd_poll(struct gps_device_t *session) +/* update the stuff in the scoreboard structure */ +{ + ssize_t newlen; + bool first_sync = false; + + gps_clear_fix(&session->newdata); + +#ifdef TIMING_ENABLE + if (session->packet.outbuflen == 0) + session->d_xmit_time = timestamp(); +#endif /* TIMING_ENABLE */ + + if (session->packet.type >= COMMENT_PACKET) { + /*@-shiftnegative@*/ + session->observed |= PACKET_TYPEMASK(session->packet.type); + /*@+shiftnegative@*/ + } + + /* can we get a full packet from the device? */ + if (session->device_type) { + newlen = session->device_type->get_packet(session); + gpsd_report(LOG_RAW, + "%s is known to be %s\n", + session->gpsdata.dev.path, + session->device_type->type_name); + } else { + const struct gps_type_t **dp; + + newlen = generic_get(session); + gpsd_report(LOG_RAW, + "packet sniff on %s finds type %d\n", + session->gpsdata.dev.path, session->packet.type); + if (session->packet.type == COMMENT_PACKET) { + gpsd_report (LOG_PROG, "comment, sync lock deferred\n"); + } else if (session->packet.type > COMMENT_PACKET) { + first_sync = (session->device_type == NULL); + for (dp = gpsd_drivers; *dp; dp++) + if (session->packet.type == (*dp)->packet_type) { + (void)gpsd_switch_driver(session, (*dp)->type_name); + break; + } + } else if (session->getcount++ > 1 && !gpsd_next_hunt_setting(session)) + return ERROR_IS; + } + + /* update the scoreboard structure from the GPS */ + gpsd_report(LOG_RAW + 2, "%s sent %zd new characters\n", + session->gpsdata.dev.path, newlen); + if (newlen < 0) { /* read error */ + gpsd_report(LOG_INF, "GPS on %s returned error %zd (%lf sec since data)\n", + session->gpsdata.dev.path, newlen, + timestamp() - session->gpsdata.online); + session->gpsdata.online = 0; + return ERROR_IS; + } else if (newlen == 0) { /* zero length read, possible EOF */ + gpsd_report(LOG_INF, "GPS on %s is offline (%lf sec since data)\n", + session->gpsdata.dev.path, + timestamp() - session->gpsdata.online); + session->gpsdata.online = 0; + return NODATA_IS; + } else if (session->packet.outbuflen == 0) { /* got new data, but no packet */ + gpsd_report(LOG_RAW + 3, "New data on %s, not yet a packet\n", + session->gpsdata.dev.path); + return ONLINE_IS; + } else { /* we have recognized a packet */ + gps_mask_t received = PACKET_IS, dopmask = 0; + session->gpsdata.online = timestamp(); + + gpsd_report(LOG_RAW + 3, "Accepted packet on %s.\n", + session->gpsdata.dev.path); + +#ifdef TIMING_ENABLE + session->d_recv_time = timestamp(); +#endif /* TIMING_ENABLE */ + + /* track the packet count since achieving sync on the device */ + if (first_sync) { + /*@-nullderef@*/ + gpsd_report(LOG_INF, + "%s identified as type %s (%f sec @ %dbps)\n", + session->gpsdata.dev.path, + session->device_type->type_name, + timestamp() - session->opentime, + gpsd_get_speed(&session->ttyset)); + /*@+nullderef@*/ + /* fire the identified hook */ + if (session->device_type != NULL + && session->device_type->event_hook != NULL) + session->device_type->event_hook(session, event_identified); + session->packet.counter = 0; + } else + session->packet.counter++; + + /* fire the configure hook */ + if (session->device_type != NULL + && session->device_type->event_hook != NULL) + session->device_type->event_hook(session, event_configure); + + /* + * If this is the first time we've achieved sync on this + * device, or the driver type has changed for any other + * reason, that's a significant event that the caller needs to + * know about. + */ + if (first_sync || session->notify_clients) { + session->notify_clients = false; + received |= DRIVER_IS; + } + + /* Get data from current packet into the fix structure */ + if (session->packet.type != COMMENT_PACKET) + if (session->device_type != NULL + && session->device_type->parse_packet != NULL) + received |= session->device_type->parse_packet(session); + +#ifdef NTPSHM_ENABLE + /* + * Only update the NTP time if we've seen the leap-seconds data. + * Else we may be providing GPS time. + */ + if (session->context->enable_ntpshm == 0) { + //gpsd_report(LOG_PROG, "NTP: off\n"); + } else if ((received & TIME_IS) == 0) { + //gpsd_report(LOG_PROG, "NTP: No time this packet\n"); + } else if (isnan(session->newdata.time)) { + //gpsd_report(LOG_PROG, "NTP: bad new time\n"); + } else if (session->newdata.time == session->last_fixtime) { + //gpsd_report(LOG_PROG, "NTP: Not a new time\n"); + } else if (session->newdata.mode == MODE_NO_FIX) { + //gpsd_report(LOG_PROG, "NTP: No fix\n"); + } else { + double offset; + //gpsd_report(LOG_PROG, "NTP: Got one\n"); + /* assume zero when there's no offset method */ + if (session->device_type == NULL + || session->device_type->ntp_offset == NULL) + offset = 0.0; + else + offset = session->device_type->ntp_offset(session); + (void)ntpshm_put(session, session->newdata.time, offset); + session->last_fixtime = session->newdata.time; + } +#endif /* NTPSHM_ENABLE */ + + /* + * Compute fix-quality data from the satellite positions. + * These will not overwrite any DOPs reported from the packet + * we just got. + */ + if ((received & SATELLITE_IS) != 0 + && session->gpsdata.satellites_visible > 0) { + dopmask = fill_dop(&session->gpsdata, &session->gpsdata.dop); + session->gpsdata.epe = NAN; + } + session->gpsdata.set = ONLINE_IS | dopmask | received; + + /* copy/merge device data into staging buffers */ + /*@-nullderef -nullpass@*/ + if ((session->gpsdata.set & CLEAR_IS) != 0) + gps_clear_fix(&session->gpsdata.fix); + /* don't downgrade mode if holding previous fix */ + if (session->gpsdata.fix.mode > session->newdata.mode) + session->gpsdata.set &= ~MODE_IS; + //gpsd_report(LOG_PROG, + // "transfer mask on %s: %02x\n", session->gpsdata.tag, session->gpsdata.set); + gps_merge_fix(&session->gpsdata.fix, + session->gpsdata.set, &session->newdata); + gpsd_error_model(session, &session->gpsdata.fix, &session->oldfix); + /*@+nullderef -nullpass@*/ + + /* + * Count good fixes. We used to check + * session->gpsdata.status > STATUS_NO_FIX + * here, but that wasn't quite right. That tells us whether + * we think we have a valid fix for the current cycle, but remains + * true while following non-fix packets are received. What we + * really want to know is whether the last packet received was a + * fix packet AND held a valid fix. We must ignore non-fix packets + * AND packets which have fix data but are flagged as invalid. Some + * devices output fix packets on a regular basis, even when unable + * to derive a good fix. Such packets should set STATUS_NO_FIX. + */ + if ((session->gpsdata.set & LATLON_IS) != 0 + && session->gpsdata.status > STATUS_NO_FIX) + session->context->fixcnt++; + +#ifdef TIMING_ENABLE + session->d_decode_time = timestamp(); +#endif /* TIMING_ENABLE */ + + /* + * Sanity check. This catches a surprising number of port and + * driver errors, including 32-vs.-64-bit problems. + */ + /*@+relaxtypes +longunsignedintegral@*/ + if ((session->gpsdata.set & TIME_IS) != 0) { + if (session->newdata.time > time(NULL) + (60 * 60 * 24 * 365)) + gpsd_report(LOG_ERROR, + "date more than a year in the future!\n"); + else if (session->newdata.time < 0) + gpsd_report(LOG_ERROR, "date is negative!\n"); + } + /*@-relaxtypes -longunsignedintegral@*/ + + return session->gpsdata.set; + } +} + +void gpsd_wrap(struct gps_device_t *session) +/* end-of-session wrapup */ +{ + if (session->gpsdata.gps_fd != -1) + gpsd_deactivate(session); +} + +void gpsd_zero_satellites( /*@out@*/ struct gps_data_t *out) +{ + (void)memset(out->PRN, 0, sizeof(out->PRN)); + (void)memset(out->elevation, 0, sizeof(out->elevation)); + (void)memset(out->azimuth, 0, sizeof(out->azimuth)); + (void)memset(out->ss, 0, sizeof(out->ss)); + out->satellites_visible = 0; + clear_dop(&out->dop); +} diff --git a/libgpsmm.cpp b/libgpsmm.cpp new file mode 100644 index 0000000..45c7016 --- /dev/null +++ b/libgpsmm.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2005 Alfredo Pironti + * + * This software is distributed under a BSD-style license. See the + * file "COPYING" in the top-level directory of the disribution for details. + * + */ +#include + +#include "gpsd_config.h" +#include "libgpsmm.h" + +gpsmm::gpsmm() : gps_data(0) { gps_data = NULL; } + +struct gps_data_t* gpsmm::open(void) { + return open("localhost",DEFAULT_GPSD_PORT); +} + +struct gps_data_t* gpsmm::open(const char *host, const char *port) { + gps_data=gps_open(host,port); + if (gps_data==NULL) { //connection not opened + return NULL; + } + else { //connection succesfully opened + to_user= new struct gps_data_t; + return backup(); //we return the backup of our internal structure + } +} + +struct gps_data_t* gpsmm::stream(int flags) { + if (gps_stream(gps_data,flags, NULL)==-1) { + return NULL; + } + else { + return backup(); + } +} + +struct gps_data_t* gpsmm::send(const char *request) { + if (gps_send(gps_data,request)==-1) { + return NULL; + } + else { + return backup(); + } +} + +struct gps_data_t* gpsmm::poll(void) { + if (gps_poll(gps_data)<0) { + // we return null if there was a read() error or connection is cloed by gpsd + return NULL; + } + else { + return backup(); + } +} + +int gpsmm::close(void) { + return gps_close(gps_data); +} + +bool gpsmm::waiting(void) { + return gps_waiting(gps_data); +} + +void gpsmm::clear_fix(void) { + gps_clear_fix(&(gps_data->fix)); +} + +void gpsmm::enable_debug(int level, FILE *fp) { +#ifdef CLIENTDEBUG_ENABLE + gps_enable_debug(level, fp); +#endif /* CLIENTDEBUG_ENABLE */ +} + +gpsmm::~gpsmm() { + if (gps_data!=NULL) { + gps_close(gps_data); + delete to_user; + } +} diff --git a/libgpsmm.h b/libgpsmm.h new file mode 100644 index 0000000..b5cf003 --- /dev/null +++ b/libgpsmm.h @@ -0,0 +1,38 @@ +#ifndef _GPSD_GPSMM_H_ +#define _GPSD_GPSMM_H_ + +/* + * Copyright (C) 2005 Alfredo Pironti + * + * This software is distributed under a BSD-style license. See the + * file "COPYING" in the toop-level directory of the distribution for details. + * + */ +#include +#include "gps.h" //the C library we are going to wrap + +#ifndef USE_QT +class gpsmm { +#else +#include "libQgpsmm_global.h" +class LIBQGPSMMSHARED_EXPORT gpsmm { +#endif + public: + gpsmm(); + virtual ~gpsmm(); + struct gps_data_t* open(const char *host,const char *port); //opens the connection with gpsd, MUST call this before any other method + struct gps_data_t* open(void); //open() with default values + struct gps_data_t* send(const char *request); //put a command to gpsd and return the updated struct + struct gps_data_t* stream(int); //set watcher and policy flags + struct gps_data_t* poll(void); //block until gpsd returns new data, then return the updated struct + int close(void); // close the GPS + bool waiting(void); //nonblocking check for data waitin + void clear_fix(void); + void enable_debug(int, FILE*); + private: + struct gps_data_t *gps_data; + struct gps_data_t *to_user; //we return the user a copy of the internal structure. This way she can modify it without + //integrity loss for the entire class + struct gps_data_t* backup(void) { *to_user=*gps_data; return to_user;}; //return the backup copy +}; +#endif // _GPSD_GPSMM_H_ diff --git a/libgpsmm.xml b/libgpsmm.xml new file mode 100644 index 0000000..5e987d5 --- /dev/null +++ b/libgpsmm.xml @@ -0,0 +1,87 @@ + + + + +13 May 2005 + +libgpsmm +3 +The GPSD Project +GPSD Documentation + + +libgpsmm +libQgpsmm +C++ and QT class wrapper for the GPS daemon + + + + + +C++: + +#include <libgpsmm> + + + +struct gps_data_t *open + char *host + char *port + + +struct gps_data_t *open + void + + +struct gps_data_t *query + char *request + + +struct gps_data_t *poll + void + + +int set_callback + void (*hook)(struct gps_data_t *sentence, char *buf) + + +int del_callback + void + + +struct gps_data_t *stream + unsigned intflags + + + + +DESCRIPTION + +libgpsmm and libQgpsmm are mere wrappers over + libgps. The important difference between the libraries is that libgpsmm is targeted at C++ applications and contained in libgps, while libQgpsmm is platform independant by using QTcpSocket to connect to gpsd and shipped as an additional library due to the necessary linking to QT. +Method names are the same as +the analogue C functions. For a detailed description of the functions +please read +libgps3. +open() must be called after class constructor and before any other method +(open() is not inside the constructor since it may fail, however constructors have no return value). +The analogue of the C function gps_close() is in the destructor. + + +SEE ALSO + +gpsd8, +gps1, +libgps3. + + + +AUTHOR +Alfredo Pironti <alfredio@users.sourceforge.net>. + + + diff --git a/ltmain.sh b/ltmain.sh new file mode 100755 index 0000000..d88da2c --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,8413 @@ +# Generated from ltmain.m4sh. + +# ltmain.sh (GNU libtool) 2.2.6b +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print informational messages (default) +# --version print version information +# -h, --help print short or long help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION="2.2.6b Debian-2.2.6b-2" +TIMESTAMP="" +package_revision=1.3017 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# NLS nuisances: We save the old values to restore during execute mode. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done + +$lt_unset CDPATH + + + + + +: ${CP="cp -f"} +: ${ECHO="echo"} +: ${EGREP="/bin/grep -E"} +: ${FGREP="/bin/grep -F"} +: ${GREP="/bin/grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="/bin/sed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + +# Generated shell functions inserted here. + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +# In the unlikely event $progname began with a '-', it would play havoc with +# func_echo (imagine progname=-n), so we prepend ./ in that case: +func_dirname_and_basename "$progpath" +progname=$func_basename_result +case $progname in + -*) progname=./$progname ;; +esac + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname${mode+: }$mode: $*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` + done + my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "X$my_tmpdir" | $Xsed +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "X$1" | $Xsed \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + + + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $SED -n '/^# Usage:/,/# -h/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + $ECHO + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help +# Echo long help message to standard output and exit. +func_help () +{ + $SED -n '/^# Usage:/,/# Report bugs to/ { + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + }' < "$progpath" + exit $? +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + func_error "missing argument for $1" + exit_cmd=exit +} + +exit_cmd=: + + + + + +# Check that we have a working $ECHO. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell, and then maybe $ECHO will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# Parse options once, thoroughly. This comes as soon as possible in +# the script to make things like `libtool --version' happen quickly. +{ + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Parse non-mode specific arguments: + while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --config) func_config ;; + + --debug) preserve_args="$preserve_args $opt" + func_echo "enabling shell trace mode" + opt_debug='set -x' + $opt_debug + ;; + + -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break + execute_dlfiles="$execute_dlfiles $1" + shift + ;; + + --dry-run | -n) opt_dry_run=: ;; + --features) func_features ;; + --finish) mode="finish" ;; + + --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break + case $1 in + # Valid mode arguments: + clean) ;; + compile) ;; + execute) ;; + finish) ;; + install) ;; + link) ;; + relink) ;; + uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; + esac + + mode="$1" + shift + ;; + + --preserve-dup-deps) + opt_duplicate_deps=: ;; + + --quiet|--silent) preserve_args="$preserve_args $opt" + opt_silent=: + ;; + + --verbose| -v) preserve_args="$preserve_args $opt" + opt_silent=false + ;; + + --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break + preserve_args="$preserve_args $opt $1" + func_enable_tag "$1" # tagname is set here + shift + ;; + + # Separate optargs to long options: + -dlopen=*|--mode=*|--tag=*) + func_opt_split "$opt" + set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} + shift + ;; + + -\?|-h) func_usage ;; + --help) opt_help=: ;; + --version) func_version ;; + + -*) func_fatal_help "unrecognized option \`$opt'" ;; + + *) nonopt="$opt" + break + ;; + esac + done + + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_duplicate_deps + ;; + esac + + # Having warned about all mis-specified options, bail out if + # anything was wrong. + $exit_cmd $EXIT_FAILURE +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +## ----------- ## +## Main. ## +## ----------- ## + +$opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + test -z "$mode" && func_fatal_error "error: you must specify a MODE." + + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$mode' for more information." +} + + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_ltwrapper_scriptname_result="" + if func_ltwrapper_executable_p "$1"; then + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" + fi +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case "$@ " in + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + removelist="$removelist $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + removelist="$removelist $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + command="$command -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { +test "$mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$mode'" + ;; + esac + + $ECHO + $ECHO "Try \`$progname --help' for more information about other modes." + + exit $? +} + + # Now that we've collected a possible --mode arg, show help if necessary + $opt_help && func_mode_help + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_quote_for_eval "$file" + args="$args $func_quote_for_eval_result" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + $ECHO "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + $ECHO "X----------------------------------------------------------------------" | $Xsed + $ECHO "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + $ECHO + $ECHO "If you ever happen to want to link against installed libraries" + $ECHO "in a given directory, LIBDIR, you must either use libtool, and" + $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" + $ECHO "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" + $ECHO " during execution" + fi + if test -n "$runpath_var"; then + $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" + $ECHO " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $ECHO + + $ECHO "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" + $ECHO "pages." + ;; + *) + $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + $ECHO "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS +} + +test "$mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $ECHO "X$nonopt" | $GREP shtool >/dev/null; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + install_prog="$install_prog$func_quote_for_eval_result" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + install_prog="$install_prog $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_verbose "extracting global C symbols from \`$progfile'" + $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + $ECHO >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +" + case $host in + *cygwin* | *mingw* | *cegcc* ) + $ECHO >> "$output_objdir/$my_dlsyms" "\ +/* DATA imports from DLLs on WIN32 con't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs. */" + lt_dlsym_const= ;; + *osf5*) + echo >> "$output_objdir/$my_dlsyms" "\ +/* This system does not cope well with relocations in const data */" + lt_dlsym_const= ;; + *) + lt_dlsym_const=const ;; + esac + + $ECHO >> "$output_objdir/$my_dlsyms" "\ +extern $lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +$lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + $ECHO >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) symtab_cflags="$symtab_cflags $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + + +# func_emit_wrapper_part1 [arg=no] +# +# Emit the first part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part1 () +{ + func_emit_wrapper_part1_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part1_arg1=$1 + fi + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + ECHO=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$ECHO works! + : + else + # Restart under the correct shell, and then maybe \$ECHO will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $ECHO "\ + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done +" +} +# end: func_emit_wrapper_part1 + +# func_emit_wrapper_part2 [arg=no] +# +# Emit the second part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part2 () +{ + func_emit_wrapper_part2_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part2_arg1=$1 + fi + + $ECHO "\ + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} +# end: func_emit_wrapper_part2 + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=no + if test -n "$1" ; then + func_emit_wrapper_arg1=$1 + fi + + # split this up so that func_emit_cwrapperexe_src + # can call each part independently. + func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" + func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" +} + + +# func_to_host_path arg +# +# Convert paths to host format when used with build tools. +# Intended for use with "native" mingw (where libtool itself +# is running under the msys shell), or in the following cross- +# build environments: +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# where wine is equipped with the `winepath' executable. +# In the native mingw case, the (msys) shell automatically +# converts paths for any non-msys applications it launches, +# but that facility isn't available from inside the cwrapper. +# Similar accommodations are necessary for $host mingw and +# $build cygwin. Calling this function does no harm for other +# $host/$build combinations not listed above. +# +# ARG is the path (on $build) that should be converted to +# the proper representation for $host. The result is stored +# in $func_to_host_path_result. +func_to_host_path () +{ + func_to_host_path_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + case $build in + *mingw* ) # actually, msys + # awkward: cmd appends spaces to result + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_path_tmp1=`( cmd //c echo "$1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_path_tmp1=`cygpath -w "$1"` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # Unfortunately, winepath does not exit with a non-zero + # error code, so we are forced to check the contents of + # stdout. On the other hand, if the command is not + # found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both + # error code of zero AND non-empty stdout, which explains + # the odd construction: + func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + else + # Allow warning below. + func_to_host_path_result="" + fi + ;; + esac + if test -z "$func_to_host_path_result" ; then + func_error "Could not determine host path corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_path_result="$1" + fi + ;; + esac + fi +} +# end: func_to_host_path + +# func_to_host_pathlist arg +# +# Convert pathlists to host format when used with build tools. +# See func_to_host_path(), above. This function supports the +# following $build/$host combinations (but does no harm for +# combinations not listed here): +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# +# Path separators are also converted from $build format to +# $host format. If ARG begins or ends with a path separator +# character, it is preserved (but converted to $host format) +# on output. +# +# ARG is a pathlist (on $build) that should be converted to +# the proper representation on $host. The result is stored +# in $func_to_host_pathlist_result. +func_to_host_pathlist () +{ + func_to_host_pathlist_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_to_host_pathlist_tmp2="$1" + # Once set for this call, this variable should not be + # reassigned. It is used in tha fallback case. + func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e 's|^:*||' -e 's|:*$||'` + case $build in + *mingw* ) # Actually, msys. + # Awkward: cmd appends spaces to result. + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # unfortunately, winepath doesn't convert pathlists + func_to_host_pathlist_result="" + func_to_host_pathlist_oldIFS=$IFS + IFS=: + for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do + IFS=$func_to_host_pathlist_oldIFS + if test -n "$func_to_host_pathlist_f" ; then + func_to_host_path "$func_to_host_pathlist_f" + if test -n "$func_to_host_path_result" ; then + if test -z "$func_to_host_pathlist_result" ; then + func_to_host_pathlist_result="$func_to_host_path_result" + else + func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" + fi + fi + fi + IFS=: + done + IFS=$func_to_host_pathlist_oldIFS + ;; + esac + if test -z "$func_to_host_pathlist_result" ; then + func_error "Could not determine the host path(s) corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This may break if $1 contains DOS-style drive + # specifications. The fix is not to complicate the expression + # below, but for the user to provide a working wine installation + # with winepath so that path translation in the cross-to-mingw + # case works properly. + lt_replace_pathsep_nix_to_dos="s|:|;|g" + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_replace_pathsep_nix_to_dos"` + fi + # Now, add the leading and trailing path separators back + case "$1" in + :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" + ;; + esac + case "$1" in + *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" + ;; + esac + ;; + esac + fi +} +# end: func_to_host_pathlist + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +# define setmode _setmode +#else +# include +# include +# ifdef __CYGWIN__ +# include +# define HAVE_SETENV +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +#ifdef _MSC_VER +# define S_IXUSR _S_IEXEC +# define stat _stat +# ifndef _INTPTR_T_DEFINED +# define intptr_t int +# endif +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifdef __CYGWIN__ +# define FOPEN_WB "wb" +#endif + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#undef LTWRAPPER_DEBUGPRINTF +#if defined DEBUGWRAPPER +# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args +static void +ltwrapper_debugprintf (const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); +} +#else +# define LTWRAPPER_DEBUGPRINTF(args) +#endif + +const char *program_name = NULL; + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_fatal (const char *message, ...); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_opt_process_env_set (const char *arg); +void lt_opt_process_env_prepend (const char *arg); +void lt_opt_process_env_append (const char *arg); +int lt_split_name_value (const char *arg, char** name, char** value); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); + +static const char *script_text_part1 = +EOF + + func_emit_wrapper_part1 yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ "/' -e 's/$/\\n"/' + echo ";" + cat <"))); + for (i = 0; i < newargc; i++) + { + LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", + wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", + tmp_pathspec)); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + char *errstr = strerror (errno); + lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal ("Could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} + +void +lt_setenv (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", + (name ? name : ""), + (value ? value : ""))); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +int +lt_split_name_value (const char *arg, char** name, char** value) +{ + const char *p; + int len; + if (!arg || !*arg) + return 1; + + p = strchr (arg, (int)'='); + + if (!p) + return 1; + + *value = xstrdup (++p); + + len = strlen (arg) - strlen (*value); + *name = XMALLOC (char, len); + strncpy (*name, arg, len-1); + (*name)[len - 1] = '\0'; + + return 0; +} + +void +lt_opt_process_env_set (const char *arg) +{ + char *name = NULL; + char *value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); + } + + lt_setenv (name, value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_prepend (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_append (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 1); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + + +EOF +} +# end: func_emit_cwrapperexe_src + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) deplibs="$deplibs $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + weak_libs="$weak_libs $arg" + prev= + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname '-L' '' "$arg" + dir=$func_stripname_result + if test -z "$dir"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" + linker_flags="$linker_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -F/path gives path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_duplicate_deps ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + case $lib in + *.la) func_source "$lib" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` + case " $weak_libs " in + *" $deplib_base "*) ;; + *) deplibs="$deplibs $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + dir=$func_stripname_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $ECHO + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because the file extensions .$libext of this argument makes me believe" + $ECHO "*** that it is just a static archive that I should not use here." + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) temp_rpath="$temp_rpath$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + notinst_deplibs="$notinst_deplibs $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + $ECHO + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $ECHO + $ECHO "*** And there doesn't seem to be a static archive available" + $ECHO "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $ECHO + $ECHO "*** Warning: This system can not link to static lib archive $lib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $ECHO "*** But as you try to build a module library, libtool will still create " + $ECHO "*** a static module, that should work as long as the dlopening application" + $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_dirname "$deplib" "" "." + dir="$func_dirname_result" + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type \`$version_type'" + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + libobjs="$libobjs $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` + # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` + # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ + -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` + done + fi + if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | + $GREP . >/dev/null; then + $ECHO + if test "X$deplibs_check_method" = "Xnone"; then + $ECHO "*** Warning: inter-library dependencies are not supported in this platform." + else + $ECHO "*** Warning: inter-library dependencies are not known to be supported." + fi + $ECHO "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $ECHO + $ECHO "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + $ECHO "*** a static module, that should work as long as the dlopening" + $ECHO "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $ECHO "*** The inter-library dependencies that have been dropped here will be" + $ECHO "*** automatically added whenever a program is linked with this library" + $ECHO "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $ECHO + $ECHO "*** Since this library must not contain undefined symbols," + $ECHO "*** because either the platform does not support them or" + $ECHO "*** it was explicitly requested with -no-undefined," + $ECHO "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + delfiles="$delfiles $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + func_len " $cmd" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$ECHO "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + $ECHO 'INPUT (' > $output + for obj in $save_libobjs + do + $ECHO "$obj" >> $output + done + $ECHO ')' >> $output + delfiles="$delfiles $output" + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + $ECHO "$obj" >> $output + done + delfiles="$delfiles $output" + output=$firstobj\"$file_list_spec$output\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + delfiles="$delfiles $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *cegcc) + # Disable wrappers for cegcc, we are cross compiling anyway. + wrappers_required=no + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $ECHO for shipping. + if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + oldobjs="$oldobjs $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $ECHO "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlfiles="$newdlfiles $libdir/$name" + ;; + *) newdlfiles="$newdlfiles $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlprefiles="$newdlprefiles $libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$mode" = link || test "$mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) RM="$RM $arg"; rmforce=yes ;; + -*) RM="$RM $arg" ;; + *) files="$files $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + rmfiles="$rmfiles $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$mode" = uninstall || test "$mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/maskaudit.py.in b/maskaudit.py.in new file mode 100644 index 0000000..04c0d15 --- /dev/null +++ b/maskaudit.py.in @@ -0,0 +1,124 @@ +#!@PYTHON@ +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# With -p, dump a Python status mask list translated from the C one. +# +# With -c, generate C code to dump client-side masks for debugging purposes. +# +# With -d, generate C code to dump demon-side masks for debugging purposes. + +import sys, commands, glob, getopt + +class SourceExtractor: + def __init__(self, sourcefile, suffix, clientside): + self.sourcefile = sourcefile + self.suffix = suffix + self.clientside = clientside + self.daemonfiles = ["gpsd.c", "libgpsd_core.c", "pseudonmea.c"] + glob.glob("driver_*.c") + ["gpsmon.c"] + glob.glob("monitor_*.c") + self.masks = [] + self.primitive_masks = [] + for line in file(self.sourcefile): + if line.startswith("#define") and self.suffix in line: + fields = line.split() + self.masks.append((fields[1], fields[2])) + if fields[2].endswith("u"): + self.primitive_masks.append((fields[1], fields[2])) + + def in_library(self, flag): + (status, output) = commands.getstatusoutput("grep %s libgps_core.c libgps_json.c gpsctl.c" % flag) + return status == 0 + + def in_daemon(self, flag): + (status, output) = commands.getstatusoutput("grep %s %s" % (flag, " ".join(self.daemonfiles))) + return status == 0 + + def relevant(self, flag): + if self.clientside: + return self.in_library(flag) + else: + return self.in_daemon(flag) + +if __name__ == '__main__': + try: + (options, arguments) = getopt.getopt(sys.argv[1:], "cdpt") + pythonize = tabulate = False + clientgen = daemongen = False + for (switch, val) in options: + if (switch == '-p'): + pythonize = True + if (switch == '-c'): + clientgen = True + if (switch == '-d'): + daemongen = True + if (switch == '-t'): + tabulate = True + + if clientgen: + source = SourceExtractor("./gps.h", "_SET", clientside=True) + prefix = "gps" + banner = "Library" + elif daemongen: + source = SourceExtractor("./gpsd.h", "_IS", clientside=False) + prefix = "gpsd" + banner = "Daemon" + + if tabulate: + print "%-14s %8s %8s" % (" ", "Library", banner) + for (flag, value) in source.masks: + print "%-14s %8s" % (flag, source.relevant(flag)) + if pythonize: + for (d, v) in source.masks: + if v[-1] == 'u': + v = v[:-1] + print "%-15s\t= %s" % (d, v) + if not pythonize and not tabulate: + maxout = 0 + for (d, v) in source.primitive_masks: + if source.relevant(d): + stem = d + if stem.endswith(source.suffix): + stem = stem[:-len(source.suffix)] + maxout += len(stem) + 1 + print """/* This code is generated. Do not hand-hack it! */ +#include +#include + +#include \"gpsd.h\" + +const char *%s_maskdump(gps_mask_t set) +{ + static char buf[%d]; + const struct { + gps_mask_t mask; + const char *name; + } *sp, names[] = {""" % (prefix, maxout + 3,) + for (flag, value) in source.primitive_masks: + stem = flag + if stem.endswith(source.suffix): + stem = stem[:-len(source.suffix)] + print "\t{%s,\t\"%s\"}," % (flag, stem) + print '''\ + }; + + memset(buf, '\\0', sizeof(buf)); + buf[0] = '{'; + for (sp = names; sp < names + sizeof(names)/sizeof(names[0]); sp++) + if ((set & sp->mask)!=0) { + (void)strlcat(buf, sp->name, sizeof(buf)); + (void)strlcat(buf, "|", sizeof(buf)); + } + if (buf[1] != \'\\0\') + buf[strlen(buf)-1] = \'\\0\'; + (void)strlcat(buf, "}", sizeof(buf)); + return buf; +} +''' + except KeyboardInterrupt: + pass + +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:python +# End: diff --git a/missing b/missing new file mode 100755 index 0000000..28055d2 --- /dev/null +++ b/missing @@ -0,0 +1,376 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/monitor_italk.c b/monitor_italk.c new file mode 100644 index 0000000..a945bdd --- /dev/null +++ b/monitor_italk.c @@ -0,0 +1,264 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd_config.h" + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif /* HAVE_NCURSES_H */ +#include "gpsd.h" + +#include "bits.h" +#include "gpsmon.h" + +#ifdef ITRAX_ENABLE +#include "driver_italk.h" + +extern const struct gps_type_t italk_binary; +static WINDOW *satwin, *navfixwin; + +#define display (void)mvwprintw +static bool italk_initialize(void) +{ + int i; + + /*@ -onlytrans @*/ + /* "heavily inspired" by monitor_nmea.c */ + if ((satwin = + derwin(devicewin, MAX_NR_VISIBLE_PRNS + 3, 27, 0, 0)) == NULL) + return false; + (void)wborder(satwin, 0, 0, 0, 0, 0, 0, 0, 0), (void)syncok(satwin, true); + (void)wattrset(satwin, A_BOLD); + display(satwin, 1, 1, "Ch PRN Az El S/N Flag U"); + for (i = 0; i < MAX_NR_VISIBLE_PRNS; i++) + display(satwin, (int)(i + 2), 1, "%2d", i); + display(satwin, MAX_NR_VISIBLE_PRNS + 2, 7, " PRN_STATUS "); + (void)wattrset(satwin, A_NORMAL); + + /* "heavily inspired" by monitor_nmea.c */ + if ((navfixwin = derwin(devicewin, 13, 52, 0, 27)) == NULL) + return false; + (void)wborder(navfixwin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(navfixwin, A_BOLD); + (void)wmove(navfixwin, 1, 1); + (void)wprintw(navfixwin, "ECEF Pos:"); + (void)wmove(navfixwin, 2, 1); + (void)wprintw(navfixwin, "ECEF Vel:"); + + (void)wmove(navfixwin, 4, 1); + (void)wprintw(navfixwin, "LTP Pos:"); + (void)wmove(navfixwin, 5, 1); + (void)wprintw(navfixwin, "LTP Vel:"); + + (void)wmove(navfixwin, 7, 1); + (void)wprintw(navfixwin, "Time UTC:"); + (void)wmove(navfixwin, 8, 1); + (void)wprintw(navfixwin, "Time GPS: Day:"); + + (void)wmove(navfixwin, 10, 1); + (void)wprintw(navfixwin, "DOP [H] [V] [P] [T] [G]"); + (void)wmove(navfixwin, 11, 1); + (void)wprintw(navfixwin, "Fix:"); + + display(navfixwin, 12, 20, " NAV_FIX "); + (void)wattrset(navfixwin, A_NORMAL); + return true; + /*@ +onlytrans @*/ +} + +static void display_itk_navfix(unsigned char *buf, size_t len) +{ + + unsigned int tow, tod, nsec, d, svlist; + unsigned short gps_week, flags, cflags, pflags, nsv; + unsigned short year, mon, day, hour, min, sec; + double epx, epy, epz, evx, evy, evz; + double latitude, longitude; + float altitude, speed, track, climb; + float hdop, gdop, pdop, vdop, tdop; + + if (len != 296) + return; + + flags = (ushort) getleuw(buf, 7 + 4); + cflags = (ushort) getleuw(buf, 7 + 6); + pflags = (ushort) getleuw(buf, 7 + 8); + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) + nsv = (ushort) MAX(getleuw(buf, 7 + 12), getleuw(buf, 7 + 14)); + svlist = (ushort) getleul(buf, 7 + 16) | getleul(buf, 7 + 24); + + hour = (ushort) getleuw(buf, 7 + 66); + min = (ushort) getleuw(buf, 7 + 68); + sec = (ushort) getleuw(buf, 7 + 70); + nsec = (ushort) getleul(buf, 7 + 72); + year = (ushort) getleuw(buf, 7 + 76); + mon = (ushort) getleuw(buf, 7 + 78); + day = (ushort) getleuw(buf, 7 + 80); + gps_week = (ushort) getlesw(buf, 7 + 82); + tow = (ushort) getleul(buf, 7 + 84); + + epx = (double)(getlesl(buf, 7 + 96) / 100.0); + epy = (double)(getlesl(buf, 7 + 100) / 100.0); + epz = (double)(getlesl(buf, 7 + 104) / 100.0); + evx = (double)(getlesl(buf, 7 + 186) / 1000.0); + evy = (double)(getlesl(buf, 7 + 190) / 1000.0); + evz = (double)(getlesl(buf, 7 + 194) / 1000.0); + + latitude = (double)(getlesl(buf, 7 + 144) / 1e7); + longitude = (double)(getlesl(buf, 7 + 148) / 1e7); + altitude = (float)(getlesl(buf, 7 + 152) / 1e3); + climb = (float)(getlesl(buf, 7 + 206) / 1e3); + speed = (float)(getleul(buf, 7 + 210) / 1e3); + track = (float)(getleuw(buf, 7 + 214) / 1e2); + + hdop = (float)(getleuw(buf, 7 + 56) / 100.0); + gdop = (float)(getleuw(buf, 7 + 58) / 100.0); + pdop = (float)(getleuw(buf, 7 + 60) / 100.0); + vdop = (float)(getleuw(buf, 7 + 62) / 100.0); + tdop = (float)(getleuw(buf, 7 + 64) / 100.0); + + (void)wmove(navfixwin, 1, 11); + (void)wprintw(navfixwin, "%12.2lf %12.2lf %12.2lfm", epx, epy, epz); + (void)wmove(navfixwin, 2, 11); + (void)wprintw(navfixwin, "%11.2lf %11.2lf %11.2lfm/s", evx, evy, evz); + + (void)wmove(navfixwin, 4, 11); + (void)wprintw(navfixwin, "%11.8lf %13.8lf %8.1lfm", + latitude, longitude, altitude); + (void)mvwaddch(navfixwin, 4, 22, ACS_DEGREE); + (void)mvwaddch(navfixwin, 4, 38, ACS_DEGREE); + (void)wmove(navfixwin, 5, 11); + (void)wprintw(navfixwin, "%6.2lfm/s %5.1lf %6.2lfm/s climb", + speed, track, climb); + (void)mvwaddch(navfixwin, 5, 27, ACS_DEGREE); + + (void)wmove(navfixwin, 7, 11); + (void)wprintw(navfixwin, "%04u-%02u-%02u %02u:%02u:%02u", + year, mon, day, hour, min, sec); + (void)wmove(navfixwin, 8, 11); + (void)wprintw(navfixwin, "%04u+%010.3lf", gps_week, tow / 1000.0); + (void)wmove(navfixwin, 8, 33); + d = (tow / 1000) / 86400; + tod = (tow / 1000) - (d * 86400); + sec = (unsigned short)tod % 60; + min = (unsigned short)(tod / 60) % 60; + hour = (unsigned short)tod / 3600; + (void)wprintw(navfixwin, "%1d %02d:%02d:%02d", d, hour, min, sec); + + (void)wmove(navfixwin, 10, 9); + (void)wprintw(navfixwin, "%-5.1f", hdop); + (void)wmove(navfixwin, 10, 18); + (void)wprintw(navfixwin, "%-5.1f", vdop); + (void)wmove(navfixwin, 10, 27); + (void)wprintw(navfixwin, "%-5.1f", pdop); + (void)wmove(navfixwin, 10, 36); + (void)wprintw(navfixwin, "%-5.1f", tdop); + (void)wmove(navfixwin, 10, 45); + (void)wprintw(navfixwin, "%-5.1f", gdop); + + (void)wmove(navfixwin, 11, 6); + { + char prn[4], satlist[38]; + unsigned int i; + satlist[0] = '\0'; + for (i = 0; i < 32; i++) { + if (svlist & (1 << i)) { + (void)snprintf(prn, 4, "%u ", i + 1); + (void)strlcat(satlist, prn, 38); + } + } + (void)wprintw(navfixwin, "%02d = %-38s", nsv, satlist); + } + (void)wnoutrefresh(navfixwin); + +} + +static void display_itk_prnstatus(unsigned char *buf, size_t len) +{ + int i, nchan; + if (len < 62) + return; + + nchan = (int)getleuw(buf, 7 + 50); + if (nchan > MAX_NR_VISIBLE_PRNS) + nchan = MAX_NR_VISIBLE_PRNS; + for (i = 0; i < nchan; i++) { + int off = 7 + 52 + 10 * i; + unsigned short fl; + unsigned char ss, prn, el, az; + + fl = (unsigned short)getleuw(buf, off); + ss = (unsigned char)getleuw(buf, off + 2) & 0xff; + prn = (unsigned char)getleuw(buf, off + 4) & 0xff; + el = (unsigned char)getlesw(buf, off + 6) & 0xff; + az = (unsigned char)getlesw(buf, off + 8) & 0xff; + (void)wmove(satwin, i + 2, 4); + (void)wprintw(satwin, "%3d %3d %2d %02d %04x %c", + prn, az, el, ss, fl, + (fl & PRN_FLAG_USE_IN_NAV) ? 'Y' : ' '); + } + for (; i < MAX_NR_VISIBLE_PRNS; i++) { + (void)wmove(satwin, (int)i + 2, 4); + (void)wprintw(satwin, " "); + } + (void)wnoutrefresh(satwin); + return; +} + +static void italk_update(void) +{ + unsigned char *buf; + size_t len; + unsigned char type; + + buf = session.packet.outbuffer; + len = session.packet.outbuflen; + type = (unsigned char)getub(buf, 4); + switch (type) { + case ITALK_NAV_FIX: + display_itk_navfix(buf, len); + break; + case ITALK_PRN_STATUS: + display_itk_prnstatus(buf, len); + break; + default: + break; + } +} + +static int italk_command(char line[]UNUSED) +{ + return COMMAND_UNKNOWN; +} + +static void italk_wrap(void) +{ + (void)delwin(satwin); + return; +} + +const struct monitor_object_t italk_mmt = { + .initialize = italk_initialize, + .update = italk_update, + .command = italk_command, + .wrap = italk_wrap, + .min_y = 23,.min_x = 80, /* size of the device window */ + .driver = &italk_binary, +}; +#endif diff --git a/monitor_nmea.c b/monitor_nmea.c new file mode 100644 index 0000000..62ac248 --- /dev/null +++ b/monitor_nmea.c @@ -0,0 +1,460 @@ +/* + * monitor_nmea.c - gpsmon support for NMEA devices. + * + * To do: Support for GPGLL, GPGBS, GPZDA, PASHR NMEA sentences. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd_config.h" + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif /* HAVE_NCURSES_H */ +#include "gpsd.h" + +#include "bits.h" +#include "gpsmon.h" +#include "gpsdclient.h" + +#ifdef NMEA_ENABLE +extern const struct gps_type_t nmea; + +static WINDOW *cookedwin, *nmeawin, *satwin, *gprmcwin, *gpggawin, *gpgsawin; +static double last_tick, tick_interval; + +/***************************************************************************** + * + * Generic NMEA support + * + *****************************************************************************/ + +#define SENTENCELINE 1 /* index of sentences line in the NMEA window */ +#define MAXSATS 12 /* max satellites we can display */ + +static bool nmea_initialize(void) +{ + int i; + + /*@ -onlytrans @*/ + cookedwin = derwin(devicewin, 3, 80, 0, 0); + (void)wborder(cookedwin, 0, 0, 0, 0, 0, 0, 0, 0); + (void)syncok(cookedwin, true); + wattrset(cookedwin, A_BOLD); + mvwaddstr(cookedwin, 1, 1, "Time: "); + mvwaddstr(cookedwin, 1, 31, "Lat: "); + mvwaddstr(cookedwin, 1, 55, "Lon: "); + mvwaddstr(cookedwin, 2, 34, " Cooked PVT "); + wattrset(cookedwin, A_NORMAL); + + nmeawin = derwin(devicewin, 3, 80, 3, 0); + (void)wborder(nmeawin, 0, 0, 0, 0, 0, 0, 0, 0); + (void)syncok(nmeawin, true); + wattrset(nmeawin, A_BOLD); + mvwaddstr(nmeawin, 2, 34, " Sentences "); + wattrset(nmeawin, A_NORMAL); + + satwin = derwin(devicewin, MAXSATS + 3, 20, 6, 0); + (void)wborder(satwin, 0, 0, 0, 0, 0, 0, 0, 0), (void)syncok(satwin, true); + (void)wattrset(satwin, A_BOLD); + (void)mvwprintw(satwin, 1, 1, "Ch PRN Az El S/N"); + for (i = 0; i < MAXSATS; i++) + (void)mvwprintw(satwin, (int)(i + 2), 1, "%2d", i); + (void)mvwprintw(satwin, 14, 7, " GSV "); + (void)wattrset(satwin, A_NORMAL); + + gprmcwin = derwin(devicewin, 9, 30, 6, 20); + (void)wborder(gprmcwin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)syncok(gprmcwin, true); + (void)wattrset(gprmcwin, A_BOLD); + (void)mvwprintw(gprmcwin, 1, 1, "Time: "); + (void)mvwprintw(gprmcwin, 2, 1, "Latitude: "); + (void)mvwprintw(gprmcwin, 3, 1, "Longitude: "); + (void)mvwprintw(gprmcwin, 4, 1, "Speed: "); + (void)mvwprintw(gprmcwin, 5, 1, "Course: "); + (void)mvwprintw(gprmcwin, 6, 1, "Status: FAA: "); + (void)mvwprintw(gprmcwin, 7, 1, "MagVar: "); + (void)mvwprintw(gprmcwin, 8, 12, " RMC "); + (void)wattrset(gprmcwin, A_NORMAL); + + gpgsawin = derwin(devicewin, 5, 30, 15, 20); + (void)wborder(gpgsawin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)syncok(gpgsawin, true); + (void)wattrset(gpgsawin, A_BOLD); + (void)mvwprintw(gpgsawin, 1, 1, "Mode: "); + (void)mvwprintw(gpgsawin, 2, 1, "Sats: "); + (void)mvwprintw(gpgsawin, 3, 1, "DOP: H= V= P="); + (void)mvwprintw(gpgsawin, 4, 12, " GSA "); + (void)wattrset(gpgsawin, A_NORMAL); + + gpggawin = derwin(devicewin, 9, 30, 6, 50); + (void)wborder(gpggawin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)syncok(gpggawin, true); + (void)wattrset(gpggawin, A_BOLD); + (void)mvwprintw(gpggawin, 1, 1, "Time: "); + (void)mvwprintw(gpggawin, 2, 1, "Latitude: "); + (void)mvwprintw(gpggawin, 3, 1, "Longitude: "); + (void)mvwprintw(gpggawin, 4, 1, "Altitude: "); + (void)mvwprintw(gpggawin, 5, 1, "Quality: Sats: "); + (void)mvwprintw(gpggawin, 6, 1, "HDOP: "); + (void)mvwprintw(gpggawin, 7, 1, "Geoid: "); + (void)mvwprintw(gpggawin, 8, 12, " GGA "); + (void)wattrset(gpggawin, A_NORMAL); + /*@ +onlytrans @*/ + + last_tick = timestamp(); + + return (nmeawin != NULL); +} + +static void cooked_pvt(void) +{ + char scr[128]; + + if (isnan(session.gpsdata.fix.time) == 0) { + (void)unix_to_iso8601(session.gpsdata.fix.time, scr, sizeof(scr)); + } else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(cookedwin, 1, 7, "%-22s", scr); + + + if (session.gpsdata.fix.mode >= MODE_2D + && isnan(session.gpsdata.fix.latitude) == 0) { + (void)snprintf(scr, sizeof(scr), "%s %c", + deg_to_str(deg_ddmmss, + fabs(session.gpsdata.fix.latitude)), + (session.gpsdata.fix.latitude < 0) ? 'S' : 'N'); + } else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(cookedwin, 1, 36, "%-17s", scr); + + if (session.gpsdata.fix.mode >= MODE_2D + && isnan(session.gpsdata.fix.longitude) == 0) { + (void)snprintf(scr, sizeof(scr), "%s %c", + deg_to_str(deg_ddmmss, + fabs(session.gpsdata.fix.longitude)), + (session.gpsdata.fix.longitude < 0) ? 'W' : 'E'); + } else + (void)snprintf(scr, sizeof(scr), "n/a"); + (void)mvwprintw(cookedwin, 1, 60, "%-17s", scr); +} + + +/*@ -globstate -nullpass (splint is confused) */ +static void nmea_update(void) +{ + static char sentences[NMEA_MAX]; + char **fields; + + assert(cookedwin != NULL); + assert(nmeawin != NULL); + assert(gpgsawin != NULL); + assert(gpggawin != NULL); + assert(gprmcwin != NULL); + + fields = session.driver.nmea.field; + + if (session.packet.outbuffer[0] == (unsigned char)'$') { + int ymax, xmax; + double now; + getmaxyx(nmeawin, ymax, xmax); + if (strstr(sentences, fields[0]) == NULL) { + char *s_end = sentences + strlen(sentences); + if ((int)(strlen(sentences) + strlen(fields[0])) < xmax - 2) { + *s_end++ = ' '; + (void)strlcpy(s_end, fields[0], NMEA_MAX); + } else { + *--s_end = '.'; + *--s_end = '.'; + *--s_end = '.'; + } + mvwaddstr(nmeawin, SENTENCELINE, 1, sentences); + } + + /* + * If the interval between this and last update is + * the longest we've seen yet, boldify the corresponding + * tag. + */ + now = timestamp(); + if (now > last_tick && (now - last_tick) > tick_interval) { + char *findme = strstr(sentences, fields[0]); + + tick_interval = now - last_tick; + if (findme != NULL) { + mvwchgat(nmeawin, SENTENCELINE, 1, xmax - 13, A_NORMAL, 0, + NULL); + mvwchgat(nmeawin, SENTENCELINE, 1 + (findme - sentences), + (int)strlen(fields[0]), A_BOLD, 0, NULL); + } + } + last_tick = now; + + if (strcmp(fields[0], "GPGSV") == 0 + || strcmp(fields[0], "GNGSV") == 0 + || strcmp(fields[0], "GLGSV") == 0) { + int i; + int nsats = + (session.gpsdata.satellites_visible < + MAXSATS) ? session.gpsdata.satellites_visible : MAXSATS; + + for (i = 0; i < nsats; i++) { + (void)wmove(satwin, i + 2, 3); + (void)wprintw(satwin, " %3d %3d%3d %3.0f", + session.gpsdata.PRN[i], + session.gpsdata.azimuth[i], + session.gpsdata.elevation[i], + session.gpsdata.ss[i]); + } + /* add overflow mark to the display */ + if (nsats <= MAXSATS) + (void)mvwaddch(satwin, MAXSATS + 2, 18, ACS_HLINE); + else + (void)mvwaddch(satwin, MAXSATS + 2, 18, ACS_DARROW); + } + + if (strcmp(fields[0], "GPRMC") == 0 + || strcmp(fields[0], "GNRMC") == 0 + || strcmp(fields[0], "GLRMC") == 0) { + /* time, lat, lon, course, speed */ + (void)mvwaddstr(gprmcwin, 1, 12, fields[1]); + (void)mvwprintw(gprmcwin, 2, 12, "%12s %s", fields[3], fields[4]); + (void)mvwprintw(gprmcwin, 3, 12, "%12s %s", fields[5], fields[6]); + (void)mvwaddstr(gprmcwin, 4, 12, fields[7]); + (void)mvwaddstr(gprmcwin, 5, 12, fields[8]); + /* the status field, FAA code, and magnetic variation */ + (void)mvwaddstr(gprmcwin, 6, 12, fields[2]); + (void)mvwaddstr(gprmcwin, 6, 25, fields[12]); + (void)mvwprintw(gprmcwin, 7, 12, "%-5s%s", fields[10], + fields[11]); + + cooked_pvt(); /* cooked version of PVT */ + } + + if (strcmp(fields[0], "GPGSA") == 0 + || strcmp(fields[0], "GNGSA") == 0 + || strcmp(fields[0], "GLGSA") == 0) { + char scr[128]; + int i; + (void)mvwprintw(gpgsawin, 1, 7, "%1s %s", fields[1], fields[2]); + (void)wmove(gpgsawin, 2, 7); + (void)wclrtoeol(gpgsawin); + scr[0] = '\0'; + for (i = 0; i < session.gpsdata.satellites_used; i++) { + (void)snprintf(scr + strlen(scr), sizeof(scr) - strlen(scr), + "%d ", session.gpsdata.used[i]); + } + getmaxyx(gpgsawin, ymax, xmax); + (void)mvwaddnstr(gpgsawin, 2, 7, scr, xmax - 2 - 7); + if (strlen(scr) >= (size_t) (xmax - 2)) { + mvwaddch(gpgsawin, 2, xmax - 2 - 7, (chtype) '.'); + mvwaddch(gpgsawin, 2, xmax - 3 - 7, (chtype) '.'); + mvwaddch(gpgsawin, 2, xmax - 4 - 7, (chtype) '.'); + } + monitor_fixframe(gpgsawin); + (void)mvwprintw(gpgsawin, 3, 8, "%-5s", fields[16]); + (void)mvwprintw(gpgsawin, 3, 16, "%-5s", fields[17]); + (void)mvwprintw(gpgsawin, 3, 24, "%-5s", fields[15]); + monitor_fixframe(gpgsawin); + } + if (strcmp(fields[0], "GPGGA") == 0 + || strcmp(fields[0], "GNGGA") == 0 + || strcmp(fields[0], "GLGGA") == 0) { + (void)mvwprintw(gpggawin, 1, 12, "%-17s", fields[1]); + (void)mvwprintw(gpggawin, 2, 12, "%-17s", fields[2]); + (void)mvwprintw(gpggawin, 3, 12, "%-17s", fields[4]); + (void)mvwprintw(gpggawin, 4, 12, "%-17s", fields[9]); + (void)mvwprintw(gpggawin, 5, 12, "%1.1s", fields[6]); + (void)mvwprintw(gpggawin, 5, 22, "%2.2s", fields[7]); + (void)mvwprintw(gpggawin, 6, 12, "%-5.5s", fields[8]); + (void)mvwprintw(gpggawin, 7, 12, "%-5.5s", fields[11]); + } + } +} + +/*@ +globstate +nullpass */ + +#undef SENTENCELINE + +static void nmea_wrap(void) +{ + (void)delwin(nmeawin); + (void)delwin(gpgsawin); + (void)delwin(gpggawin); + (void)delwin(gprmcwin); +} + +const struct monitor_object_t nmea_mmt = { + .initialize = nmea_initialize, + .update = nmea_update, + .command = NULL, + .wrap = nmea_wrap, + .min_y = 21,.min_x = 80, + .driver = &nmea, +}; + +/***************************************************************************** + * + * Extended NMEA support + * + *****************************************************************************/ + +#ifdef ALLOW_CONTROLSEND +static void monitor_nmea_send(const char *fmt, ...) +{ + char buf[BUFSIZ]; + va_list ap; + + va_start(ap, fmt); + (void)vsnprintf(buf, sizeof(buf) - 5, fmt, ap); + va_end(ap); + (void)monitor_control_send((unsigned char *)buf, strlen(buf)); +} +#endif /* ALLOW_CONTROLSEND */ + +/* + * Yes, it's OK for most of these to be clones of the generic NMEA monitor + * object except for the pointer to the GPSD driver. That pointer makes + * a difference, as it will automatically enable stuff like speed-switcher + * and mode-switcher commands. It's really only necessary to write a + * separate monitor object if you want to change the device-window + * display or implement device-specific commands. + */ + +#if defined(GARMIN_ENABLE) && defined(NMEA_ENABLE) +extern const struct gps_type_t garmin; + +const struct monitor_object_t garmin_mmt = { + .initialize = nmea_initialize, + .update = nmea_update, + .command = NULL, + .wrap = nmea_wrap, + .min_y = 21,.min_x = 80, + .driver = &garmin, +}; +#endif /* GARMIN_ENABLE && NMEA_ENABLE */ + +#ifdef ASHTECH_ENABLE +extern const struct gps_type_t ashtech; + +#define ASHTECH_SPEED_9600 5 +#define ASHTECH_SPEED_57600 8 + +#ifdef ALLOW_CONTROLSEND +static int ashtech_command(char line[]) +{ + switch (line[0]) { + case 'N': /* normal = 9600, GGA+GSA+GSV+RMC+ZDA */ + monitor_nmea_send("$PASHS,NME,ALL,A,OFF"); /* silence outbound chatter */ + monitor_nmea_send("$PASHS,NME,ALL,B,OFF"); + monitor_nmea_send("$PASHS,NME,GGA,A,ON"); + monitor_nmea_send("$PASHS,NME,GSA,A,ON"); + monitor_nmea_send("$PASHS,NME,GSV,A,ON"); + monitor_nmea_send("$PASHS,NME,RMC,A,ON"); + monitor_nmea_send("$PASHS,NME,ZDA,A,ON"); + + monitor_nmea_send("$PASHS,INI,%d,%d,,,0,", + ASHTECH_SPEED_9600, ASHTECH_SPEED_9600); + (void)sleep(6); /* it takes 4-6 sec for the receiver to reboot */ + monitor_nmea_send("$PASHS,WAS,ON"); /* enable WAAS */ + break; + + case 'R': /* raw = 57600, normal+XPG+POS+SAT+MCA+PBN+SNV */ + monitor_nmea_send("$PASHS,NME,ALL,A,OFF"); /* silence outbound chatter */ + monitor_nmea_send("$PASHS,NME,ALL,B,OFF"); + monitor_nmea_send("$PASHS,NME,GGA,A,ON"); + monitor_nmea_send("$PASHS,NME,GSA,A,ON"); + monitor_nmea_send("$PASHS,NME,GSV,A,ON"); + monitor_nmea_send("$PASHS,NME,RMC,A,ON"); + monitor_nmea_send("$PASHS,NME,ZDA,A,ON"); + + monitor_nmea_send("$PASHS,INI,%d,%d,,,0,", + ASHTECH_SPEED_57600, ASHTECH_SPEED_9600); + (void)sleep(6); /* it takes 4-6 sec for the receiver to reboot */ + monitor_nmea_send("$PASHS,WAS,ON"); /* enable WAAS */ + + monitor_nmea_send("$PASHS,NME,POS,A,ON"); /* Ashtech PVT solution */ + monitor_nmea_send("$PASHS,NME,SAT,A,ON"); /* Ashtech Satellite status */ + monitor_nmea_send("$PASHS,NME,MCA,A,ON"); /* MCA measurements */ + monitor_nmea_send("$PASHS,NME,PBN,A,ON"); /* ECEF PVT solution */ + monitor_nmea_send("$PASHS,NME,SNV,A,ON,10"); /* Almanac data */ + + monitor_nmea_send("$PASHS,NME,XMG,A,ON"); /* exception messages */ + break; + + default: + return COMMAND_UNKNOWN; + } + + return COMMAND_UNKNOWN; +} +#endif /* ALLOW_CONTROLSEND */ + +const struct monitor_object_t ashtech_mmt = { + .initialize = nmea_initialize, + .update = nmea_update, +#ifdef ALLOW_CONTROLSEND + .command = ashtech_command, +#else + .command = NULL, +#endif /* ALLOW_CONTROLSEND */ + .wrap = nmea_wrap, + .min_y = 21,.min_x = 80, + .driver = &ashtech, +}; +#endif /* ASHTECH_ENABLE */ + +#ifdef FV18_ENABLE +extern const struct gps_type_t fv18; + +const struct monitor_object_t fv18_mmt = { + .initialize = nmea_initialize, + .update = nmea_update, + .command = NULL, + .wrap = nmea_wrap, + .min_y = 21,.min_x = 80, + .driver = &fv18, +}; +#endif /* FV18_ENABLE */ + +#ifdef GPSCLOCK_ENABLE +extern const struct gps_type_t gpsclock; + +const struct monitor_object_t gpsclock_mmt = { + .initialize = nmea_initialize, + .update = nmea_update, + .command = NULL, + .wrap = nmea_wrap, + .min_y = 21,.min_x = 80, + .driver = &gpsclock, +}; +#endif /* GPSCLOCK_ENABLE */ + +#ifdef MTK3301_ENABLE +extern const struct gps_type_t mtk3301; + +const struct monitor_object_t mtk3301_mmt = { + .initialize = nmea_initialize, + .update = nmea_update, + .command = NULL, + .wrap = nmea_wrap, + .min_y = 21,.min_x = 80, + .driver = &mtk3301, +}; +#endif /* MTK3301_ENABLE */ + +#endif /* NMEA_ENABLE */ diff --git a/monitor_oncore.c b/monitor_oncore.c new file mode 100644 index 0000000..719773a --- /dev/null +++ b/monitor_oncore.c @@ -0,0 +1,478 @@ +/* + * OnCore object for the GPS packet monitor. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd_config.h" + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif /* HAVE_NCURSES_H */ +#include "gpsd.h" + +#include "bits.h" +#include "gpsmon.h" + +#if defined(ONCORE_ENABLE) && defined(BINARY_ENABLE) +extern const struct gps_type_t oncore_binary; + +static WINDOW *Ea1win, *Eawin, *Bbwin, *Enwin, *Bowin, *Aywin, *Aswin, *Atwin; +static unsigned char EaSVlines[8]; + +static const char *antenna[] = { + "OK (conn)", + "OC (short)", + "UC (open)", + "OU (short)" +}; + +static const char *sv_mode[] = { + "srch", + "acq", + "AGCs", + "pacq", + "bits", + "msgs", + "satT", + "epha", + "avl" +}; + +static const char *pps_ctrl[] = { + "off", + "on", + "on if >= 1 SV", + "on if TRAIM ok" +}; + +static const char *pps_sync[] = { + "UTC", + "GPS" +}; + +static const char *traim_sol[] = { + "OK", + "ALARM", + "UNKNOWN" +}; + +static const char *traim_status[] = { + "detect & isolate", + "detect", + "insufficient" +}; + +static const char *pos_hold_mode[] = { + "off", + "on", + "survey" +}; + +#define ONCTYPE(id2,id3) ((((unsigned int)id2)<<8)|(id3)) + +#define MAXTRACKSATS 8 /* the most satellites being tracked */ +#define MAXVISSATS 12 /* the most satellites with known az/el */ + +static bool oncore_initialize(void) +{ + unsigned int i; + + /*@ -onlytrans @*/ + Ea1win = subwin(devicewin, 5, 80, 1, 0); + Eawin = subwin(devicewin, MAXTRACKSATS + 3, 27, 6, 0); + Bbwin = subwin(devicewin, MAXVISSATS + 3, 22, 6, 28); + Enwin = subwin(devicewin, 10, 29, 6, 51); + Bowin = subwin(devicewin, 4, 11, 17, 0); + Aywin = subwin(devicewin, 4, 15, 17, 12); + Atwin = subwin(devicewin, 5, 9, 16, 51); + Aswin = subwin(devicewin, 5, 19, 16, 61); + /*@ +onlytrans @*/ + + if (Ea1win == NULL || Eawin == NULL || Bbwin == NULL || Enwin == NULL + || Bowin == NULL || Aswin == NULL || Atwin == NULL) + return false; + + (void)syncok(Ea1win, true); + (void)syncok(Eawin, true); + (void)syncok(Bbwin, true); + (void)syncok(Enwin, true); + (void)syncok(Bowin, true); + (void)syncok(Aywin, true); + (void)syncok(Aswin, true); + (void)syncok(Atwin, true); + + (void)wborder(Ea1win, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(Ea1win, A_BOLD); + (void)mvwaddstr(Ea1win, 1, 1, + "Time: Lat: Lon:"); + (void)mvwaddstr(Ea1win, 2, 1, + "Antenna: DOP: Speed: Course:"); + (void)mvwaddstr(Ea1win, 3, 1, + "SV/vis: Status: Alt:"); + (void)mvwprintw(Ea1win, 4, 4, " @@Ea (pos) "); + (void)wattrset(Ea1win, A_NORMAL); + + (void)wborder(Eawin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(Eawin, A_BOLD); + (void)mvwprintw(Eawin, 1, 1, "Ch PRN mode S/N ????????"); + (void)mvwprintw(Eawin, 10, 4, " @@Ea (sat) "); + for (i = 0; i < 8; i++) { + (void)mvwprintw(Eawin, (int)(i + 2), 1, "%2d", i); + } + (void)wattrset(Eawin, A_NORMAL); + + (void)wborder(Bbwin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(Bbwin, A_BOLD); + (void)mvwprintw(Bbwin, 1, 1, "PRN Az El doppl ??"); + (void)mvwprintw(Bbwin, 14, 4, " @@Bb "); + (void)wattrset(Bbwin, A_NORMAL); + + (void)wborder(Enwin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(Enwin, A_BOLD); + (void)mvwprintw(Enwin, 1, 1, "Time RAIM: "); + (void)mvwprintw(Enwin, 2, 1, "Alarm limit:"); + (void)mvwprintw(Enwin, 3, 1, "PPS ctrl:"); + (void)mvwprintw(Enwin, 4, 1, "Pulse:"); + (void)mvwprintw(Enwin, 5, 1, "PPS sync:"); + (void)mvwprintw(Enwin, 6, 1, "TRAIM sol stat:"); + (void)mvwprintw(Enwin, 7, 1, "Status:"); + (void)mvwprintw(Enwin, 8, 1, "Time sol sigma:"); + (void)mvwprintw(Enwin, 9, 4, " @@En "); + (void)wattrset(Enwin, A_NORMAL); + + (void)wborder(Bowin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(Bowin, A_BOLD); + (void)mvwprintw(Bowin, 1, 1, "UTC:"); + (void)mvwprintw(Bowin, 3, 2, " @@Bo "); + (void)wattrset(Bowin, A_NORMAL); + + (void)wborder(Aywin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(Aywin, A_BOLD); + (void)mvwprintw(Aywin, 1, 1, "PPS delay:"); + (void)mvwprintw(Aywin, 3, 4, " @@Ay "); + (void)wattrset(Aywin, A_NORMAL); + + (void)wborder(Atwin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(Atwin, A_BOLD); + (void)mvwprintw(Atwin, 1, 1, "PHold:"); + (void)mvwprintw(Atwin, 4, 1, " @@At "); + (void)wattrset(Atwin, A_NORMAL); + + (void)wborder(Aswin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(Aswin, A_BOLD); + (void)mvwprintw(Aswin, 1, 1, "Lat:"); + (void)mvwprintw(Aswin, 2, 1, "Lon:"); + (void)mvwprintw(Aswin, 3, 1, "Alt:"); + (void)mvwprintw(Aswin, 4, 4, " @@As "); + (void)wattrset(Aswin, A_NORMAL); + + memset(EaSVlines, 0, sizeof(EaSVlines)); + + return true; +} + +static void oncore_update(void) +{ + unsigned int i, j, off; + unsigned char *buf; + unsigned int type; + + assert(Eawin != NULL); + buf = session.packet.outbuffer; + type = ONCTYPE(buf[2], buf[3]); + switch (type) { + case ONCTYPE('E', 'a'): + { + double lat, lon, alt; + float speed, track; + float dop; + unsigned short year; + unsigned char mon, day, hour, min, sec; + unsigned int nsec; + unsigned char dopt, nvis, nsat, status; + char statusbuf[64]; /* 6+9+3+3+10+5+7+12+1=56 */ + + mon = (unsigned char)getub(buf, 4); + day = (unsigned char)getub(buf, 5); + year = (unsigned short)getbeuw(buf, 6); + hour = (unsigned char)getub(buf, 8); + min = (unsigned char)getub(buf, 9); + sec = (unsigned char)getub(buf, 10); + nsec = (unsigned int)getbeul(buf, 11); + + lat = getbesl(buf, 15) / 3600000.0; + lon = getbesl(buf, 19) / 3600000.0; + alt = getbesl(buf, 23) / 100.0; + speed = (float)(getbeuw(buf, 31) / 100.0); + track = (float)(getbeuw(buf, 33) / 10.0); + dop = (float)(getbeuw(buf, 35) / 10.0); + dopt = (unsigned char)getub(buf, 37); + nvis = (unsigned char)getub(buf, 38); + nsat = (unsigned char)getub(buf, 39); + status = (unsigned char)getub(buf, 72); + + (void)mvwprintw(Ea1win, 1, 7, "%04d-%02d-%02d %02d:%02d:%02d.%09d", + year, mon, day, hour, min, sec, nsec); + (void)mvwprintw(Ea1win, 1, 47, "%10.6lf %c", + fabs(lat), lat < 0 ? 'S' : lat > 0 ? 'N' : ' '); + (void)mvwprintw(Ea1win, 1, 66, "%10.6lf %c", + fabs(lon), lat < 0 ? 'W' : lon > 0 ? 'E' : ' '); + + (void)mvwprintw(Ea1win, 2, 50, "%6.2f m/s", speed); + (void)mvwprintw(Ea1win, 2, 70, "%5.1f", track); + (void)mvwprintw(Ea1win, 3, 68, "%8.2f m", alt); + + /*@ -predboolothers @*/ + (void)snprintf(statusbuf, sizeof(statusbuf), "%s%s%s%s%s%s%s%s", + status & 0x80 ? "PProp " : "", + status & 0x40 ? "PoorGeom " : "", + status & 0x20 ? "3D " : "", + status & 0x10 ? "2D " : "", + status & 0x08 ? "Acq/PHold " : "", + status & 0x04 ? "Diff " : "", + status & 0x02 ? "Ins (<3 SV) " : "", + status & 0x01 ? "BadAlm " : ""); + /*@ +predboolothers @*/ + + (void)mvwprintw(Ea1win, 3, 24, "%-37s", statusbuf); + + (void)mvwprintw(Ea1win, 2, 10, "%-10s", antenna[dopt >> 6]); + + /*@ -predboolothers @*/ + (void)mvwprintw(Ea1win, 2, 27, "%s %4.1f", + dopt & 1 ? "hdop" : "pdop", dop); + /*@ +predboolothers @*/ + + (void)mvwprintw(Ea1win, 3, 10, "%d/%d ", nsat, nvis); + } + + for (i = 0; i < 8; i++) { + unsigned char sv, mode, sn, status; + + off = 40 + 4 * i; + sv = (unsigned char)getub(buf, off); + mode = (unsigned char)getub(buf, off + 1); + sn = (unsigned char)getub(buf, off + 2); + status = (unsigned char)getub(buf, off + 3); + (void)wmove(Eawin, (int)(i + 2), 3); + (void)wprintw(Eawin, " %3d", sv); + EaSVlines[i] = sv; + if (mode <= (unsigned char)8) + (void)wprintw(Eawin, " %4s", sv_mode[mode]); + else + (void)wprintw(Eawin, " -"); + (void)wprintw(Eawin, " %3d", sn); + /*@ -predboolothers @*/ + (void)wprintw(Eawin, " %c%c%c%c%c%c%c%c", (status & 0x80) ? 'p' : ' ', /* used for pos fix */ + (status & 0x40) ? 'M' : ' ', /* momentum alert */ + (status & 0x20) ? 's' : ' ', /* anti-spoof */ + (status & 0x10) ? 'U' : ' ', /* unhealthy */ + (status & 0x08) ? 'I' : ' ', /* inaccurate */ + (status & 0x04) ? 'S' : ' ', /* spare */ + (status & 0x02) ? 't' : ' ', /* used for time sol */ + (status & 0x01) ? 'P' : ' '); /* parity error */ + /*@ +predboolothers @*/ + } + + monitor_log("Ea ="); + break; + + case ONCTYPE('B', 'b'): + { + unsigned int Bblines[12]; + unsigned int Bblines_mask; + unsigned int next_line; + unsigned char sv; + unsigned int ch; + + ch = (unsigned int)getub(buf, 4); + if (ch > 12) + ch = 12; + /* Try to align the entries for each SV of the Bb message at + * the same lines as in the Ea message. + */ + memset(Bblines, 0, sizeof(Bblines)); + Bblines_mask = 0; + for (i = 0; i < ch; i++) { + off = 5 + 7 * i; + sv = (unsigned char)getub(buf, off); + /*@ -boolops @*/ + for (j = 0; j < 8; j++) + if (EaSVlines[j] == sv && !(Bblines_mask & (1 << (j + 2)))) { + Bblines[i] = j + 2; + Bblines_mask |= 1 << Bblines[i]; + } + /*@ +boolops @*/ + } + /* SVs not seen in Ea fill lines left over. */ + next_line = 2; + for (i = 0; i < ch; i++) { + if (Bblines[i] == 0) { + while (Bblines_mask & (1 << next_line)) + next_line++; + Bblines[i] = next_line++; + Bblines_mask |= 1 << Bblines[i]; + } + } + /* Ready to print on precalculated lines. */ + for (i = 0; i < ch; i++) { + int doppl, el, az, health; + + off = 5 + 7 * i; + sv = (unsigned char)getub(buf, off); + doppl = (int)getbesw(buf, off + 1); + el = (int)getub(buf, off + 3); + az = (int)getbeuw(buf, off + 4); + health = (int)getub(buf, off + 5); + + (void)wmove(Bbwin, (int)Bblines[i], 1); + (void)wprintw(Bbwin, "%3d %3d %2d %5d %c%c", sv, az, el, doppl, (health & 0x02) ? 'U' : ' ', /* unhealthy */ + (health & 0x01) ? 'R' : ' '); /* removed */ + } + + for (i = 2; i < 14; i++) + /*@ -boolops @*/ + if (!(Bblines_mask & (1 << i))) { + (void)wmove(Bbwin, (int)i, 1); + (void)wprintw(Bbwin, " "); + } + /*@ +boolops @*/ + } + + monitor_log("Bb ="); + break; + + case ONCTYPE('E', 'n'): + { + unsigned char traim, ctrl, pulse, sync, sol_stat, status; + float alarm, sigma; + + traim = (unsigned char)getub(buf, 5); + alarm = (float)(getbeuw(buf, 6) / 10.); + ctrl = (unsigned char)getub(buf, 8); + pulse = (unsigned char)getub(buf, 9); + sync = (unsigned char)getub(buf, 10); + sol_stat = (unsigned char)getub(buf, 11); + status = (unsigned char)getub(buf, 12); + sigma = (float)(getbeuw(buf, 13)); + + /*@ -predboolothers @*/ + (void)mvwprintw(Enwin, 1, 24, "%3s", traim ? "on" : "off"); + (void)mvwprintw(Enwin, 2, 18, "%6.1f us", alarm); + (void)mvwprintw(Enwin, 3, 13, "%14s", pps_ctrl[ctrl]); + (void)mvwprintw(Enwin, 4, 24, "%3s", pulse ? "on" : "off"); + (void)mvwprintw(Enwin, 5, 24, "%3s", pps_sync[sync]); + (void)mvwprintw(Enwin, 6, 20, "%7s", traim_sol[sol_stat]); + (void)mvwprintw(Enwin, 7, 11, "%16s", traim_status[status]); + (void)mvwprintw(Enwin, 8, 18, "%6.3f us", sigma); + /*@ +predboolothers @*/ + } + + monitor_log("En ="); + break; + + case ONCTYPE('B', 'o'): + { + unsigned char utc_offset; + + utc_offset = (unsigned char)getub(buf, 4); + + if (utc_offset != (unsigned char)0) + (void)mvwprintw(Bowin, 2, 2, "GPS%+4d", utc_offset); + else + (void)mvwprintw(Bowin, 2, 2, "unknown", utc_offset); + } + + monitor_log("Bo ="); + break; + + case ONCTYPE('A', 'y'): + { + double pps_delay; + + pps_delay = getbesl(buf, 4) / 1000000.0; + + (void)mvwprintw(Aywin, 2, 2, " %7.3f ms", pps_delay); + } + + monitor_log("Ay ="); + break; + + case ONCTYPE('A', 't'): + { + unsigned char mode; + + mode = (unsigned char)getub(buf, 4); + + (void)mvwprintw(Atwin, 2, 1, "%6s", pos_hold_mode[mode]); + } + + monitor_log("At ="); + break; + + case ONCTYPE('A', 's'): + { + double lat, lon, alt; + + lat = getbesl(buf, 4) / 3600000.0; + lon = getbesl(buf, 8) / 3600000.0; + alt = getbesl(buf, 12) / 100.0; + + (void)mvwprintw(Aswin, 1, 5, "%10.6lf %c", + fabs(lat), lat < 0 ? 'S' : lat > 0 ? 'N' : ' '); + (void)mvwprintw(Aswin, 2, 5, "%10.6lf %c", + fabs(lon), lat < 0 ? 'W' : lon > 0 ? 'E' : ' '); + (void)mvwprintw(Aswin, 3, 7, "%8.2f m", alt); + } + + monitor_log("As ="); + break; + + default: + monitor_log("%c%c =", buf[2], buf[3]); + break; + } +} + +static int oncore_command(char line[]UNUSED) +{ + return COMMAND_UNKNOWN; +} + +static void oncore_wrap(void) +{ + (void)delwin(Ea1win); + (void)delwin(Eawin); + (void)delwin(Bbwin); + (void)delwin(Enwin); + (void)delwin(Bowin); + (void)delwin(Aywin); + (void)delwin(Atwin); + (void)delwin(Aswin); +} + +const struct monitor_object_t oncore_mmt = { + .initialize = oncore_initialize, + .update = oncore_update, + .command = oncore_command, + .wrap = oncore_wrap, + .min_y = 20,.min_x = 80, /* size of the device window */ + .driver = &oncore_binary, +}; + +#endif /* defined(ONCORE_ENABLE) && defined(BINARY_ENABLE) */ diff --git a/monitor_proto.c b/monitor_proto.c new file mode 100644 index 0000000..6afb202 --- /dev/null +++ b/monitor_proto.c @@ -0,0 +1,163 @@ +/* + * Prototype file for a gpsmon monitor object. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd_config.h" + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif /* HAVE_NCURSES_H */ +#include "gpsd.h" + +#include "bits.h" +#include "gpsmon.h" + +/* + * Replace PROTO everywhere with the name of the GPSD driver describing + * the device you want to support. + * + * gpsmon basically sits in a loop reading packets, using the same layer + * as gpsd to dispatch on packet type to select an active device driver. + * Your monitor object will become the handler for incoming packets whenever + * the driver your object points at is selected. + * + * A comment following the method descriptions explains some available + * helper functions. + */ + +extern const struct gps_type_t PROTO_binary; + +static bool PROTO_initialize(void) +{ + /* + * This function is called when your monitor object is activated. + * + * When you enter it, two windows will be accessible to you; (1) + * devicewin, just below the status and command line at top of + * screen, and (2) packetwin, taking up the rest of the screen below + * it; packetwin will be enabled for scrolling. Note, however, + * that you cannot necessarily update packetwin safely, as it may be NULL + * if the screen has no lines left over after allocating devicewin; + * you'll need to check this in your code. + * + * Use this method to paint windowframes and legends on the + * freshly initialized device window. You can also use this + * method to send probes to the device, e.g. to elicit a response + * telling you firmware rev levels or whatever. + */ + + /* return false if the window allocation failed; gpsmon will abort */ + return true; +} + +static void PROTO_update(void) +{ + /* + * Called on each packet received. The packet will be accessible in + * session.packet.outbuffer and the length in session.packet.outbuflen. + * If the device is NMEA, session.driver.nmea.fields[] will contain the + * array of unconverted field strings, including the tag in slot zero + * but not including the checksum or trailing \r\n. + * + * Use this function to update devicewin. The packet will be echoed to + * packetwin immediately after this function is called; you can use this + * function to write a prefix on the line. + */ +} + +static int PROTO_command(char line[]) +{ + /* + * Interpret a command line. Whatever characters the user types will + * be echoed in the command buffer at the top right of the display. When + * he/she presses enter the command line will be passed to this function + * for interpretation. Note: packet receipt is suspended while this + * function is executing. + * + * This method is optional. If you set the command method pointer to + * NULL, gpsmon will behave sanely, accepting no device-specific commands. + * + * It is a useful convention to use uppercase letters for + * driver-specific commands and leave lowercase ones for the + * generic gpsmon ones. + */ + + /* + * Return COMMAND_UNKNOWN to tell gpsmon you can't interpret the line, and + * it will be passed to the generic command interpreter to be handled there. + * You can alse return COMMAND_MATCH to tell it you handled the command, + * or COMMAND_TERMINATE to tell gpsmon you handled it and gpsmon should + * terminate. + */ + return COMMAND_UNKNOWN; +} + +static void PROTO_wrap(void) +{ + /* + * Deinitialize any windows you created in PROTO_initialize. + * This will be called when gpsmon switches drivers due to seeing + * a new packet type. + */ +} + +/* + * Use mmt = monitor method table as a suffix for naming these things + * Yours will need to be added to the monitor_objects table in gpsmon.c, + * then of course you need to link your module into gpsmon. + */ +const struct monitor_object_t PROTO_mmt = { + .initialize = PROTO_initialize, + .update = PROTO_update, + .command = PROTO_command, + .wrap = PROTO_wrap, + .min_y = 23, .min_x = 80, /* size of the device window */ + /* + * The gpsd driver type for your device. gpsmon will use the mode_switcher + * method for 'n', the speed_switcher for 's', and the control_send method + * for 'c'. Additionally, the driver type name will be displayed before + * the '>' command prompt in the top line of the display. + */ + .driver = &PROTO_binary, +}; + +/* + * Helpers: + * + * bool monitor_control_send(unsigned char *buf, size_t len) + * Ship a packet payload to the device. Calls the driver send_control() + * method to add headers/trailers/checksum; also dumps the sent + * packet to the packet window, if the send_control() is playing + * nice by using session.msgbuf to assemble the message. + * + * void monitor_log(const char *fmt, ...) + * Write a message to the packet window. Safe if the packet window + * is not on screen. + * + * void monitor_complain(const char *fmt, ...) + * Post an error message to the command window, wait till user presses a key. + * You get to make sure the message will fit. + * + * void monitor_fixframe(WINDOW *win) + * Fix the frame of win to the right of the current location by redrawing + * ACS_VLINE there. Useful after doing wclrtoeol() and writing on the + * line. + * + * The libgpsd session object is accessible as the global variable 'session'. + */ diff --git a/monitor_sirf.c b/monitor_sirf.c new file mode 100644 index 0000000..09b38bf --- /dev/null +++ b/monitor_sirf.c @@ -0,0 +1,743 @@ +/* + * SiRF object for the GPS packet monitor. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + */ +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd_config.h" + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif /* HAVE_NCURSES_H */ +#include "gpsd.h" + +#include "bits.h" +#include "gpsmon.h" + +#if defined(SIRF_ENABLE) && defined(BINARY_ENABLE) +extern const struct gps_type_t sirf_binary; + +static WINDOW *mid2win, *mid4win, *mid6win, *mid7win, *mid9win, *mid13win; +static WINDOW *mid19win, *mid27win; +static bool dispmode = false, subframe_enabled = false; +static int nfix, fix[20]; + +/*@ -nullassign @*/ +static char *verbpat[] = { + "#Time:", + "@R Time:", + "CSTD: New almanac for", + "NOTICE: DOP Q Boost", + "RTC not set", + "numOfSVs = 0", + "rtcaj tow ", + NULL +}; + +/*@ +nullassign @*/ + +static char *dgpsvec[] = { + "None", + "SBAS", + "Serial", + "Beacon", + "Software", +}; + +/* check range of an unsigned quantity */ +#define CHECK_RANGE(vec, i) ((i) < sizeof(vec)/sizeof(vec[0])) + +/***************************************************************************** + * + * SiRF packet-decoding routines + * + *****************************************************************************/ + +#define display (void)mvwprintw + +#define MAXSATS 12 /* the most satellites we can dump data on */ + +static bool sirf_initialize(void) +{ + unsigned int i; + + /*@ -onlytrans @*/ + mid2win = subwin(devicewin, 7, 80, 1, 0); + mid4win = subwin(devicewin, MAXSATS + 3, 30, 8, 0); + mid6win = subwin(devicewin, 3, 50, 8, 30); + mid7win = subwin(devicewin, 4, 50, 11, 30); + mid9win = subwin(devicewin, 3, 50, 15, 30); + mid13win = subwin(devicewin, 3, 50, 18, 30); + mid19win = newwin(16, 50, 8, 30); + mid27win = subwin(devicewin, 3, 50, 21, 30); + if (mid2win == NULL || mid4win == NULL || mid6win == NULL + || mid9win == NULL || mid13win == NULL || mid19win == NULL + || mid27win == NULL) + return false; + + (void)syncok(mid2win, true); + (void)syncok(mid4win, true); + (void)syncok(mid6win, true); + (void)syncok(mid7win, true); + (void)syncok(mid9win, true); + (void)syncok(mid13win, true); + (void)syncok(mid27win, true); + + /*@ -nullpass @*/ + (void)wborder(mid2win, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(mid2win, A_BOLD); + (void)wmove(mid2win, 0, 1); + display(mid2win, 0, 12, " X "); + display(mid2win, 0, 21, " Y "); + display(mid2win, 0, 30, " Z "); + display(mid2win, 0, 43, " North "); + display(mid2win, 0, 54, " East "); + display(mid2win, 0, 65, " Alt "); + + (void)wmove(mid2win, 1, 1); + (void)wprintw(mid2win, + "Pos: m m"); + (void)wmove(mid2win, 2, 1); + (void)wprintw(mid2win, + "Vel: m/s climb m/s"); + (void)wmove(mid2win, 3, 1); + (void)wprintw(mid2win, + "Week+TOW: Day: Heading: speed m/s"); + (void)wmove(mid2win, 4, 1); + (void)wprintw(mid2win, + "Skew: TZ: HDOP: M1: M2: "); + (void)wmove(mid2win, 5, 1); + (void)wprintw(mid2win, "Fix:"); + display(mid2win, 6, 24, " Packet type 2 (0x02) "); + (void)wattrset(mid2win, A_NORMAL); + + (void)wborder(mid4win, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(mid4win, A_BOLD); + display(mid4win, 1, 1, "Ch PRN Az El Stat C/N ? A"); + for (i = 0; i < MAXSATS; i++) { + display(mid4win, (int)(i + 2), 1, "%2d", i); + } + display(mid4win, 14, 4, " Packet Type 4 (0x04) "); + (void)wattrset(mid4win, A_NORMAL); + + (void)wborder(mid19win, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(mid19win, A_BOLD); + display(mid19win, 1, 1, "Alt. hold mode:"); + display(mid19win, 2, 1, "Alt. hold source:"); + display(mid19win, 3, 1, "Alt. source input:"); + display(mid19win, 4, 1, "Degraded timeout:"); + display(mid19win, 5, 1, "DR timeout:"); + display(mid19win, 6, 1, "Track smooth mode:"); + display(mid19win, 7, 1, "Static Navigation:"); + display(mid19win, 8, 1, "3SV Least Squares:"); + display(mid19win, 9, 1, "DOP Mask mode:"); + display(mid19win, 10, 1, "Nav. Elev. mask:"); + display(mid19win, 11, 1, "Nav. Power mask:"); + display(mid19win, 12, 1, "DGPS Source:"); + display(mid19win, 13, 1, "DGPS Mode:"); + display(mid19win, 14, 1, "DGPS Timeout:"); + display(mid19win, 1, 26, "LP Push-to-Fix:"); + display(mid19win, 2, 26, "LP On Time:"); + display(mid19win, 3, 26, "LP Interval:"); + display(mid19win, 4, 26, "U. Tasks Enab.:"); + display(mid19win, 5, 26, "U. Task Inter.:"); + display(mid19win, 6, 26, "LP Pwr Cyc En:"); + display(mid19win, 7, 26, "LP Max Acq Srch:"); + display(mid19win, 8, 26, "LP Max Off Time:"); + display(mid19win, 9, 26, "APM enabled:"); + display(mid19win, 10, 26, "# of Fixes:"); + display(mid19win, 11, 26, "Time btw Fixes:"); + display(mid19win, 12, 26, "H/V Error Max:"); + display(mid19win, 13, 26, "Rsp Time Max:"); + display(mid19win, 14, 26, "Time/Accu:"); + + display(mid19win, 15, 8, " Packet type 19 (0x13) "); + (void)wattrset(mid19win, A_NORMAL); + + (void)wborder(mid6win, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(mid6win, A_BOLD); + display(mid6win, 1, 1, "Version:"); + display(mid6win, 2, 8, " Packet Type 6 (0x06) "); + (void)wattrset(mid6win, A_NORMAL); + + (void)wborder(mid7win, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(mid7win, A_BOLD); + display(mid7win, 1, 1, "SVs: "); + display(mid7win, 1, 9, "Drift: "); + display(mid7win, 1, 23, "Bias: "); + display(mid7win, 2, 1, "Estimated GPS Time: "); + display(mid7win, 3, 8, " Packet type 7 (0x07) "); + (void)wattrset(mid7win, A_NORMAL); + + (void)wborder(mid9win, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(mid9win, A_BOLD); + display(mid9win, 1, 1, "Max: "); + display(mid9win, 1, 13, "Lat: "); + display(mid9win, 1, 25, "Time: "); + display(mid9win, 1, 39, "MS: "); + display(mid9win, 2, 8, " Packet type 9 (0x09) "); + (void)wattrset(mid9win, A_NORMAL); + + (void)wborder(mid13win, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(mid13win, A_BOLD); + display(mid13win, 1, 1, "SVs: "); + display(mid13win, 1, 9, "="); + display(mid13win, 2, 8, " Packet type 13 (0x0D) "); + (void)wattrset(mid13win, A_NORMAL); + + (void)wborder(mid27win, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(mid27win, A_BOLD); + display(mid27win, 1, 1, "DGPS source: "); + display(mid27win, 1, 31, "Corrections: "); + display(mid27win, 2, 8, " Packet type 27 (0x1B) "); + (void)wattrset(mid27win, A_NORMAL); + /*@ +nullpass @*/ + /*@ -onlytrans @*/ + +#ifdef ALLOW_CONTROLSEND + /* probe for version */ + /*@ -compdef @*/ + (void)monitor_control_send((unsigned char *)"\x84\x00", 2); + /*@ +compdef @*/ +#endif /* ALLOW_CONTROLSEND */ + + return true; +} + +static void decode_time(int week, int tow) +{ + int day = tow / 8640000; + int tod = tow % 8640000; + int h = tod / 360000; + int m = tod % 360000; + int s = m % 6000; + + m = (m - s) / 6000; + + (void)wmove(mid2win, 3, 10); + (void)wprintw(mid2win, "%4d+%9.2f", week, (double)tow / 100); + (void)wmove(mid2win, 3, 30); + (void)wprintw(mid2win, "%d %02d:%02d:%05.2f", day, h, m, (double)s / 100); + (void)wmove(mid2win, 4, 8); + (void)wattrset(mid2win, A_UNDERLINE); + (void)wprintw(mid2win, "%f", + timestamp() - gpstime_to_unix(week, tow / 100.0)); + (void)wmove(mid2win, 4, 29); + (void)wprintw(mid2win, "%d", gmt_offset); + (void)wattrset(mid2win, A_NORMAL); +} + +static void decode_ecef(double x, double y, double z, + double vx, double vy, double vz) +{ + const double a = WGS84A; + const double b = WGS84B; + const double e2 = (a * a - b * b) / (a * a); + const double e_2 = (a * a - b * b) / (b * b); + double lambda, p, theta, phi, n, h, vnorth, veast, vup, speed, heading; + + lambda = atan2(y, x); + /*@ -evalorder @*/ + p = sqrt(pow(x, 2) + pow(y, 2)); + theta = atan2(z * a, p * b); + phi = + atan2(z + e_2 * b * pow(sin(theta), 3), + p - e2 * a * pow(cos(theta), 3)); + n = a / sqrt(1.0 - e2 * pow(sin(phi), 2)); + h = p / cos(phi) - n; + h -= wgs84_separation((double)(RAD_2_DEG * phi), + (double)(RAD_2_DEG * lambda)); + vnorth = + -vx * sin(phi) * cos(lambda) - vy * sin(phi) * sin(lambda) + + vz * cos(phi); + veast = -vx * sin(lambda) + vy * cos(lambda); + vup = + vx * cos(phi) * cos(lambda) + vy * cos(phi) * sin(lambda) + + vz * sin(phi); + speed = sqrt(pow(vnorth, 2) + pow(veast, 2)); + heading = atan2(veast, vnorth); + /*@ +evalorder @*/ + if (heading < 0) + heading += 2 * GPS_PI; + + (void)wattrset(mid2win, A_UNDERLINE); + (void)wmove(mid2win, 1, 40); + (void)wprintw(mid2win, "%9.5f %9.5f", (double)(RAD_2_DEG * phi), + (double)(RAD_2_DEG * lambda)); + (void)mvwaddch(mid2win, 1, 49, ACS_DEGREE); + (void)mvwaddch(mid2win, 1, 59, ACS_DEGREE); + (void)wmove(mid2win, 1, 61); + (void)wprintw(mid2win, "%8d", (int)h); + + (void)wmove(mid2win, 2, 40); + (void)wprintw(mid2win, "%9.1f %9.1f", vnorth, veast); + (void)wmove(mid2win, 2, 61); + (void)wprintw(mid2win, "%8.1f", vup); + + (void)wmove(mid2win, 3, 54); + (void)wprintw(mid2win, "%5.1f", (double)(RAD_2_DEG * heading)); + (void)mvwaddch(mid2win, 3, 59, ACS_DEGREE); + (void)wmove(mid2win, 3, 61); + (void)wprintw(mid2win, "%8.1f", speed); + (void)wattrset(mid2win, A_NORMAL); +} + +/*@ -globstate */ +static void sirf_update(void) +{ + int i, j, ch, off, cn; + unsigned char *buf; + size_t len; + uint8_t dgps; + + assert(mid27win != NULL); + buf = session.packet.outbuffer + 4; + len = session.packet.outbuflen - 8; + switch (buf[0]) { + case 0x02: /* Measured Navigation Data */ + (void)wmove(mid2win, 1, 6); /* ECEF position */ + (void)wprintw(mid2win, "%8d %8d %8d", getbesl(buf, 1), + getbesl(buf, 5), getbesl(buf, 9)); + (void)wmove(mid2win, 2, 6); /* ECEF velocity */ + (void)wprintw(mid2win, "%8.1f %8.1f %8.1f", + (double)getbesw(buf, 13) / 8, (double)getbesw(buf, + 15) / 8, + (double)getbesw(buf, 17) / 8); + decode_ecef((double)getbesl(buf, 1), (double)getbesl(buf, 5), + (double)getbesl(buf, 9), (double)getbesw(buf, 13) / 8, + (double)getbesw(buf, 15) / 8, (double)getbesw(buf, + 17) / 8); + decode_time((int)getbeuw(buf, 22), getbesl(buf, 24)); + /* line 4 */ + (void)wmove(mid2win, 4, 49); + (void)wprintw(mid2win, "%4.1f", (double)getub(buf, 20) / 5); /* HDOP */ + (void)wmove(mid2win, 4, 58); + (void)wprintw(mid2win, "%02x", getub(buf, 19)); /* Mode 1 */ + (void)wmove(mid2win, 4, 70); + (void)wprintw(mid2win, "%02x", getub(buf, 21)); /* Mode 2 */ + (void)wmove(mid2win, 5, 7); + nfix = (int)getub(buf, 28); + (void)wprintw(mid2win, "%d = ", nfix); /* SVs in fix */ + for (i = 0; i < MAXSATS; i++) { /* SV list */ + if (i < nfix) + (void)wprintw(mid2win, "%3d", fix[i] = + (int)getub(buf, 29 + i)); + else + (void)wprintw(mid2win, " "); + } + monitor_log("MND 0x02="); + break; + + case 0x04: /* Measured Tracking Data */ + decode_time((int)getbeuw(buf, 1), getbesl(buf, 3)); + ch = (int)getub(buf, 7); + for (i = 0; i < ch; i++) { + int sv, st; + + off = 8 + 15 * i; + (void)wmove(mid4win, i + 2, 3); + sv = (int)getub(buf, off); + (void)wprintw(mid4win, " %3d", sv); + + (void)wprintw(mid4win, " %3d%3d %04x", + ((int)getub(buf, off + 1) * 3) / 2, (int)getub(buf, + off + + 2) / + 2, (int)getbesw(buf, off + 3)); + + st = ' '; + if ((int)getbeuw(buf, off + 3) == 0xbf) + st = 'T'; + for (j = 0; j < nfix; j++) + if (sv == fix[j]) { + st = 'N'; + break; + } + + cn = 0; + + for (j = 0; j < 10; j++) + cn += (int)getub(buf, off + 5 + j); + + (void)wprintw(mid4win, "%5.1f %c", (double)cn / 10, st); + + if (sv == 0) /* not tracking? */ + (void)wprintw(mid4win, " "); /* clear other info */ + } + monitor_log("MTD 0x04="); + break; + +#ifdef __UNUSED__ + case 0x05: /* raw track data */ + for (off = 1; off < len; off += 51) { + ch = getbeul(buf, off); + (void)wmove(mid4win, ch + 2, 19); + cn = 0; + + for (j = 0; j < 10; j++) + cn += getub(buf, off + 34 + j); + + printw("%5.1f", (double)cn / 10); + + printw("%9d%3d%5d", getbeul(buf, off + 8), + (int)getbeuw(buf, off + 12), (int)getbeuw(buf, off + 14)); + printw("%8.5f %10.5f", (double)getbeul(buf, off + 16) / 65536, + (double)getbeul(buf, off + 20) / 1024); + } + monitor_log("RTD 0x05="); + break; +#endif /* __UNUSED */ + + case 0x06: /* firmware version */ + display(mid6win, 1, 10, "%s", buf + 1); + monitor_log("FV 0x06="); + break; + + case 0x07: /* Response - Clock Status Data */ + decode_time((int)getbeuw(buf, 1), getbesl(buf, 3)); + display(mid7win, 1, 5, "%2d", getub(buf, 7)); /* SVs */ + display(mid7win, 1, 16, "%lu", getbeul(buf, 8)); /* Clock drift */ + display(mid7win, 1, 29, "%lu", getbeul(buf, 12)); /* Clock Bias */ + display(mid7win, 2, 21, "%lu", getbeul(buf, 16)); /* Estimated Time */ + monitor_log("CSD 0x07="); + break; + + case 0x08: /* 50 BPS data */ + ch = (int)getub(buf, 1); + display(mid4win, ch + 2, 27, "Y"); + monitor_log("50B 0x08="); + subframe_enabled = true; + break; + + case 0x09: /* Throughput */ + display(mid9win, 1, 6, "%.3f", (double)getbeuw(buf, 1) / 186); /*SegStatMax */ + display(mid9win, 1, 18, "%.3f", (double)getbeuw(buf, 3) / 186); /*SegStatLat */ + display(mid9win, 1, 31, "%.3f", (double)getbeuw(buf, 5) / 186); /*SegStatTime */ + display(mid9win, 1, 42, "%3d", (int)getbeuw(buf, 7)); /* Last Millisecond */ + monitor_log("THR 0x09="); + break; + + case 0x0b: /* Command Acknowledgement */ + monitor_log("ACK 0x0b="); + break; + + case 0x0c: /* Command NAcknowledgement */ + monitor_log("NAK 0x0c="); + break; + + case 0x0d: /* Visible List */ + display(mid13win, 1, 6, "%02d", getub(buf, 1)); + (void)wmove(mid13win, 1, 10); + for (i = 0; i < MAXSATS; i++) { + if (i < (int)getub(buf, 1)) + (void)wprintw(mid13win, " %2d", getub(buf, 2 + 5 * i)); + else + (void)wprintw(mid13win, " "); + } + monitor_log("VL 0x0d="); + break; + + case 0x13: +#define YESNO(n) (((int)getub(buf, n) != 0)?'Y':'N') + display(mid19win, 1, 20, "%d", getub(buf, 5)); /* Alt. hold mode */ + display(mid19win, 2, 20, "%d", getub(buf, 6)); /* Alt. hold source */ + display(mid19win, 3, 20, "%dm", (int)getbeuw(buf, 7)); /* Alt. source input */ + if (getub(buf, 9) != (uint8_t) '\0') + display(mid19win, 4, 20, "%dsec", getub(buf, 10)); /* Degraded timeout */ + else + display(mid19win, 4, 20, "N/A "); + display(mid19win, 5, 20, "%dsec", getub(buf, 11)); /* DR timeout */ + display(mid19win, 6, 20, "%c", YESNO(12)); /* Track smooth mode */ + display(mid19win, 7, 20, "%c", YESNO(13)); /* Static Nav. */ + display(mid19win, 8, 20, "0x%x", getub(buf, 14)); /* 3SV Least Squares */ + display(mid19win, 9, 20, "0x%x", getub(buf, 19)); /* DOP Mask mode */ + display(mid19win, 10, 20, "0x%x", (int)getbeuw(buf, 20)); /* Nav. Elev. mask */ + display(mid19win, 11, 20, "0x%x", getub(buf, 22)); /* Nav. Power mask */ + display(mid19win, 12, 20, "0x%x", getub(buf, 27)); /* DGPS Source */ + display(mid19win, 13, 20, "0x%x", getub(buf, 28)); /* DGPS Mode */ + display(mid19win, 14, 20, "%dsec", getub(buf, 29)); /* DGPS Timeout */ + display(mid19win, 1, 42, "%c", YESNO(34)); /* LP Push-to-Fix */ + display(mid19win, 2, 42, "%dms", getbeul(buf, 35)); /* LP On Time */ + display(mid19win, 3, 42, "%d", getbeul(buf, 39)); /* LP Interval */ + display(mid19win, 4, 42, "%c", YESNO(43)); /* User Tasks enabled */ + display(mid19win, 5, 42, "%d", getbeul(buf, 44)); /* User Task Interval */ + display(mid19win, 6, 42, "%c", YESNO(48)); /* LP Power Cycling Enabled */ + display(mid19win, 7, 42, "%d", getbeul(buf, 49)); /* LP Max Acq Search Time */ + display(mid19win, 8, 42, "%d", getbeul(buf, 53)); /* LP Max Off Time */ + display(mid19win, 9, 42, "%c", YESNO(57)); /* APM Enabled */ + display(mid19win, 10, 42, "%d", (int)getbeuw(buf, 58)); /* # of fixes */ + display(mid19win, 11, 42, "%d", (int)getbeuw(buf, 60)); /* Time Between fixes */ + display(mid19win, 12, 42, "%d", getub(buf, 62)); /* H/V Error Max */ + display(mid19win, 13, 42, "%d", getub(buf, 63)); /* Response Time Max */ + display(mid19win, 14, 42, "%d", getub(buf, 64)); /* Time/Accu & Duty Cycle Priority */ +#undef YESNO + break; + + case 0x1b: + /****************************************************************** + Not actually documented in any published materials. + Here is what Chris Kuethe got from the SiRF folks, + (plus some corrections from the GpsPaSsion forums): + + Start of message + ---------------- + Message ID 1 byte 27 + Correction Source 1 byte 0=None, 1=SBAS, 2=Serial, 3=Beacon, + 4=Software + + total: 2 bytes + + Middle part of message varies if using beacon or other: + ------------------------------------------------------- + If Beacon: + Receiver Freq Hz 4 bytes + Bit rate BPS 1 byte + Status bit map 1 byte 01=Signal Valid, + 02=Auto frequency detect + 04=Auto bit rate detect + Signal Magnitude 4 bytes Note: in internal units + Signal Strength dB 2 bytes derived from Signal Magnitude + SNR dB 2 bytes + + total: 14 bytes + + If Not Beacon: + Correction Age[12] 1 byte x 12 Age in seconds in same order as follows + Reserved 2 bytes + + total: 14 bytes + + End of Message + -------------- + Repeated 12 times (pad with 0 if less than 12 SV corrections): + SVID 1 byte + Correction (cm) 2 bytes (signed short) + + total 3 x 12 = 36 bytes + ******************************************************************/ + dgps = getub(buf, 1); + display(mid27win, 1, 14, "%d (%s)", + dgps, (CHECK_RANGE(dgpsvec, dgps) ? dgpsvec[dgps] : "???")); + /*@ -type @*/ + //(void) wmove(mid27win, 2, 0); + for (i = j = 0; i < 12; i++) { + if (getub(buf, 16 + 3 * i) != '\0') { + //(void)wprintw(mid27win, " %d=%d", getub(buf, 16+3*i), getbesw(buf, 16+3*i+1)); + j++; + } + } + /*@ +type @*/ + display(mid27win, 1, 44, "%d", j); + monitor_log("DST 0x1b="); + break; + + case 0x1C: /* NL Measurement Data */ + case 0x1D: /* DGPS Data */ + case 0x1E: /* SV State Data */ + case 0x1F: /* NL Initialized Data */ + subframe_enabled = true; + break; + case 0x29: /* Geodetic Navigation Message */ + monitor_log("GNM 0x29="); + break; + case 0x32: /* SBAS Parameters */ + monitor_log("SBP 0x32="); + break; + case 0x34: /* PPS Time */ + monitor_log("PPS 0x34="); + break; + +#ifdef __UNUSED__ + case 0x62: + attrset(A_BOLD); + move(2, 40); + printw("%9.5f %9.5f", (double)(RAD_2_DEG * 1e8 * getbesl(buf, 1)), + (double)(RAD_2_DEG * 1e8 * getbesl(buf, 5))); + move(2, 63); + printw("%8d", getbesl(buf, 9) / 1000); + + move(3, 63); + + printw("%8.1f", (double)getbesl(buf, 17) / 1000); + + move(4, 54); + if (getbeul(buf, 13) > 50) { + double heading = RAD_2_DEG * 1e8 * getbesl(buf, 21); + if (heading < 0) + heading += 360; + printw("%5.1f", heading); + } else + printw(" 0.0"); + + move(4, 63); + printw("%8.1f", (double)getbesl(buf, 13) / 1000); + attrset(A_NORMAL); + + move(5, 13); + printw("%04d-%02d-%02d %02d:%02d:%02d.%02d", + (int)getbeuw(buf, 26), getub(buf, 28), getub(buf, 29), + getub(buf, 30), getub(buf, 31), (unsigned short)getbeuw(buf, + 32) / + 1000, ((unsigned short)getbeuw(buf, 32) % 1000) / 10); + { + struct timeval clk, gps; + struct tm tm; + + gettimeofday(&clk, NULL); + + memset(&tm, 0, sizeof(tm)); + tm.tm_sec = (unsigned short)getbeuw(buf, 32) / 1000; + tm.tm_min = (int)getub(buf, 31); + tm.tm_hour = (int)getub(buf, 30); + tm.tm_mday = (int)getub(buf, 29); + tm.tm_mon = (int)getub(buf, 28) - 1; + tm.tm_year = (int)getbeuw(buf, 26) - 1900; + + gps.tv_sec = mkgmtime(&tm); + gps.tv_usec = + (((unsigned short)getbeuw(buf, 32) % 1000) / 10) * 10000; + + move(5, 2); + printw(" "); + move(5, 2); +#if 1 + printw("%ld", (gps.tv_usec - clk.tv_usec) + + ((gps.tv_sec - clk.tv_sec) % 3600) * 1000000); +#else + printw("%ld %ld %ld %ld", gps.tv_sec % 3600, gps.tv_usec, + clk.tv_sec % 3600, clk.tv_usec); +#endif + } + monitor_log("??? 0x62="); + break; +#endif /* __UNUSED__ */ + + case 0xff: /* Development Data */ + /*@ +ignoresigns @*/ + while (len > 0 && buf[len - 1] == '\n') + len--; + while (len > 0 && buf[len - 1] == ' ') + len--; + /*@ -ignoresigns @*/ + buf[len] = '\0'; + j = 1; + for (i = 0; verbpat[i] != NULL; i++) + if (strncmp((char *)(buf + 1), verbpat[i], strlen(verbpat[i])) == + 0) { + j = 0; + break; + } + if (j != 0) + monitor_log("%s\n", buf + 1); + monitor_log("DD 0xff="); + break; + + default: + monitor_log(" 0x%02x=", buf[4]); + break; + } + +#ifdef ALLOW_CONTROLSEND + /* elicit navigation parameters */ + if (dispmode && (time(NULL) % 10 == 0)) { + (void)monitor_control_send((unsigned char *)"\x98\x00", 2); + } +#endif /* ALLOW_CONTROLSEND */ + + /*@ -nullpass -nullderef @*/ + if (dispmode) { + (void)touchwin(mid19win); + (void)wnoutrefresh(mid19win); + } + /*@ +nullpass -nullderef @*/ +} + +/*@ +globstate */ + +#ifdef ALLOW_CONTROLSEND +static int sirf_command(char line[]) +{ + unsigned char buf[BUFSIZ]; + int v; + + switch (line[0]) { + case 'A': /* toggle 50bps subframe data */ + (void)memset(buf, '\0', sizeof(buf)); + putbyte(buf, 0, 0x80); + putbyte(buf, 23, 12); + putbyte(buf, 24, subframe_enabled ? 0x00 : 0x10); + (void)monitor_control_send(buf, 25); + return COMMAND_MATCH; + + case 'M': /* static navigation */ + putbyte(buf, 0, 0x8f); /* id */ + putbyte(buf, 1, atoi(line + 1)); + (void)monitor_control_send(buf, 2); + return COMMAND_MATCH; + + case 'D': /* MID 4 rate change (undocumented) */ + v = atoi(line + 1); + if (v > 30) + return COMMAND_MATCH; + putbyte(buf, 0, 0xa6); + putbyte(buf, 1, 0); + putbyte(buf, 2, 4); /* satellite picture */ + putbyte(buf, 3, v); + putbyte(buf, 4, 0); + putbyte(buf, 5, 0); + putbyte(buf, 6, 0); + putbyte(buf, 7, 0); + (void)monitor_control_send(buf, 8); + return COMMAND_MATCH; + + case 'P': /* poll navigation params */ + dispmode = !dispmode; + return COMMAND_MATCH; + } + + return COMMAND_UNKNOWN; /* no match */ +} +#endif /* ALLOW_CONTROLSEND */ + +static void sirf_wrap(void) +{ + (void)delwin(mid2win); + (void)delwin(mid4win); + (void)delwin(mid6win); + (void)delwin(mid7win); + (void)delwin(mid9win); + (void)delwin(mid13win); + (void)delwin(mid19win); + (void)delwin(mid27win); +} + +const struct monitor_object_t sirf_mmt = { + .initialize = sirf_initialize, + .update = sirf_update, +#ifdef ALLOW_CONTROLSEND + .command = sirf_command, +#else + .command = NULL, +#endif /* ALLOW_CONTROLSEND */ + .wrap = sirf_wrap, + .min_y = 23,.min_x = 80, + .driver = &sirf_binary, +}; +#endif /* defined(SIRF_ENABLE) && defined(BINARY_ENABLE) */ + +/* sirfmon.c ends here */ diff --git a/monitor_superstar2.c b/monitor_superstar2.c new file mode 100644 index 0000000..340f59f --- /dev/null +++ b/monitor_superstar2.c @@ -0,0 +1,124 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd_config.h" + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif /* HAVE_NCURSES_H */ +#include "gpsd.h" + +#include "bits.h" +#include "gpsmon.h" + +#ifdef SUPERSTAR2_ENABLE +#include "driver_superstar2.h" +extern const struct gps_type_t superstar2_binary; +static WINDOW *satwin; + +static bool superstar2_initialize(void) +{ + int i; + + /*@ -onlytrans @*/ + /* "heavily inspired" by monitor_nmea.c */ + if ((satwin = derwin(devicewin, 15, 27, 7, 0)) == NULL) + return false; + (void)wborder(satwin, 0, 0, 0, 0, 0, 0, 0, 0), (void)syncok(satwin, true); + (void)wattrset(satwin, A_BOLD); + (void)mvwprintw(satwin, 1, 1, "Ch PRN Az El S/N Fl U"); + for (i = 0; i < 12; i++) + (void)mvwprintw(satwin, (int)(i + 2), 1, "%2d", i); + (void)mvwprintw(satwin, 14, 1, " Satellite Data & Status "); + (void)wattrset(satwin, A_NORMAL); + /*@ +onlytrans @*/ + + return true; +} + +static void display_superstar2_svinfo(unsigned char *buf, size_t data_len) +{ + int i; + + if (data_len != 67) + return; + + for (i = 0; i < 12; i++) { + /* get info for one channel/satellite */ + int off = i * 5 + 5; + unsigned char fl, porn, ss; + char el; + unsigned short az; + + /*@ +charint */ + if ((porn = (unsigned char)getub(buf, off) & 0x1f) == 0) + porn = ((unsigned char)getub(buf, off + 3) >> 1) + 87; + /*@ -charint */ + + ss = (unsigned char)getub(buf, off + 4); + el = getsb(buf, off + 1); + az = (unsigned short)(getub(buf, off + 2) + + ((getub(buf, off + 3) & 0x1) << 1)); + fl = (unsigned char)getub(buf, off) & 0xe0; + (void)wmove(satwin, i + 2, 4); + /*@ +charint */ + (void)wprintw(satwin, "%3u %3d %2d %02d %02x %c", + porn, az, el, ss, fl, + ((fl & 0x60) == 0x60) ? 'Y' : ' '); + /*@ -charint */ + } + (void)wnoutrefresh(satwin); + return; +} + +static void superstar2_update(void) +{ + unsigned char *buf; + size_t len; + unsigned char type; + + buf = session.packet.outbuffer; + len = session.packet.outbuflen; + type = buf[SUPERSTAR2_TYPE_OFFSET]; + switch (type) { + case SUPERSTAR2_SVINFO: + display_superstar2_svinfo(buf, len - 3); + break; + default: + break; + } +} + +static int superstar2_command(char line[]UNUSED) +{ + return COMMAND_UNKNOWN; +} + +static void superstar2_wrap(void) +{ +} + +const struct monitor_object_t superstar2_mmt = { + .initialize = superstar2_initialize, + .update = superstar2_update, + .command = superstar2_command, + .wrap = superstar2_wrap, + .min_y = 23,.min_x = 80, /* size of the device window */ + .driver = &superstar2_binary, +}; +#endif diff --git a/monitor_tnt.c b/monitor_tnt.c new file mode 100644 index 0000000..a7fe523 --- /dev/null +++ b/monitor_tnt.c @@ -0,0 +1,147 @@ +/* + * monitor_tnt.c - gpsmon support for True North Revolution devices. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd_config.h" + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif /* HAVE_NCURSES_H */ +#include "gpsd.h" + +#include "bits.h" +#include "gpsmon.h" + +#ifdef TNT_ENABLE +extern const struct gps_type_t trueNorth; + +static WINDOW *thtmwin; + +static bool tnt_initialize(void) +{ + /*@ -onlytrans @*/ + thtmwin = derwin(devicewin, 6, 80, 0, 0); + (void)wborder(thtmwin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)syncok(thtmwin, true); + (void)wattrset(thtmwin, A_BOLD); + (void)mvwaddstr(thtmwin, 0, 35, " PTNTHTM "); + (void)mvwaddstr(thtmwin, 1, 1, "Heading: "); + (void)mvwaddstr(thtmwin, 2, 1, "Pitch: "); + (void)mvwaddstr(thtmwin, 3, 1, "Roll: "); + (void)mvwaddstr(thtmwin, 4, 1, "Dip: "); + + (void)mvwaddstr(thtmwin, 1, 40, "Magnetometer Status: "); + (void)mvwaddstr(thtmwin, 2, 40, "Pitch Status: "); + (void)mvwaddstr(thtmwin, 3, 40, "Roll Status "); + (void)mvwaddstr(thtmwin, 4, 40, "Horizontal Field: "); + (void)wattrset(thtmwin, A_NORMAL); + /*@ +onlytrans @*/ + return true; +} + +static void tnt_update(void) +{ + /* + * We have to do our own field parsing because the way this + * gets valled, nmea_parse() is never called on the sentence. + */ + (void)nmea_parse((char *)session.packet.outbuffer, &session); + + (void)mvwaddstr(thtmwin, 1, 19, session.driver.nmea.field[1]); + (void)mvwaddstr(thtmwin, 2, 19, session.driver.nmea.field[3]); + (void)mvwaddstr(thtmwin, 3, 19, session.driver.nmea.field[5]); + (void)mvwaddstr(thtmwin, 4, 19, session.driver.nmea.field[7]); + + (void)mvwaddstr(thtmwin, 1, 61, session.driver.nmea.field[2]); + (void)mvwaddstr(thtmwin, 2, 61, session.driver.nmea.field[4]); + (void)mvwaddstr(thtmwin, 3, 61, session.driver.nmea.field[6]); + (void)mvwaddstr(thtmwin, 4, 61, session.driver.nmea.field[8]); +} + +static int tnt_command(char line[]) +{ + /* + * Interpret a command line. Whatever characters the user types will + * be echoed in the command buffer at the top right of the display. When + * he/she presses enter the command line will be passed to this function + * for interpretation. Note: packet receipt is suspended while this + * function is executing. + * + * This method is optional. If you set the command method pointer to + * NULL, gpsmon will behave sanely, accepting no device-specific commands. + * + * It is a useful convention to use uppercase letters for + * driver-specific commands and leave lowercase ones for the + * generic gpsmon ones. + */ + + /* + * Return COMMAND_UNKNOWN to tell gpsmon you can't interpret the line, and + * it will be passed to the generic command interpreter to be handled there. + * You can alse return COMMAND_MATCH to tell it you handled the command, + * or COMMAND_TERMINATE to tell gpsmon you handled it and gpsmon should + * terminate. + */ + return COMMAND_UNKNOWN; +} + +static void tnt_wrap(void) +{ + (void)delwin(thtmwin); +} + +/* + * Use mmt = monitor method table as a suffix for naming these things + * Yours will need to be added to the monitor_objects table in gpsmon.c, + * then of course you need to link your module into gpsmon. + */ +const struct monitor_object_t tnt_mmt = { + .initialize = tnt_initialize, + .update = tnt_update, + .command = tnt_command, + .wrap = tnt_wrap, + .min_y = 6,.min_x = 80, /* size of the device window */ + .driver = &trueNorth, +}; +#endif /* TNT_ENABLE */ + +/* + * Helpers: + * + * bool monitor_control_send(unsigned char *buf, size_t len) + * Ship a packet payload to the device. Calls the driver send_control() + * method to add headers/trailers/checksum; also dumps the sent + * packet to the packet window, if the send_control() is playing + * nice by using session.msgbuf to assemble the message. + * + * void monitor_log(const char *fmt, ...) + * Write a message to the packet window. Safe if the packet window + * is not on screen. + * + * void monitor_complain(const char *fmt, ...) + * Post an error message to the command window, wait till user presses a key. + * You get to make sure the message will fit. + * + * void monitor_fixframe(WINDOW *win) + * Fix the frame of win to the right of the current location by redrawing + * ACS_VLINE there. Useful after doing wclrtoeol() and writing on the + * line. + * + * The libgpsd session object is accessible as the global variable 'session'. + */ diff --git a/monitor_ubx.c b/monitor_ubx.c new file mode 100644 index 0000000..1d46122 --- /dev/null +++ b/monitor_ubx.c @@ -0,0 +1,265 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd_config.h" + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif /* HAVE_NCURSES_H */ +#include "gpsd.h" + +#include "bits.h" +#include "gpsmon.h" + +#ifdef UBX_ENABLE +#include "driver_ubx.h" +extern const struct gps_type_t ubx_binary; +static WINDOW *satwin, *navsolwin, *dopwin; + +#define display (void)mvwprintw +static bool ubx_initialize(void) +{ + int i; + + /*@ -onlytrans @*/ + /* "heavily inspired" by monitor_nmea.c */ + if ((satwin = derwin(devicewin, 19, 28, 0, 0)) == NULL) + return false; + (void)wborder(satwin, 0, 0, 0, 0, 0, 0, 0, 0), (void)syncok(satwin, true); + (void)wattrset(satwin, A_BOLD); + (void)mvwprintw(satwin, 1, 1, "Ch PRN Az El S/N Flag U"); + for (i = 0; i < 16; i++) + (void)mvwprintw(satwin, (int)(i + 2), 1, "%2d", i); + (void)mvwprintw(satwin, 18, 7, " NAV_SVINFO "); + (void)wattrset(satwin, A_NORMAL); + /*@ -onlytrans @*/ + + /* "heavily inspired" by monitor_nmea.c */ + if ((navsolwin = derwin(devicewin, 13, 51, 0, 28)) == NULL) + return false; + (void)wborder(navsolwin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(navsolwin, A_BOLD); + (void)wmove(navsolwin, 1, 1); + (void)wprintw(navsolwin, "ECEF Pos:"); + (void)wmove(navsolwin, 2, 1); + (void)wprintw(navsolwin, "ECEF Vel:"); + + (void)wmove(navsolwin, 4, 1); + (void)wprintw(navsolwin, "LTP Pos:"); + (void)wmove(navsolwin, 5, 1); + (void)wprintw(navsolwin, "LTP Vel:"); + + (void)wmove(navsolwin, 7, 1); + (void)wprintw(navsolwin, "Time UTC:"); + (void)wmove(navsolwin, 8, 1); + (void)wprintw(navsolwin, "Time GPS: Day:"); + + (void)wmove(navsolwin, 10, 1); + (void)wprintw(navsolwin, "Est Pos Err m Est Vel Err m/s"); + (void)wmove(navsolwin, 11, 1); + (void)wprintw(navsolwin, "PRNs: ## PDOP: xx.x Fix 0x.. Flags 0x.."); + + display(navsolwin, 12, 20, " NAV_SOL "); + (void)wattrset(navsolwin, A_NORMAL); + + if ((dopwin = derwin(devicewin, 3, 51, 13, 28)) == NULL) + return false; + (void)wborder(dopwin, 0, 0, 0, 0, 0, 0, 0, 0), + (void)wattrset(dopwin, A_BOLD); + (void)wmove(dopwin, 1, 1); + (void)wprintw(dopwin, "DOP [H] [V] [P] [T] [G]"); + display(dopwin, 2, 20, " NAV_DOP "); + (void)wattrset(dopwin, A_NORMAL); + + return true; +} + +static void display_nav_svinfo(unsigned char *buf, size_t data_len) +{ + int i, nchan; + + if (data_len < 152) + return; + + nchan = (int)getub(buf, 4); + if (nchan > 16) + nchan = 16; + + for (i = 0; i < nchan; i++) { + int off = 8 + 12 * i; + unsigned char ss, prn; + char el; + short az; + unsigned short fl; + + prn = (unsigned char)getub(buf, off + 1); + fl = (unsigned short)getleuw(buf, off + 2); + ss = (unsigned char)getub(buf, off + 4); + el = getsb(buf, off + 5); + az = getlesw(buf, off + 6); + (void)wmove(satwin, (int)(i + 2), 4); + (void)wprintw(satwin, "%3d %3d %3d %2d %04x %c", + prn, az, el, ss, fl, (fl & UBX_SAT_USED) ? 'Y' : ' '); + } + (void)wnoutrefresh(satwin); + return; +} + +/*@ -mustfreeonly -compdestroy @*/ +static void display_nav_sol(unsigned char *buf, size_t data_len) +{ + unsigned short gw = 0; + unsigned int tow = 0, flags; + double epx, epy, epz, evx, evy, evz; + unsigned char navmode; + double t; + time_t tt; + struct gps_data_t g; + double separation; + + if (data_len != 52) + return; + + navmode = (unsigned char)getub(buf, 10); + flags = (unsigned int)getub(buf, 11); + + if ((flags & (UBX_SOL_VALID_WEEK | UBX_SOL_VALID_TIME)) != 0) { + tow = (unsigned int)getleul(buf, 0); + gw = (unsigned short)getlesw(buf, 8); + t = gpstime_to_unix((int)gw, tow / 1000.0); + tt = (time_t) trunc(t); + } + + epx = (double)(getlesl(buf, 12) / 100.0); + epy = (double)(getlesl(buf, 16) / 100.0); + epz = (double)(getlesl(buf, 20) / 100.0); + evx = (double)(getlesl(buf, 28) / 100.0); + evy = (double)(getlesl(buf, 32) / 100.0); + evz = (double)(getlesl(buf, 36) / 100.0); + ecef_to_wgs84fix(&g.fix, &separation, epx, epy, epz, evx, evy, evz); + g.fix.epx = g.fix.epy = (double)(getlesl(buf, 24) / 100.0); + g.fix.eps = (double)(getlesl(buf, 40) / 100.0); + g.dop.pdop = (double)(getleuw(buf, 44) / 100.0); + g.satellites_used = (int)getub(buf, 47); + + (void)wmove(navsolwin, 1, 11); + (void)wprintw(navsolwin, "%+10.2fm %+10.2fm %+10.2fm", epx, epy, epz); + (void)wmove(navsolwin, 2, 11); + (void)wprintw(navsolwin, "%+9.2fm/s %+9.2fm/s %+9.2fm/s", evx, evy, evz); + + (void)wmove(navsolwin, 4, 11); + (void)wprintw(navsolwin, "%12.9f %13.9f %8.2fm", + g.fix.latitude, g.fix.longitude, g.fix.altitude); + (void)mvwaddch(navsolwin, 4, 23, ACS_DEGREE); + (void)mvwaddch(navsolwin, 4, 39, ACS_DEGREE); + (void)wmove(navsolwin, 5, 11); + (void)wprintw(navsolwin, "%6.2fm/s %5.1fo %6.2fm/s", + g.fix.speed, g.fix.track, g.fix.climb); + (void)mvwaddch(navsolwin, 5, 26, ACS_DEGREE); + + (void)wmove(navsolwin, 7, 11); + /*@ -compdef @*/ + (void)wprintw(navsolwin, "%s", ctime(&tt)); + /*@ +compdef @*/ + (void)wmove(navsolwin, 8, 11); + if ((flags & (UBX_SOL_VALID_WEEK | UBX_SOL_VALID_TIME)) != 0) { + (void)wprintw(navsolwin, "%d+%10.3lf", gw, (double)(tow / 1000.0)); + (void)wmove(navsolwin, 8, 36); + (void)wprintw(navsolwin, "%d", (tow / 86400000)); + } + + /* relies on the fact that expx and epy are aet to same value */ + (void)wmove(navsolwin, 10, 12); + (void)wprintw(navsolwin, "%7.2f", g.fix.epx); + (void)wmove(navsolwin, 10, 33); + (void)wprintw(navsolwin, "%6.2f", g.fix.epv); + (void)wmove(navsolwin, 11, 7); + (void)wprintw(navsolwin, "%2d", g.satellites_used); + (void)wmove(navsolwin, 11, 15); + (void)wprintw(navsolwin, "%5.1f", g.dop.pdop); + (void)wmove(navsolwin, 11, 25); + (void)wprintw(navsolwin, "0x%02x", navmode); + (void)wmove(navsolwin, 11, 36); + (void)wprintw(navsolwin, "0x%02x", flags); + (void)wnoutrefresh(navsolwin); +} + +/*@ +mustfreeonly +compdestroy @*/ + +static void display_nav_dop(unsigned char *buf, size_t data_len) +{ + if (data_len != 18) + return; + (void)wmove(dopwin, 1, 9); + (void)wprintw(dopwin, "%4.1f", getleuw(buf, 12) / 100.0); + (void)wmove(dopwin, 1, 18); + (void)wprintw(dopwin, "%4.1f", getleuw(buf, 10) / 100.0); + (void)wmove(dopwin, 1, 27); + (void)wprintw(dopwin, "%4.1f", getleuw(buf, 6) / 100.0); + (void)wmove(dopwin, 1, 36); + (void)wprintw(dopwin, "%4.1f", getleuw(buf, 8) / 100.0); + (void)wmove(dopwin, 1, 45); + (void)wprintw(dopwin, "%4.1f", getleuw(buf, 4) / 100.0); + (void)wnoutrefresh(dopwin); +} + +static void ubx_update(void) +{ + unsigned char *buf; + size_t data_len; + unsigned short msgid; + + buf = session.packet.outbuffer; + msgid = (unsigned short)((buf[2] << 8) | buf[3]); + data_len = (size_t) getlesw(buf, 4); + switch (msgid) { + case UBX_NAV_SVINFO: + display_nav_svinfo(&buf[6], data_len); + break; + case UBX_NAV_DOP: + display_nav_dop(&buf[6], data_len); + break; + case UBX_NAV_SOL: + display_nav_sol(&buf[6], data_len); + break; + default: + break; + } + +} + +static int ubx_command(char line[]UNUSED) +{ + return COMMAND_UNKNOWN; +} + +static void ubx_wrap(void) +{ + (void)delwin(satwin); + return; +} + +const struct monitor_object_t ubx_mmt = { + .initialize = ubx_initialize, + .update = ubx_update, + .command = ubx_command, + .wrap = ubx_wrap, + .min_y = 23,.min_x = 80, /* size of the device window */ + .driver = &ubx_binary, +}; +#endif diff --git a/net_dgpsip.c b/net_dgpsip.c new file mode 100644 index 0000000..92eb5a2 --- /dev/null +++ b/net_dgpsip.c @@ -0,0 +1,173 @@ +/* net_dgpsip.c -- gather and dispatch DGPS data from DGPSIP servers + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include "gpsd_config.h" +#include +#ifndef S_SPLINT_S +#ifdef HAVE_SYS_SOCKET_H +#include +#else +#define AF_UNSPEC 0 +#endif /* HAVE_SYS_SOCKET_H */ +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#ifndef S_SPLINT_S +#ifdef HAVE_NETDB_H +#include +#endif /* HAVE_NETDB_H */ +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd.h" + +/*@ -branchstate */ +int dgpsip_open(struct gps_context_t *context, const char *dgpsserver) +/* open a connection to a DGPSIP server */ +{ + char hn[256], buf[BUFSIZ]; + char *colon, *dgpsport = "rtcm-sc104"; + int opts; + + if ((colon = strchr(dgpsserver, ':')) != NULL) { + dgpsport = colon + 1; + *colon = '\0'; + } + if (!getservbyname(dgpsport, "tcp")) + dgpsport = DEFAULT_RTCM_PORT; + + context->dsock = + netlib_connectsock(AF_UNSPEC, dgpsserver, dgpsport, "tcp"); + if (context->dsock >= 0) { + gpsd_report(LOG_PROG, "connection to DGPS server %s established.\n", + dgpsserver); + (void)gethostname(hn, sizeof(hn)); + /* greeting required by some RTCM104 servers; others will ignore it */ + (void)snprintf(buf, sizeof(buf), "HELO %s gpsd %s\r\nR\r\n", hn, + VERSION); + if (write(context->dsock, buf, strlen(buf)) == (ssize_t) strlen(buf)) + context->netgnss_service = netgnss_dgpsip; + else + gpsd_report(LOG_ERROR, "hello to DGPS server %s failed\n", + dgpsserver); + } else + gpsd_report(LOG_ERROR, + "can't connect to DGPS server %s, netlib error %d.\n", + dgpsserver, context->dsock); + opts = fcntl(context->dsock, F_GETFL); + + if (opts >= 0) + (void)fcntl(context->dsock, F_SETFL, opts | O_NONBLOCK); + return context->dsock; +} + +/*@ +branchstate */ + +void dgpsip_report(struct gps_device_t *session) +/* may be time to ship a usage report to the DGPSIP server */ +{ + /* + * 10 is an arbitrary number, the point is to have gotten several good + * fixes before reporting usage to our DGPSIP server. + */ + if (session->context->fixcnt > 10 && !session->context->sentdgps) { + session->context->sentdgps = true; + if (session->context->dsock > -1) { + char buf[BUFSIZ]; + (void)snprintf(buf, sizeof(buf), "R %0.8f %0.8f %0.2f\r\n", + session->gpsdata.fix.latitude, + session->gpsdata.fix.longitude, + session->gpsdata.fix.altitude); + if (write(session->context->dsock, buf, strlen(buf)) == + (ssize_t) strlen(buf)) + gpsd_report(LOG_IO, "=> dgps %s\n", buf); + else + gpsd_report(LOG_IO, "write to dgps FAILED\n"); + } + } +} + +#define DGPS_THRESHOLD 1600000 /* max. useful dist. from DGPS server (m) */ +#define SERVER_SAMPLE 12 /* # of servers within threshold to check */ + +struct dgps_server_t +{ + double lat, lon; + char server[257]; + double dist; +}; + +static int srvcmp(const void *s, const void *t) +{ + return (int)(((const struct dgps_server_t *)s)->dist - ((const struct dgps_server_t *)t)->dist); /* fixes: warning: cast discards qualifiers from pointer target type */ +} + +void dgpsip_autoconnect(struct gps_context_t *context, + double lat, double lon, const char *serverlist) +/* tell the library to talk to the nearest DGPSIP server */ +{ + struct dgps_server_t keep[SERVER_SAMPLE], hold, *sp, *tp; + char buf[BUFSIZ]; + FILE *sfp = fopen(serverlist, "r"); + + if (sfp == NULL) { + gpsd_report(LOG_ERROR, "no DGPS server list found.\n"); + context->dsock = -2; /* don't try this again */ + return; + } + + for (sp = keep; sp < keep + SERVER_SAMPLE; sp++) { + sp->dist = DGPS_THRESHOLD; + sp->server[0] = '\0'; + } + /*@ -usedef @*/ + while (fgets(buf, (int)sizeof(buf), sfp)) { + char *cp = strchr(buf, '#'); + if (cp != NULL) + *cp = '\0'; + if (sscanf(buf, "%lf %lf %256s", &hold.lat, &hold.lon, hold.server) == + 3) { + hold.dist = earth_distance(lat, lon, hold.lat, hold.lon); + tp = NULL; + /* + * The idea here is to look for a server in the sample array + * that is (a) closer than the one we're checking, and (b) + * furtherest away of all those that are closer. Replace it. + * In this way we end up with the closest possible set. + */ + for (sp = keep; sp < keep + SERVER_SAMPLE; sp++) + if (hold.dist < sp->dist + && (tp == NULL || hold.dist > tp->dist)) + tp = sp; + if (tp != NULL) + memcpy(tp, &hold, sizeof(struct dgps_server_t)); + } + } + (void)fclose(sfp); + + if (keep[0].server[0] == '\0') { + gpsd_report(LOG_ERROR, "no DGPS servers within %dm.\n", + (int)(DGPS_THRESHOLD / 1000)); + context->dsock = -2; /* don't try this again */ + return; + } + /*@ +usedef @*/ + + /* sort them and try the closest first */ + qsort((void *)keep, SERVER_SAMPLE, sizeof(struct dgps_server_t), srvcmp); + for (sp = keep; sp < keep + SERVER_SAMPLE; sp++) { + if (sp->server[0] != '\0') { + gpsd_report(LOG_INF, "%s is %dkm away.\n", sp->server, + (int)(sp->dist / 1000)); + if (dgpsip_open(context, sp->server) >= 0) + break; + } + } +} diff --git a/net_gnss_dispatch.c b/net_gnss_dispatch.c new file mode 100644 index 0000000..064247e --- /dev/null +++ b/net_gnss_dispatch.c @@ -0,0 +1,120 @@ +/* net_gnss_dispatch.c -- common interface to a number of Network GNSS services + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#include +#include "gpsd_config.h" +#include +#ifndef S_SPLINT_S +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#include +#endif /* S_SPLINT_S */ +#include +#include + +#include "gpsd.h" + +#define NETGNSS_DGPSIP "dgpsip://" +#define NETGNSS_NTRIP "ntrip://" + +/* Where to find the list of DGPSIP correction servers, if there is one */ +#define DGPSIP_SERVER_LIST "/usr/share/gpsd/dgpsip-servers" + +bool netgnss_uri_check(char *name) +/* is given string a valid URI for GNSS/DGPS service? */ +{ + return + strncmp(name, NETGNSS_NTRIP, strlen(NETGNSS_NTRIP)) == 0 + || strncmp(name, NETGNSS_DGPSIP, strlen(NETGNSS_DGPSIP)) == 0; +} + + +/*@ -branchstate */ +int netgnss_uri_open(struct gps_context_t *context, char *netgnss_service) +/* open a connection to a DGNSS service */ +{ +#ifdef NTRIP_ENABLE + if (strncmp(netgnss_service, NETGNSS_NTRIP, strlen(NETGNSS_NTRIP)) == 0) + return ntrip_open(context, netgnss_service + strlen(NETGNSS_NTRIP)); +#endif + + if (strncmp(netgnss_service, NETGNSS_DGPSIP, strlen(NETGNSS_DGPSIP)) == 0) + return dgpsip_open(context, netgnss_service + strlen(NETGNSS_DGPSIP)); + +#ifndef REQUIRE_DGNSS_PROTO + return dgpsip_open(context, netgnss_service); +#else + gpsd_report(LOG_ERROR, + "Unknown or unspecified DGNSS protocol for service %s\n", + netgnss_service); + return -1; +#endif +} + +/*@ +branchstate */ + +int netgnss_poll(struct gps_context_t *context) +/* poll the DGNSS service for a correction report */ +{ + if (context->dsock > -1) { + ssize_t rtcmbytes = + read(context->dsock, context->rtcmbuf, sizeof(context->rtcmbuf)); + if ((rtcmbytes == -1 && errno != EAGAIN) || (rtcmbytes == 0)) { + (void)shutdown(context->dsock, SHUT_RDWR); + (void)close(context->dsock); + context->rtcmbytes = 0; + return -1; + } else { + context->rtcmbytes = (size_t) rtcmbytes; + context->rtcmtime = timestamp(); + } + } + return 0; +} + +void netgnss_report(struct gps_device_t *session) +/* may be time to ship a usage report to the DGNSS service */ +{ + if (session->context->netgnss_service == netgnss_dgpsip) + dgpsip_report(session); +#ifdef NTRIP_ENABLE + else if (session->context->netgnss_service == netgnss_ntrip) + ntrip_report(session); +#endif +} + +void netgnss_autoconnect(struct gps_context_t *context, double lat, + double lon) +{ + if (context->netgnss_service == netgnss_dgpsip) { + dgpsip_autoconnect(context, lat, lon, DGPSIP_SERVER_LIST); + } +} + +/* *INDENT-OFF* */ +void rtcm_relay(struct gps_device_t *session) +/* pass a DGNSS connection report to a session */ +{ + if (session->gpsdata.gps_fd != -1 + && session->context->rtcmbytes > 0 + && session->rtcmtime < session->context->rtcmtime + && session->device_type->rtcm_writer != NULL) { + if (session->device_type->rtcm_writer(session, + session->context->rtcmbuf, + session->context->rtcmbytes) == + 0) + gpsd_report(LOG_ERROR, "Write to RTCM sink failed\n"); + else { + session->rtcmtime = timestamp(); + gpsd_report(LOG_IO, "<= DGPS: %zd bytes of RTCM relayed.\n", + session->context->rtcmbytes); + } + } +} +/* *INDENT-ON* */ + +/* end */ diff --git a/net_ntrip.c b/net_ntrip.c new file mode 100644 index 0000000..37ba1ac --- /dev/null +++ b/net_ntrip.c @@ -0,0 +1,519 @@ +/* net_ntrip.c -- gather and dispatch DGNSS data from Ntrip broadcasters + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include "gpsd_config.h" +#include +#ifndef S_SPLINT_S +#ifdef HAVE_SYS_SOCKET_H +#include +#else +#define AF_UNSPEC 0 +#endif /* HAVE_SYS_SOCKET_H */ +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#ifndef S_SPLINT_S +#ifdef HAVE_NETDB_H +#include +#endif +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd.h" +#include "bsd-base64.h" + +struct ntrip_stream_t +{ + char mountpoint[101]; + enum + { + fmt_rtcm2, + fmt_rtcm2_0, + fmt_rtcm2_1, + fmt_rtcm2_2, + fmt_rtcm2_3, + fmt_rtcm3, + fmt_unknown + } format; + int carrier; + double latitude; + double longitude; + int nmea; + enum + { cmp_enc_none, cmp_enc_unknown } compr_encryp; + enum + { auth_none, auth_basic, auth_digest, auth_unknown } authentication; + int fee; + int bitrate; +}; + +#define NTRIP_SOURCETABLE "SOURCETABLE 200 OK\r\n" +#define NTRIP_ENDSOURCETABLE "ENDSOURCETABLE" +#define NTRIP_CAS "CAS;" +#define NTRIP_NET "NET;" +#define NTRIP_STR "STR;" +#define NTRIP_BR "\r\n" +#define NTRIP_QSC "\";\"" +#define NTRIP_ICY "ICY 200 OK" +#define NTRIP_UNAUTH "401 Unauthorized" + +static struct ntrip_stream_t ntrip_stream; + +/*@ -temptrans -mustfreefresh @*/ +static /*@null@*/ char *ntrip_field_iterate( /*@null@ */ char *start, + /*@null@*/ char *prev, + const char *eol) +{ + char *s, *t, *u; + + if (start) + s = start; + else { + if (!prev) + return NULL; + s = prev + strlen(prev) + 1; + if (s >= eol) + return NULL; + } + + /* ignore any quoted ; chars as they are part of the field content */ + t = s; + while ((u = strstr(t, NTRIP_QSC))) + t = u + strlen(NTRIP_QSC); + + if ((t = strstr(t, ";"))) + *t = '\0'; + + gpsd_report(LOG_RAW, "Next Ntrip source table field %s\n", s); + + return s; +} + +/*@ +temptrans +mustfreefresh @*/ + +/*@ -mustfreefresh @*/ +static void ntrip_str_parse(char *str, size_t len, + /*@out@*/ struct ntrip_stream_t *hold) +{ + char *s, *eol = str + len; + + memset(hold, 0, sizeof(*hold)); + + /* */ + if ((s = ntrip_field_iterate(str, NULL, eol))) + strncpy(hold->mountpoint, s, sizeof(hold->mountpoint) - 1); + /* */ + s = ntrip_field_iterate(NULL, s, eol); + /* */ + if ((s = ntrip_field_iterate(NULL, s, eol))) { + if (strcasecmp("RTCM 2", s) == 0) + hold->format = fmt_rtcm2; + else if (strcasecmp("RTCM 2.0", s) == 0) + hold->format = fmt_rtcm2_0; + else if (strcasecmp("RTCM 2.1", s) == 0) + hold->format = fmt_rtcm2_1; + else if (strcasecmp("RTCM 2.2", s) == 0) + hold->format = fmt_rtcm2_2; + else if (strcasecmp("RTCM 2.3", s) == 0) + hold->format = fmt_rtcm2_3; + else if (strcasecmp("RTCM 3.0", s) == 0) + hold->format = fmt_rtcm3; + else + hold->format = fmt_unknown; + } + /* */ + s = ntrip_field_iterate(NULL, s, eol); + /* */ + if ((s = ntrip_field_iterate(NULL, s, eol))) + (void)sscanf(s, "%d", &hold->carrier); + /* */ + s = ntrip_field_iterate(NULL, s, eol); + /* */ + s = ntrip_field_iterate(NULL, s, eol); + /* */ + s = ntrip_field_iterate(NULL, s, eol); + /* */ + hold->latitude = NAN; + if ((s = ntrip_field_iterate(NULL, s, eol))) + (void)sscanf(s, "%lf", &hold->latitude); + /* */ + hold->longitude = NAN; + if ((s = ntrip_field_iterate(NULL, s, eol))) + (void)sscanf(s, "%lf", &hold->longitude); + /* */ + if ((s = ntrip_field_iterate(NULL, s, eol))) { + (void)sscanf(s, "%d", &hold->nmea); + } + /* */ + s = ntrip_field_iterate(NULL, s, eol); + /* */ + s = ntrip_field_iterate(NULL, s, eol); + /* */ + if ((s = ntrip_field_iterate(NULL, s, eol))) { + if (strcasecmp("none", s) == 0) + hold->compr_encryp = cmp_enc_none; + else + hold->compr_encryp = cmp_enc_unknown; + } + /* */ + if ((s = ntrip_field_iterate(NULL, s, eol))) { + if (strcasecmp("N", s) == 0) + hold->authentication = auth_none; + else if (strcasecmp("B", s) == 0) + hold->authentication = auth_basic; + else if (strcasecmp("D", s) == 0) + hold->authentication = auth_digest; + else + hold->authentication = auth_unknown; + } + /* */ + if ((s = ntrip_field_iterate(NULL, s, eol))) { + (void)sscanf(s, "%d", &hold->fee); + } + /* */ + if ((s = ntrip_field_iterate(NULL, s, eol))) { + (void)sscanf(s, "%d", &hold->bitrate); + } + /* ... */ + while ((s = ntrip_field_iterate(NULL, s, eol))); +} + +/*@ +mustfreefresh @*/ + +static int ntrip_sourcetable_parse(int fd, char *buf, ssize_t blen, + const char *stream, + struct ntrip_stream_t *keep) +{ + struct ntrip_stream_t hold; + ssize_t llen, len = 0; + char *line; + bool srctbl = false; + bool match = false; + + for (;;) { + char *eol; + ssize_t rlen; + + memset(&buf[len], 0, (size_t) (blen - len)); + + if ((rlen = recv(fd, &buf[len], (size_t) (blen - 1 - len), 0)) == -1) { + if (errno == EINTR) + continue; + return -1; + } + if (rlen == 0) + continue; + + line = buf; + rlen = len += rlen; + + gpsd_report(LOG_RAW, "Ntrip source table buffer %s\n", buf); + + if (!srctbl) { + /* parse SOURCETABLE */ + if (strncmp(line, NTRIP_SOURCETABLE, strlen(NTRIP_SOURCETABLE)) == + 0) { + srctbl = true; + llen = (ssize_t) strlen(NTRIP_SOURCETABLE); + line += llen; + len -= llen; + } else { + gpsd_report(LOG_WARN, "Received unexpexted Ntrip reply %s.\n", + buf); + return -1; + } + } + if (!srctbl) + return -1; + + while (len > 0) { + /* parse ENDSOURCETABLE */ + if (strncmp + (line, NTRIP_ENDSOURCETABLE, + strlen(NTRIP_ENDSOURCETABLE)) == 0) + goto done; + + if (!(eol = strstr(line, NTRIP_BR))) + break; + + gpsd_report(LOG_IO, "next Ntrip source table line %s\n", line); + + *eol = '\0'; + llen = (ssize_t) (eol - line); + + /* todo: parse headers */ + + /* parse STR */ + if (strncmp(line, NTRIP_STR, strlen(NTRIP_STR)) == 0) { + ntrip_str_parse(line + strlen(NTRIP_STR), + (size_t) (llen - strlen(NTRIP_STR)), &hold); + if (stream != NULL && strcmp(stream, hold.mountpoint) == 0) { + /* todo: support for RTCM 3.0, SBAS (WAAS, EGNOS), ... */ + if (hold.format == fmt_unknown) { + gpsd_report(LOG_ERROR, + "Ntrip stream %s format not supported\n", + line); + return -1; + } + /* todo: support encryption and compression algorithms */ + if (hold.compr_encryp != cmp_enc_none) { + gpsd_report(LOG_ERROR, + "Ntrip stream %s compression/encryption algorithm not supported\n", + line); + return -1; + } + /* todo: support digest authentication */ + if (hold.authentication != auth_none + && hold.authentication != auth_basic) { + gpsd_report(LOG_ERROR, + "Ntrip stream %s authentication method not supported\n", + line); + return -1; + } + memcpy(keep, &hold, sizeof(hold)); + match = true; + } + /* todo: compare stream location to own location to + * find nearest stream if user hasn't provided one */ + } + /* todo: parse CAS */ + /* else if (strncmp(line, NTRIP_CAS, strlen(NTRIP_CAS))==0); */ + + /* todo: parse NET */ + /* else if (strncmp(line, NTRIP_NET, strlen(NTRIP_NET))==0); */ + + llen += strlen(NTRIP_BR); + line += llen; + len -= llen; + gpsd_report(LOG_RAW, + "Remaining Ntrip source table buffer %zd %s\n", len, + line); + } + /* message too big to fit into buffer */ + if (len == blen - 1) + return -1; + + if (len > 0) + memcpy(buf, &buf[rlen - len], (size_t) len); + } + + done: + return match ? 0 : -1; +} + +static int ntrip_stream_probe(const char *caster, + const char *port, + const char *stream, struct ntrip_stream_t *keep) +{ + int ret; + socket_t dsock; + char buf[BUFSIZ]; + + if ((dsock = netlib_connectsock(AF_UNSPEC, caster, port, "tcp")) == -1) { + printf("ntrip stream connect error %d\n", dsock); + return -1; + } + (void)snprintf(buf, sizeof(buf), + "GET / HTTP/1.1\r\n" + "User-Agent: NTRIP gpsd/%s\r\n" + "Connection: close\r\n" "\r\n", VERSION); + if (write(dsock, buf, strlen(buf)) != (ssize_t) strlen(buf)) { + printf("ntrip stream write error %d\n", dsock); + return -1; + } + ret = + ntrip_sourcetable_parse(dsock, buf, (ssize_t) sizeof(buf), stream, + keep); + (void)close(dsock); + return ret; +} + +static int ntrip_auth_encode(const struct ntrip_stream_t *stream, + const char *auth, + /*@out@*/ char buf[], + size_t size) +{ + memset(buf, 0, size); + if (stream->authentication == auth_none) + return 0; + else if (stream->authentication == auth_basic) { + char authenc[64]; + if (!auth) + return -1; + memset(authenc, 0, sizeof(authenc)); + if (b64_ntop + ((unsigned char *)auth, strlen(auth), authenc, + sizeof(authenc) - 1) < 0) + return -1; + (void)snprintf(buf, size - 1, "Authorization: Basic %s\r\n", authenc); + } else { + /* todo: support digest authentication */ + } + return 0; +} + +/* *INDENT-OFF* */ +/*@ -nullpass @*//* work around a splint bug */ +static int ntrip_stream_open(const char *caster, const char *port, + /*@null@*/ const char *auth, + struct gps_context_t *context, + struct ntrip_stream_t *stream) +{ + char buf[BUFSIZ]; + char authstr[128]; + int opts; + + if (ntrip_auth_encode(stream, auth, authstr, sizeof(authstr)) < 0) { + gpsd_report(LOG_ERROR, "User-ID and password needed for %s:%s/%s\n", + caster, port, stream->mountpoint); + return -1; + } + if ((context->dsock = + netlib_connectsock(AF_UNSPEC, caster, port, "tcp")) < 0) + return -1; + + (void)snprintf(buf, sizeof(buf), + "GET /%s HTTP/1.1\r\n" + "User-Agent: NTRIP gpsd/%s\r\n" + "Accept: rtk/rtcm, dgps/rtcm\r\n" + "%s" + "Connection: close\r\n" + "\r\n", stream->mountpoint, VERSION, authstr); + if (write(context->dsock, buf, strlen(buf)) != (ssize_t) strlen(buf)) { + printf("ntrip stream write error on %d\n", context->dsock); + return -1; + } + + memset(buf, 0, sizeof(buf)); + if (read(context->dsock, buf, sizeof(buf) - 1) == -1) + goto close; + + /* parse 401 Unauthorized */ + if (strstr(buf, NTRIP_UNAUTH)) { + gpsd_report(LOG_ERROR, + "%s not authorized for Ntrip stream %s:%s/%s\n", auth, + caster, port, stream->mountpoint); + goto close; + } + /* parse SOURCETABLE */ + if (strstr(buf, NTRIP_SOURCETABLE)) { + gpsd_report(LOG_ERROR, + "Broadcaster doesn't recognize Ntrip stream %s:%s/%s\n", + caster, port, stream->mountpoint); + goto close; + } + /* parse ICY 200 OK */ + if (!strstr(buf, NTRIP_ICY)) { + gpsd_report(LOG_ERROR, + "Unknown reply %s from Ntrip service %s:%s/%s\n", buf, + caster, port, stream->mountpoint); + goto close; + } + opts = fcntl(context->dsock, F_GETFL); + + if (opts >= 0) + (void)fcntl(context->dsock, F_SETFL, opts | O_NONBLOCK); + + context->netgnss_service = netgnss_ntrip; +#ifndef S_SPLINT_S + context->netgnss_privdata = stream; +#endif + return context->dsock; + close: + (void)close(context->dsock); + return -1; +} +/* *INDENT-ON* */ + +/*@ +nullpass @*/ + +/*@ -branchstate @*/ +int ntrip_open(struct gps_context_t *context, char *caster) +/* open a connection to a Ntrip broadcaster */ +{ + char *amp, *colon, *slash; + char *auth = NULL; + char *port = NULL; + char *stream = NULL; + int ret; + + /*@ -boolops @*/ + if ((amp = strchr(caster, '@')) != NULL) { + if (((colon = strchr(caster, ':')) != NULL) && colon < amp) { + auth = caster; + *amp = '\0'; + caster = amp + 1; + } else { + gpsd_report(LOG_ERROR, + "can't extract user-ID and password from %s\n", + caster); + return -1; + } + } + /*@ +boolops @*/ + if ((slash = strchr(caster, '/')) != NULL) { + *slash = '\0'; + stream = slash + 1; + } else { + /* todo: add autoconnect like in dgpsip.c */ + gpsd_report(LOG_ERROR, "can't extract Ntrip stream from %s\n", + caster); + return -1; + } + if ((colon = strchr(caster, ':')) != NULL) { + port = colon + 1; + *colon = '\0'; + } + if (!port) { + port = "rtcm-sc104"; + if (!getservbyname(port, "tcp")) + port = DEFAULT_RTCM_PORT; + } + if (ntrip_stream_probe(caster, port, stream, &ntrip_stream)) { + gpsd_report(LOG_ERROR, + "unable to probe for data about stream %s:%s/%s\n", + caster, port, stream); + return -1; + } + ret = ntrip_stream_open(caster, port, auth, context, &ntrip_stream); + if (ret >= 0) + gpsd_report(LOG_PROG, + "connection to Ntrip broadcaster %s established.\n", + caster); + else + gpsd_report(LOG_ERROR, "can't connect to Ntrip stream %s:%s/%s.\n", + caster, port, stream); + return ret; +} + +/*@ +branchstate @*/ + +void ntrip_report(struct gps_device_t *session) +/* may be time to ship a usage report to the Ntrip caster */ +{ + struct ntrip_stream_t *stream = session->context->netgnss_privdata; + /* + * 10 is an arbitrary number, the point is to have gotten several good + * fixes before reporting usage to our Ntrip caster. + */ + if (stream != NULL && stream->nmea != 0 + && session->context->fixcnt > 10 && !session->context->sentdgps) { + session->context->sentdgps = true; + if (session->context->dsock > -1) { + char buf[BUFSIZ]; + gpsd_position_fix_dump(session, buf, sizeof(buf)); + if (write(session->context->dsock, buf, strlen(buf)) == + (ssize_t) strlen(buf)) + gpsd_report(LOG_IO, "=> dgps %s\n", buf); + else + gpsd_report(LOG_IO, "ntrip report write failed\n"); + } + } +} diff --git a/netlib.c b/netlib.c new file mode 100644 index 0000000..9726f36 --- /dev/null +++ b/netlib.c @@ -0,0 +1,204 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include + +#include "gpsd_config.h" + +#ifndef S_SPLINT_S +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETINET_IN_SYSTM_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#endif /* S_SPLINT_S */ +#ifndef S_SPLINT_S +#ifdef HAVE_NETDB_H +#include +#endif /* HAVE_NETDB_H */ +#ifdef HAVE_ARPA_INET_H +#include +#endif /* HAVE_ARPA_INET_H */ +#endif /* S_SPLINT_S */ +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include + +#include "gpsd.h" +#include "sockaddr.h" + +#if !defined (INADDR_NONE) +#define INADDR_NONE ((in_addr_t)-1) +#endif + +/*@-mustfreefresh -usedef@*/ +socket_t netlib_connectsock(int af, const char *host, const char *service, + const char *protocol) +{ + struct protoent *ppe; + struct addrinfo hints; + struct addrinfo *result, *rp; + int ret, type, proto, one = 1; + socket_t s = -1; + bool bind_me; + + /*@-type@*/ + ppe = getprotobyname(protocol); + if (strcmp(protocol, "udp") == 0) { + type = SOCK_DGRAM; + proto = (ppe) ? ppe->p_proto : IPPROTO_UDP; + } else { + type = SOCK_STREAM; + proto = (ppe) ? ppe->p_proto : IPPROTO_TCP; + } + /*@+type@*/ + + /* we probably ought to pass this in as an explicit flag argument */ + bind_me = (type == SOCK_DGRAM); + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af; + hints.ai_socktype = type; + hints.ai_protocol = proto; +#ifndef S_SPLINT_S + if (bind_me) + hints.ai_flags = AI_PASSIVE; + if ((ret = getaddrinfo(host, service, &hints, &result))) { + return NL_NOHOST; + } +#endif /* S_SPLINT_S */ + + /* + * From getaddrinfo(3): + * Normally, the application should try using the addresses in the + * order in which they are returned. The sorting function used within + * getaddrinfo() is defined in RFC 3484). + * From RFC 3484 (Section 10.3): + * The default policy table gives IPv6 addresses higher precedence than + * IPv4 addresses. + * Thus, with the default parameters, we get IPv6 addresses first. + */ + /*@-type@*/ + for (rp = result; rp != NULL; rp = rp->ai_next) { + ret = NL_NOCONNECT; + if ((s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0) + ret = NL_NOSOCK; + else if (setsockopt + (s, SOL_SOCKET, SO_REUSEADDR, (char *)&one, + sizeof(one)) == -1) { + (void)close(s); + ret = NL_NOSOCKOPT; + } else { + if (bind_me) { + if (bind(s, rp->ai_addr, rp->ai_addrlen) == 0) { + ret = 0; + break; + } + } else { + if (connect(s, rp->ai_addr, rp->ai_addrlen) == 0) { + ret = 0; + break; + } + } + } + + if (s > 0) { + gpsd_report(LOG_SPIN, "close(%d) in netlib_connectsock()\n", s); + (void)close(s); + } + } + /*@+type@*/ +#ifndef S_SPLINT_S + freeaddrinfo(result); +#endif /* S_SPLINT_S */ + if (ret) + return ret; + +#ifdef IPTOS_LOWDELAY + { + int opt = IPTOS_LOWDELAY; + /*@ -unrecog @*/ + (void)setsockopt(s, IPPROTO_IP, IP_TOS, &opt, sizeof opt); + /*@ +unrecog @*/ + } +#endif +#ifdef TCP_NODELAY + if (type == SOCK_STREAM) + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof one); +#endif + + gpsd_report(LOG_SPIN, "netlib_connectsock() returns socket on fd %d\n", + s); + return s; + /*@ +type +mustfreefresh @*/ +} + +/*@+mustfreefresh +usedef@*/ + +char /*@observer@*/ *netlib_errstr(const int err) +{ + switch (err) { + case NL_NOSERVICE: + return "can't get service entry"; + case NL_NOHOST: + return "can't get host entry"; + case NL_NOPROTO: + return "can't get protocol entry"; + case NL_NOSOCK: + return "can't create socket"; + case NL_NOSOCKOPT: + return "error SETSOCKOPT SO_REUSEADDR"; + case NL_NOCONNECT: + return "can't connect to host/port pair"; + default: + return "unknown error"; + } +} + +char *netlib_sock2ip(int fd) +{ + sockaddr_t fsin; + socklen_t alen = (socklen_t) sizeof(fsin); + /*@i1@*/ static char ip[INET6_ADDRSTRLEN]; + int r; + + r = getpeername(fd, &(fsin.sa), &alen); + /*@ -branchstate -unrecog @*/ + if (r == 0) { + switch (fsin.sa.sa_family) { + case AF_INET: + r = !inet_ntop(fsin.sa_in.sin_family, &(fsin.sa_in.sin_addr), + ip, sizeof(ip)); + break; +#ifdef IPV6_ENABLE + case AF_INET6: + r = !inet_ntop(fsin.sa_in6.sin6_family, &(fsin.sa_in6.sin6_addr), + ip, sizeof(ip)); + break; +#endif + default: + gpsd_report(LOG_ERROR, "Unhandled address family %d in %s\n", + fsin.sa.sa_family, __FUNCTION__); + (void)strlcpy(ip, "", sizeof(ip)); + return ip; + } + } + if (r != 0) { + gpsd_report(LOG_INF, "getpeername() = %d, error = %s (%d)\n", r, + strerror(errno), errno); + (void)strlcpy(ip, "", sizeof(ip)); + } + /*@ +branchstate +unrecog @*/ + return ip; +} diff --git a/ntpshm.c b/ntpshm.c new file mode 100644 index 0000000..85e4cd4 --- /dev/null +++ b/ntpshm.c @@ -0,0 +1,343 @@ +/* + * ntpshm.c - put time information in SHM segment for xntpd + * struct shmTime and getShmTime from file in the xntp distribution: + * sht.c - Testprogram for shared memory refclock + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#include +#include "gpsd_config.h" +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include + +#include "gpsd.h" +#ifdef NTPSHM_ENABLE + +#if defined(HAVE_SYS_TIME_H) +#include +#endif + +#ifdef HAVE_SYS_IPC_H +#include +#endif /* HAVE_SYS_IPC_H */ +#ifdef HAVE_SYS_SHM_H +#include +#endif /* HAVE_SYS_SHM_H */ + +#define PPS_MAX_OFFSET 100000 /* microseconds the PPS can 'pull' */ +#define PUT_MAX_OFFSET 1000000 /* microseconds for lost lock */ + +#define NTPD_BASE 0x4e545030 /* "NTP0" */ +#define SHM_UNIT 0 /* SHM driver unit number (0..3) */ + +struct shmTime +{ + int mode; /* 0 - if valid set + * use values, + * clear valid + * 1 - if valid set + * if count before and after read of values is equal, + * use values + * clear valid + */ + int count; + time_t clockTimeStampSec; + int clockTimeStampUSec; + time_t receiveTimeStampSec; + int receiveTimeStampUSec; + int leap; + int precision; + int nsamples; + int valid; + int pad[10]; +}; + +/* Note: you can start gpsd as non-root, and have it work with ntpd. + * However, it will then only use the ntpshm segments 2 and 3. + * + * Ntpd always runs as root (to be able to control the system clock). + * Its logics for the creation of ntpshm segments are: + * + * Segments 0 and 1: permissions 0600, i.e. other programs can only + * read and write as root. + * + * Segments 2 and 3: permissions 0666, i.e. other programs can read + * and write as any user. I.e.: if ntpd has been + * configured to use these segments, any + * unpriviliged user is allowed to provide data + * for synchronisation. + * + * As gpsd can be started as both root and non-root, this behaviour is + * mimiced by: + * + * Started as root: do as ntpd when attaching (creating) the segments. + * (In contrast to ntpd, which only attaches (creates) configured + * segments, gpsd creates all segments.) + * + * Started as non-root: only attach (create) segments 2 and 3 with + * permissions 0666. As the permissions are for any user, the creator + * does not matter. + * + * For each GPS module gpsd controls, it will use the attached ntpshm + * segments in pairs (for coarse clock and pps source, respectively) + * starting from the first found segments. I.e. started as root, one + * GPS will deliver data on segments 0 and 1, and as non-root data + * will be delivered on segments 2 and 3. + * + * to debug, try looking at the live segments this way + * ipcs -m + * results should look like this: + * ------ Shared Memory Segments -------- + * key shmid owner perms bytes nattch status + * 0x4e545030 0 root 700 96 2 + * 0x4e545031 32769 root 700 96 2 + * 0x4e545032 163842 root 666 96 1 + * 0x4e545033 196611 root 666 96 1 + * + * For a bit more data try this: + * cat /proc/sysvipc/shm + * + * If gpsd can not open the segments be sure you are not running SELinux + * or apparmor. + * + * if you see the shared segments (keys 1314148400 -- 1314148403), and + * no gpsd or ntpd is running then try removing them like this: + * + * ipcrm -M 0x4e545030 + * ipcrm -M 0x4e545031 + * ipcrm -M 0x4e545032 + * ipcrm -M 0x4e545033 + */ +static /*@null@*/ struct shmTime *getShmTime(int unit) +{ + int shmid; + unsigned int perms; + // set the SHM perms the way ntpd does + if (unit < 2) { + // we are root, be careful + perms = 0600; + } else { + // we are not root, try to work anyway + perms = 0666; + } + + shmid = shmget((key_t) (NTPD_BASE + unit), + sizeof(struct shmTime), (int)(IPC_CREAT | perms)); + if (shmid == -1) { + gpsd_report(LOG_ERROR, "NTPD shmget(%ld, %zd, %o) fail: %s\n", + (long int)(NTPD_BASE + unit), sizeof(struct shmTime), + (int)perms, strerror(errno)); + return NULL; + } else { + struct shmTime *p = (struct shmTime *)shmat(shmid, 0, 0); + /*@ -mustfreefresh */ + if ((int)(long)p == -1) { + gpsd_report(LOG_ERROR, "NTPD shmat failed: %s\n", + strerror(errno)); + return NULL; + } + gpsd_report(LOG_PROG, "NTPD shmat(%d,0,0) succeeded, segment %d\n", + shmid, unit); + return p; + /*@ +mustfreefresh */ + } +} + +void ntpshm_init(struct gps_context_t *context, bool enablepps) +/* attach all NTP SHM segments. + * called once at startup, while still root, although root not required */ +{ + int i; + + for (i = 0; i < NTPSHMSEGS; i++) { + // Only grab the first two when running as root. + if (2 <= i || 0 == getuid()) { + context->shmTime[i] = getShmTime(i); + } + } + memset(context->shmTimeInuse, 0, sizeof(context->shmTimeInuse)); +# ifdef PPS_ENABLE + context->shmTimePPS = enablepps; +# endif /* PPS_ENABLE */ + context->enable_ntpshm = true; +} + +int ntpshm_alloc(struct gps_context_t *context) +/* allocate NTP SHM segment. return its segment number, or -1 */ +{ + int i; + + for (i = 0; i < NTPSHMSEGS; i++) + if (context->shmTime[i] != NULL && !context->shmTimeInuse[i]) { + context->shmTimeInuse[i] = true; + + memset((void *)context->shmTime[i], 0, sizeof(struct shmTime)); + context->shmTime[i]->mode = 1; + context->shmTime[i]->precision = -1; /* initially 0.5 sec */ + context->shmTime[i]->nsamples = 3; /* stages of median filter */ + + return i; + } + + return -1; +} + +bool ntpshm_free(struct gps_context_t * context, int segment) +/* free NTP SHM segment */ +{ + if (segment < 0 || segment >= NTPSHMSEGS) + return false; + + context->shmTimeInuse[segment] = false; + return true; +} + + +int ntpshm_put(struct gps_device_t *session, double fixtime, double fudge) +/* put a received fix time into shared memory for NTP */ +{ + struct shmTime *shmTime = NULL; + struct timeval tv; + double seconds, microseconds; + + // gpsd_report(LOG_PROG, "NTP: doing ntpshm_put(,%g, %g)\n", fixtime, fudge); + if (session->shmindex < 0 || + (shmTime = session->context->shmTime[session->shmindex]) == NULL) { + gpsd_report(LOG_RAW, "NTPD missing shm\n"); + return 0; + } + + (void)gettimeofday(&tv, NULL); + fixtime += fudge; + microseconds = 1000000.0 * modf(fixtime, &seconds); + if (shmTime->clockTimeStampSec == (time_t) seconds) { + gpsd_report(LOG_RAW, "NTPD ntpshm_put: skipping duplicate second\n"); + return 0; + } + + /* we use the shmTime mode 1 protocol + * + * ntpd does this: + * + * reads valid. + * IFF valid is 1 + * reads count + * reads values + * reads count + * IFF count unchanged + * use values + * clear valid + * + */ + shmTime->valid = 0; + shmTime->count++; + shmTime->clockTimeStampSec = (time_t) seconds; + shmTime->clockTimeStampUSec = (int)microseconds; + shmTime->receiveTimeStampSec = (time_t) tv.tv_sec; + shmTime->receiveTimeStampUSec = (int)tv.tv_usec; + /* setting the precision here does not seem to help anything, too + * hard to calculate properly anyway. Let ntpd figure it out. + * Any NMEA will be about -1 or -2. + * Garmin GPS-18/USB is around -6 or -7. + */ + shmTime->count++; + shmTime->valid = 1; + + gpsd_report(LOG_RAW, + "NTPD ntpshm_put: Clock: %lu.%06lu @ %lu.%06lu, fudge: %0.3f\n", + (unsigned long)seconds, (unsigned long)microseconds, + (unsigned long)tv.tv_sec, (unsigned long)tv.tv_usec, fudge); + + return 1; +} + +#ifdef PPS_ENABLE +/* put NTP shared memory info based on received PPS pulse */ + +int ntpshm_pps(struct gps_device_t *session, struct timeval *tv) +{ + struct shmTime *shmTime = NULL, *shmTimeP = NULL; + time_t seconds; + /* FIX-ME, microseconds needs to be set for 5Hz PPS */ + int microseconds = 0; + int precision; + double offset; + long l_offset; + + if (0 > session->shmindex || 0 > session->shmTimeP || + (shmTime = session->context->shmTime[session->shmindex]) == NULL || + (shmTimeP = session->context->shmTime[session->shmTimeP]) == NULL) + return 0; + + /* PPS has no seconds attached to it. + * check to see if we have a fresh timestamp from the + * GPS serial input then use that */ + + /* FIX-ME, does not handle 5Hz yet */ + +#ifdef S_SPLINT_S /* avoids an internal error in splint 3.1.1 */ + l_offset = 0; +#else + l_offset = tv->tv_sec - shmTime->receiveTimeStampSec; +#endif + /*@ -ignorequals @*/ + l_offset *= 1000000; + l_offset += tv->tv_usec - shmTime->receiveTimeStampUSec; + if (0 > l_offset || 1000000 < l_offset) { + gpsd_report(LOG_RAW, "PPS ntpshm_pps: no current GPS seconds: %ld\n", + (long)l_offset); + return -1; + } + + /*@+relaxtypes@*/ + seconds = shmTime->clockTimeStampSec + 1; + offset = fabs((tv->tv_sec - seconds) + + ((double)(tv->tv_usec - 0) / 1000000.0)); + /*@-relaxtypes@*/ + + + /* we use the shmTime mode 1 protocol + * + * ntpd does this: + * + * reads valid. + * IFF valid is 1 + * reads count + * reads values + * reads count + * IFF count unchanged + * use values + * clear valid + * + */ + shmTimeP->valid = 0; + shmTimeP->count++; + shmTimeP->clockTimeStampSec = seconds; + shmTimeP->clockTimeStampUSec = (int)microseconds; + shmTimeP->receiveTimeStampSec = (time_t) tv->tv_sec; + shmTimeP->receiveTimeStampUSec = (int)tv->tv_usec; + /* precision is a placebo, ntpd does not really use it + * real world accuracty is around 16uS, thus -16 precision */ + shmTimeP->precision = -16; + shmTimeP->count++; + shmTimeP->valid = 1; + + /* this is more an offset jitter/dispersion than precision, + * but still useful for debug */ + precision = offset != 0 ? (int)(ceil(log(offset) / M_LN2)) : -20; + gpsd_report(LOG_RAW, "PPS ntpshm_pps %lu.%03lu @ %lu.%06lu, preci %d\n", + (unsigned long)seconds, (unsigned long)microseconds / 1000, + (unsigned long)tv->tv_sec, (unsigned long)tv->tv_usec, + precision); + return 1; +} +#endif /* PPS_ENABLE */ +#endif /* NTPSHM_ENABLE */ diff --git a/packaging/X11/gpsd-logo.png b/packaging/X11/gpsd-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..83ca308013ba016901c96ec21dfb7bf4face5128 GIT binary patch literal 16518 zcmZvjb5thp`^TSb+qV5=Z?)OBZEog5Xx(V^O;<4Vj=EV*FrOLjsF-Qc$-|)=k^?AQ9fmttbdxR5*C%8f zr#IRk@^0TaVn4O)Nw;9l(K(X}C-Hb+@ISmxb>w(=Q2YBL{VDBnD0Kb@{iif#ex1Av z=EyPe59A%MtTTikQE@9M8u*n`EI9uK2So9AGH;eh!kIv6HwP-5oI$^mTf9l#1$_!M z<(~hBR@#b8hXE46IiKdPei#3wCe+Mjp0G?S!S=n35)Ru+>T^5t#{l?@1sZcW?&K(g zwXVJQr$FaU%rnwI`{QsfOrf7nHV^4U$@9uw=ny&C^p@2h5W#Qzp&DZZPg_yB@39Rr zi%f2?=n`#%2k>%Zzf{wFw-hP^=9~W7>hU(d3~O>pP7{P$;3x_!g7=8|e}E~-<0$H8 z-Oe&U&e#YPc9145o&OQLX@DZ!gBxGZq(UmR(oMZJ-BiC1Yb>u3EOxJ;Qxidlgu1Ud z@M<`|hu}h~v=ae8Ej-+We72D(0SXWLW zF~UP{P){uMO}wtqxIZI7#CKM73r^i`y9BHBYg7%m_}Fn;rji`rRQ~hO)zlt3cAU^V z3*_f@FMh9haZ(;OJLV|+=r{FV+*iLCyM4Q!QK~aTA^X1U5Iyf_ER!Bl`N?>=4&6lPl)|^?+T?Cpa;=c z5~^3F(^<7zvv6*j=M%5lk(~$W z=8~>cQJagir}XFscTteLf{Mw9pykHWG`VT)^;zQRB>E6w_BXDq%%U14_IGKP4Yu}kzVU}m3(fs;xoX#cNvYD)vD}k3 zNQQ>szum+`J7>)&4b)nBn&?sVa(eX{+Nt2HAa|9J4Ky%Q5$AEJjV#`rN3S;YFKK)2 z|IUL;>hg^&u#acqw$1WvM2ms|C3HU?${AbdP-DY&N<1;;cH-oU`c#iK$5HqFkF4kI zP}3rT2|0ES&OI0&h9cPHh=3+Hqv3ZyRN9I{4~>xPjL6DcH74;^*sCvtC`9sIZQm&KTVGehkf5#L?c^D54Kz}8+k=H_wDETi2o z?y^>ny&4C3UnYUMsRr6fvpRMd)t!=T8nj3YLV_>UE9d+TAEpllhG_JC*Kh2eP~iv2 z$*qL4{8OVW-8(l+gL>MXTx~x4FXsD;Oeo?SeQr@R8;~k0?4>{$__tc|7JnU5vveJj zo|;+V#6gfx>Boy=b)X_-_kjCzvBHE0UQ?W26NN?UCOZt{GgdMUyQM2joq~+lYU6SJ zE?+FUii>VNp_g`qmQgdcs%{T2sm-5^J1y3EYWhDDR^c;+_fofL*>VaUrI9Va5{Ui# zdA%N`88A=i^k})PDf2^p{e_&NDBRt}FX9Hp<9qhxYsOyN4C-|nEpck1*V1CC?$5QQ z-46{ob-oT@sQt`aH|gLbotkR z?HcZsS}xO)rNf6b1`Odalm>F9g+m>_Fi;nixJqN2&+C(< z=Md_SlwCg|DivJv2VXEdTjyZ)`=X*tv{P|<{;+yU`S^Rb`Xp#}v|7aPSJ0b_Aq%rP zAiautyyi20R2kco@w45&j{q^HEIgz3>hWT1lg)p4wc~{%OX;`RQE1mnL{zD-B$Z@& zKpK)J2dr~4Jm~;?G&SPJ*krkUZ&UV9+th4?elQ=uaoa<#dnU);+ID z4gb>jpe&cBk!N7mvlDPJIZYVz5_t%q;1%>OH48rM+o7|c5nM){}zC!(9;~KjOIxX z6j^Dz(+g9BA>IxRE_GD)?|L4Lx=>IX_07(KE-?HY{-rFcb+PkxWJ?e3OCFqc9G0IIXO_E)1iQrF649Iy|Lc&Q zE1s14;uJ2f59(XI+`}Fy&<||Z*y@^^yNeH%nwQ~pofS4sE}}^i?!~4 z6r1bbzSgdFy3rCebw7?gyp)FiA(dJ5bTz)Oj2W^zJo{Kp5m9K0X3r< z1nr698QK)?Wmw7X2e1sBonL2yyh3$wD zYR*R|I(D?T?R##auKD(S(2JE{)8gMAZ~sMM3J+PMqFZil^P6zPOH5ed+Ze}a_eO`0 zT+OJsrt~KZFI?EH`#&sh}_2Eq1u_~UvsQa z9)vzFHK#=%VY1@j_;IFIh$r>W@FO>#j`K3Vw8Sg5Vog9m{{;!)(!)*>z*D$@iB&XV zN=+r^Jx!JAmws&}^48w9qdpd()x$t)zQUILHQjyRtsP4BzFCu&A3q`7IQGaoT4g3i zg@dO^tl<^l;AddwGwUgfBPeThRc7Lp2g5b42^D2;y|L|_9LV?L!|%Y%3+T6=W;#C^ z`#s82SJ8llC9kzOOO?A(W;m=d^0MLFRM&E-$Ie~Ee;l2h{7%(2ik_NM z0-vFxPhHQ=EX=X}n|dF{*A!&PynGcgEX;8gjSHN$)8stH2Ad~Z5{TrZ^_igms+Gi* z{;xzJJD6*jH%wQDV`$a1b-Aa>&$QEVL$PLV4NICAUyN$`Soj#*+oFxE#rf_g&W4TJ zR@Q+I!@B19HC+@ebc;$XbBG(qI;A_Bz<)_twHT9@hHK!nW5sOv3%Y?hRBZS*tVq6F zFz=UoSz+oGOurO7K3v*SJ>ANRN`6lR=CKE1g$80)X`fT;z_}L{HnPOkMNuMJeF7)VU6w@$!Njm7 z*pao89)24)vL90d$-=!#v%z2ny8X7V6tkUYm6>Am2OGzN)3x9Gy)8b%mZ*fM3xEGU z@RcSmYq;bq-5V##W~&+aCI9D5Qhy$5+I4-B7Kix`yTP9x;uCTc%8=Tk44aWtLLw!- zdk@*mN~vu>J90)Tf);W#xZVc3@ z9T)JnTYKW?5;1H|k!{3{ax8IvO^h#UiSUQp4VB^RT3a?Mu6b25qgI8Ma7J(Z3Y*(B zu_^K-C5yQL)ZjT<>vhNB}}&SH)e zF14cs7rLq-s#MggJYJlJXsyV?{2a!z-TE;lctoI6n1fEgp};B+ONLKIa1h7w=r001 z18|4Pu&P>Guu+?l49@p3<{E~6l|{J*bguCZzM3*kg-*gZX07Ji1Q1#z~PqHgA#U@09`D#_T^- z2KQiCDQE=m2N!&oz=qMO!SxZU^=BQ+xfoSO5}Ps^iEhd9)HXIoiyDA1QS!z~OXrB> zm~>zyZNrr%79&`OW1@v6O|>LwV3tIOj!Q@wuxsw;CQwUSjca!vW`a2CI>W}*4J`O(Nd7Z*gL2mdr+-_#NJtk?ZG?i*^z8 zF&PLED(h<(IbGXX(;pKqf$P+v{+&@uM5W*N@;0`lR7apJr8PBiq*R4IwW@wr(bkUo zM#N_}U#fWZxB+!C@I!w?OrvjB+QVI7B|i2|fhe z9-SJ)a%WcC34yHBs|NSonSDqZrYz+U3}0BxFMKbyV!r^gb zNIG`pXapW)VqyXsPh*kfCLH|z8+xf)H%u}LRXo}9x8!^UO5t_#i0(h1FKxXjaU9%y ze5SVtlRtHseRd-7(2-#aDiJXeNMPo3(Bo@s_g6Z7v2v8?#>U*1PU`~ineP7m>o-$P zoU|KepHL7m=WAz14336T>kGE|o4LGEQ158lVLrbwr5#1MM8|9SthJ*8X|IpJ& zf8&y{HL5!U%|NJY4UJj$oiNm4lBJh}RYC3X8)U{`wfX#yoLrmw$bSx4=1R-Z%hRR}rwSvc zPcJLh7i=;*zDMs zfl65#i$~6-JGz~YLttV~23Pry_oTG9+$NvZF&Fl)Cnt7a3%_o5c$-gV@c?08k}*{R zIDm&h9%6rfP3aJ&q3L08OEax=cS@G-gAUHhB4jr1CO*s$5@BRwa$VHaF6izi&Hs4C zOH`l*xu|@eSzV1jt?fX~&CNYJJ(Uz9mC@G5v$MCyK#Xvi78VWB?Pr4N#e{V~318D7 z|78-KXpAI5L&rxOuuXu*G2s7#g!ZQL;K8$0*EeUmjM;r>m`&Qj`twl!_HQD0*~#L;uTxjVfcBRq&ntGYJ^hskBx(0ivb z|BZQQXy~f@p$qN&{G4BvNd=s%9 zz?XH^vp*z|;e)&3_P3D%F_&2zpL_!{l$!CmEURFtS%r9LK`qV(-3NVM{HlQ!7zm583?u{NsgpPwerr z?f2AFQyUw2w(dttTo${b=lfF?yRX>vj_k3pc7jlGAdo7h)+a4v|8)}Mce}wDmSx_J zVMAm27`2F*j~n^qYIBb`icDV9M%A34KEF6E&u%6;=)-8<;b?J6=xyYsnMb1nsTe$! zX|>sY81Xo@cD=pd$)C$q4Gq7ouIk3c$D93Um!zbhc(WrWt-|Jye?R`kR_kc#_Rmf3 zj^$K8q*KkRtSoeyA|xOPDYgANXa-(bkL`XBoS2%DSmw6CL?}+SJzHxgN=Zq@~V&3Ls$r458aAtV+arC~LeIj2<E(rCJU!a`!>i~_=q8h}n!_PA6B(_!cg!?gfR1e>nOCviVq;#&k-ih@9Q z91ZEqmBK>@-TU1(S7Q>qlxq0$skFB@pT7thWC-Zr*=m?uK3ep3QYOpjY@Khr$W$;^ z9vK2y!|J!ffEeI4z?%h`e1t&Z3%EfG=6!*V|0`n9leUw~RJgJs5KA)sj(Kc>ZB&N_ zLPw1FX}`?s(`5t_0~3poej33qCA8jXG+9PJoT(s(tI!~uwz=s|qLM9}ci|^qsffip z{-lNY&?WR|)l!l*DP;2vay4=FldxrDKwoERh-ka3+^_gCE}|mOcM_Rr_P9N5>adlTqG*LG9(Do{ReRrhK6X8%Viswj&2hx$hd%cXKcA(rn6C$_8K(5rw6aPI@kbl7y|Zql;Rlv;cOCm=9si{Tu;K)Fz8tM>CTuLKHF%h7i<32d?iAE4BX9QQiLQ#^zgpx*iAF0wL1ZQPS7H ztz5AW(bDbUpZFfwWxb-}o0t8CIplW^A(!>J87*^}?D!KQC~_nIdYy;C{X$t@%LTNL zlqyI%ER+Veh<$d2EjQ8|e$BzW`6yV?ew~*~34Mo}S1b8>gLz#q@%AUDv_KkzqVTn{j(9NcwP`^1ZgUm z{UxTQn4^-|c7D?Qc$tsY)9QEfHZ79<`Q;(@@%HsWAS zaM}|@Uii0(V04tvZiE9^Tt{~EKil$5WTt1MhBw^rf6ue%l?>4KDdasP$CkDxdZsVC z4VqobP71xw1$+c}{ywq8ka>PEC>#nD!w*BuJNc~m@$BL~ok}G+u-l?-EZtCGEuCHIXB>3ml%K^EP(6IHP#s{-XoDH&_YmGg95TgX zCS$q1N?4{<=by{oi`Z>ZE~s7Ag_gUo-u{*i?WbL|U!h&X?ey3x4RM8g~DAVL$&n z@wxDY!rIAU#gxYQ_U+r%%Nu?8zNg`EU8J=LyX5}bvLXJIcm@LNXqwGoWcG9I+v!#U zi(X&~f^2xBfk!OY?=kx&3(G}KA3eVDco@#v^VPUWS?bW37)11Bq?GUhQ`zKjF+~(q z0Y)cT)!6_)fr_RK#9&0+hs>mq($xJ^ZpHqoTvY|dthW6nzdK?-(j_W3(f#z%8Pv^R z`OGI%4xX$n;8cm;66KCl%w{xcR=Qfw>k(xrUfmZg+!fH<{P|Vi z!Am-A*42~<|8b12Rb+H4oAe19pXr->z6&Dd4>`z1afTB?zFwIk@Jt6*p{BTEGkmNJ zNE<90DUN}k<~OIZAu#kwL8u)HEHsa3|K^*h&p0cA!<_Zie7V*T=pX_D0s!XKKlBYx zY~I6Rs~bg6i%ygzuj_oSq#JHr_g6Yz3>vlcBsAf2czSIIKR{DA308MutlQI|o~-FD zl;tL7{DlQCN-{kP6W=GmGiJ2;U!GkaNSB|Hrp+TEB;Z5)$iatzQNhE8p`W9kvaa6d z(J(*JB`e4AQ^>+-4+q+HDVSJQhFKYZcG=DSDY!)KB^n*yGWodTC{O+w)=T7S04o2l zWRQ0P!=DO1@9H!fjQ{HI=4GSU$VgZPSjo1J?SG7E#F$?bV{0(xx!n#f>R|@jAF=y> zh^N7*XK8C<`}hYwR;5vTkVjX{3hNjs&Zx?m+`3p;5m<$ZS;Uwtll=^+3$``IVN5du zRjs3RY{E|A6A}^Ce|d0nnc@%@{swfM1yxl@yxB0{G1))WySrJ`>2ahO;B%oK;w;fjvVB2j*8JnXINp=UYW0iA8+9Lq+K zo}orf@5ND|!;_OHgsH_`U%Qr9A|{MSa0I;#&JU=6!IPn zS}d$IDMespx@t0x>2t!_3)+bI*Jb-S4pw6@@q&eqf-g+~Z1jA7ZQlUe>oGS3$!cuYr%>^s?@PE1UQE#I3>$R|@P#3e}9 z*p>^j{|T@xseKdNdwnFwv2aO4YT}N)(`(uB(x+ZI%^~(*74dtd8DAJt;=mvyZyv%Qq6xDOxB2Eq!yJmJ!l)ve!yy-~!)*`QFg2sV&YJukXc+ z@ypus4_kg3(rBq4^oW&J_A@{m3eaZ{=Hv2A6lf8pTO>t9xDDTJbaY0SFG4~p&6oRR zKL5J>(G-WQk(QJ8s_ldAg{O7^Mcnfn89<{^qoCB))q$eht3x(rdMo zKdN2(IIHWIq$ela-k(oR>vdcG79{wrT731i#e zfe#CJ3-`%`m4LHVEh5Gah5{%MoTH>7kyKu7%uh^qVSv0hJskWS0v;MaxZwuJc-*?m zz=@yufBygW_V(j@VPhj!&&S)P>lWMPVqNaahdCJsotl)3UgL4aqWw~nE;DYpHPy=d zNmb-p$CuN)6&=RYQY}`7wB)AW?RP(4B{IUlGQOOAbCljLQ>M65ga??y{2&!XM0R^hPK`jH%gauZ&g%{TL{=!^e~j6OcD!F=Q8?o)GD0M^{MV({h8R;k$b{JEw(sSCY>DD-~;|hxduXe z!@%>i!rD`_)O#W>Etv?pauqc~4(AXfZy8L;0d@dXVnj=k%V7$Uq8YF*yQ+77?$Ji< zzpiBh4e-m*riioS_ZLVCzb5}(5p~Wud6UVD8;;p^4#AM<=l>)nzs$z?i?o4Y%|qVe z?46bBpAF428p6f`LH-s&BfMJQUtw8hytjqLo2q~JL`-)MxG{w$W@eCpW<{C+2XM&W z$u#nbvea&J5mZzMW0Lwkk4l6cNQ0%8?cy;|I9^gaV)UPrFRuCMpuU~%^2D;nz1VA8 zp5+M`em~<^80Co7!Tu)0@;C|-e!iXi^4$%|9Qju*72!8CH#f{EG&GaxJYgUYd}1f= zhY4xe{8%;eG9OfB&4y9!P8n~rIls$V`;kjvnz!sd?4Fx+wa+4L&#F{1cG(}awM!(@ z#t-I+@DYkXIIvPsR+dbr24GELR~JcGSeR^yT6t~Fz(P?^z@3--O&G4#L|%h)Z4&}E z4t?WVmut}G+Q+ca2Pr1YxBF%uz@}U}Hh-=<+)8Pgnj*2{7%o$c-^hh9!nA5^C@LwL z0fwBBkge`RbT_)j6x2RFgv^cZB`U{%PF$kYHz68 zS0IHI2PcP%A{SXS@Tc>rx3QpF?u3PDeYp$xtnGeD-}U9Zb%1-auz#5wCDJsQBNA8w z7jT>ydE)rAAR_!{259kM`WX7+x5`RHO-&$T0RDG1!8N^o(Q(O2YdWY|GdB|^n!Bgw7dg0h+F6qvdnUeu3;on~e zke~wXe~8`me61NDA0I>k-39m0noVBWza!IrU5V|JMnlmJr5Bxc-MiNG3Ld7dB5gQ% z>gTXIehv+7ZS4gtmT?bMu=8 zXXf%pe<$_00qcpuEFlFn0SnWs{li~60qsR6V=9Yx7h37rGD%99VdSJrQmx8v|38-6 zK4|xMy~iGfz_WLCb$uP)17rvQA+L0JvjP6Y%u6(JNcJ=tVYW*rjbsrb$oRRWSM*`> zbyEeb_GvUHedd$}>X2AjnMHj@$eMX)}js!P|>%DGX5iA{94dH z#biF)c39hYl>X7U*uLy&0jr#*;La=im~F-8!6<;rWja~T(DGbaDV07SE&S!*e`Ygc z!3ppyAZb@th9Xiv=e?;vurNQ$@x?{Mj9X2KGYr0QyhoG$i`$&Qr;8}%3P*>AOto=# zmf_3{FSWh$5h|~)4hOI&wH$!ir1$nikyyn5(A;UnMlHwa7EdjQE{#!YOPM4~j*UnG z9E9Hh5|>dLU0KOkt>21T*Zm7;)B-aWueGqD0dm%+$tLSC!?M=E3Y=71d-qGdN>j)^ zr{TdJG*`%3KB3@|G=X(|opjvY)IQO)V&LiNnURwr#+fN)ZB6Ir=Vwx{!_LK#_seIu zH$5$Bg2D2&lN1BQrBVBKva{L|X>Bf|Ho-`T4jr?!gxl2ITu@Vk@}G<$ARrL4|F0br z9|(q!`}_MkO*X3a6UF%SMc56@cqI}*iJ6t14TvBxx@k$H7KxKq7_oyfd67WP35cOR zTL}#foIp+PSU z=&b7Dt@3h4&yLNb^K)rn$&xFunb|~Lr#to+3{56&d%12qP4XG24u zpdlfE^#>w1liT#QtfnS?jGNwu0eTo<<-jXc z(Zm60K2TWLI64l>vvolmF2`mz?C*CM>f0JgQ|x6d+*OV<I?yuPa|b^vf+biX+Lw|EWy{b%c#SWkC{lJFsg^yPpT00jT&i2gND6bQ(Gyrssy zi4_eET#`I$(LFG>k%6Juy6ltFXkYX9*u5e<-WEd)p1}pDj(R8wN8`)uNN=zT2iN;< ziNr}yFTWsG@J&GIRTOmleJfPTB~WCPS5)*BNJg1t(Y~M5y(8v7{-%q$$XzC~ueF@) z7vwpp)JwkKSeT2B6u@rn2#m9OuU_uT&y!a4RV5dP6oL6VC@PZwd$Rw)jM0hJyQu>k{C z1xi?bKp83q<+3nt7-LH_>ovhwY1Q;wrW?ZMPe%cHPeV(qu%ZG12sgm3NObSG9Y3Ij zo7cSXG>C%-tVrkzu_C7tAn@Vg&HXr1?vY{lKvEJv`Q-VWv*SG~aFGDL6BgDjmFLoL zx#OqZVx=$A<0n!yK|rOAs72| z(LMKiJVOmMy4F>evm-+RaYL&LhwqP%dAI+^uKfZ@Jb*$mkp95^lcu4bu z(2O_}%tiKO64Fn9dfq{_yL69zRNY}&c!d2cjkB~~tKPdmLV<{OK}|uN>zdD8hqE$E z6}yNt!-oZ#Z2t1RdK&9(OFGpYCP3V51snS;9IPZW8@-0(Q1Q2K$+w2BpRDq%MBu<{o{s3T)F^1h4F|yeLTX3dwJKCwa>CPCO{~+CXRDg5Kr$I1;d*`<&vr3 zQQ*6jC@@JwE%#HehMq0|)^7r?zF3%uf!QW-En=IM|0D|&6kj)d_{(qK88PpJL8So8 zGK5+VaDFLj%uH{^V-|D0C0vg72Lt@l!@LyuM9vICg;J7;D5l2^z_cxNSz~ZP!zW3} zPI@p1n!9mR#uA@@QVwTI+A95X#r|T8NgeF4G*U(km6LttCp?(3Fl)>dSAHCsvEcD! zpyT75gCO!?Gx)t4NF5^$2FSJ7uN`UedVNI~67f&MY(6)arQoH?Y|+4DO0v|Y)Shzm zK^7GtNdPkH;lB8UCENZ`!FM-R?B3}R_oJMi=s0&VOzB!iT-4u5@?Q_(rza>0WBX6< zDY3^|Iku781JrGJeTZv36eMWa(PWJtsTg89i>8hERi$J8kqvHi!9$dml_n}sZ+i&L zuC^nGi17f~GzLWy-<*B{4~NsGON&RfR+cL#(^@$1J+hNk2}b@Ao8ioLE^SDR70=D( zyXi;w8vyghm@M)xXQyvI=rRPsd0!8*_Hlnq?$=Fz@QQw(#)*r};m?Dr0cjZ(bVk(5`b=2#Y8k%2AOr)HEI{s?@Ym*R>A@ueVU|7D<+47=aE|bArXcubMt% zGeYIl4x*ahpg}nlzx><`rtIL538Cui$)6W?UjA>_^$376C^7Fw!x867ozmXK3yi)! z^n83$P*Mz|!-}r+)Ceqzw|>a8tv>hhxZsb5lB>JzY>1qx6v&QbBr{1u(6h%s@y86j z0}Uu&Jn>t|_2nA3V_8~SKCw%iUMoXSowAIm8n}n@P=%9=2!_xFUAM9qu@zP5_DfG9 z2+>iqW5*s&JKyeU$7Mc^I0983WPV%qZ8MMGEG}&AE9%pa8esV{|^Q z*A1K^7LE~x&!-JK=g(opAAAmuS5l`9|Iyir4EOJRxHO*O^?p*ThY`-q0^E}7J~Yj% zV(qZGA6o%W0j-fNZCB49y?8+h%r!fpe(0orND8kdF)BK8K|5yX&U6$?+)fed#Fl08$9 z%g+uxFH`u|&Vk@>XN^``O7ASTbzNqCb?RV<-1;^u5czn^YT8DXf$wlXZYAzs5Q zvNAy=&1XNtu}*P&MVbgrQ|a|@SYo*NW8?5zY~#Bpsss-rLs$K=Y};Xc0qDjb&&#fF z_si*Eo@o)+DGX(5^xWKt3cL?QO~?&Yj0|?9Nj0~_#!$Sk>TM3#e1;VLho3{-do999 ziz==$cY?20LbI@PnSi0~AIZ#UY*imU9gAW44bkSf*=E6@#4~84DOKmat2PD)-eA(f z)*Oh2-zvItE<1!!!eNx}oy%fDL82n>*9qny?{AM2)*@jyH#hE(Guzwb@2@xG;D$?3 zMy5RjG`fx^79I=UjIeAXYt!XE^|U7RzEWs*U9zjVHf(63veFJMcz!xMUbHA1bE?4C z;QZx#l77zEkCOJR-a_2(bWk+GVhGTP=$t{``zI<8763d7eHMVy&I8Ots(+z6#D+V@ zIq)`nrPZ0N`}&*n1k&$Zl+1jkvU>AjRALc-{LCiU0csP!S|J&9f?AziX-eAdR4C{j zY6w1pGhB#RI~W6B(w{BzVdG9>=pZFG=Pc8aO7h}IV0#aIB1kMnE?^0{9m)$bDpm4( zh;Ni?UXVRk=8JvBX*d_^=-=`iERSZpm4%XR?`fj#5t`GF9kig{$44+Qz;bB{WGn0Q zos>~(i2@alQB2xi57a4msgQz+N!NYE$Xh!p{5T18FtJwe9@lp5%#Mc}z1!5lw7A$L zaueYmXUSYoctQdhIJ+Iy+5xOWc?6lN^G@b|h>@4RLlcS1pSL&&QR}W_5&ugdK6W`v z2OGW5cSjf-((7y`Bq8W^4`||?FPN;w`SBRJK_Ceyf{dgu`vN7w^P?E$CgoLQg$0~p z2Pe!Yb`4kBM=l+pSUt*aeh3O=LgAI~Mw-_gl(KgYpE9QLspa^r8Cq>3A=p3NJQ46C z#iJWRPPlq$?I{t&3?>5{5XLT`FLMoEgMLt8;9^$xS&pvxX8tK8u* zDbVLvUBw%tFe^fLS){kIak&$DI{O<+j&=_H+TCt+dU{h+9cu^_@DT%#^C`-dnO{R7*a>&QApygWMub+v!iL}Eqn&XeIZlV`{@iHVg%PnNYiX3cPRjI zu$x()d^LCt*2FwLB;4p*v-U=ax52FvFyiQAl>9Cc%@J9a=SP_TG*QMOB=oiUTYJBa zI5WaD9%O7;^@r?xMv~w?BWILYX~e3A&$Y{VmNQQT6Y5<3^(IpN^VB2zIE`E!R*_O6 zEp)*TQ6;j9-Nm@DGKjj^B1aAx>a3ws&vT#wAI{AAizL$OA@J?XWfxx1$Aj_k$OyZI zYOvuBx-_iZr|!4I{=5Qw`cbwpdPv;SUIl?&GqniMg7wolw8qj&Ej%r*s&iggRZ1jP zncKXitDFdFl*l#0&}b@gq377TKK;e72WggNT|OnzADf$-Z7&xcu3G^Q6qyQP=oppI z^q67fse~|PXet#t6Ewpr8HADo_EEz&D~yq}ez;lkJtnJt{BQ->;yrIC)$Ce(511p? zeGL5wVql1Qkmim~lTI-D*0;;Ify3E=t8H60Qgh@eG_s-A?t2!4FXzpV*9k#!8jPvV z$D^j2Al1Liin{pD2@o6dhgbau%U ztxEo0FVyOa&W^RsoQ|6~>1Lw~vyDQa-Sp&oc(Jl&?(c>t3PsU))iurE(6F7*7)_Xv zEvc#M02ZuMqZ=k1q+Kz2wQ( zs9kqo&}+ZrG9!*En`VZaJjH4RpV49s|Mq8^_NL@PQ0%588hMJ6n;+xSPCJN!&;D?ucw=-~5rlkrDWI9PXQ_&GA*Ux|#R6w&8UKWk>mr%p!|-J!|J4uVbw>WlIfNZo}dx85PSLV}A%ANhsRgcx!?I^x1lCqT@L8k;k(SU5tV z0;zX(h!Kp=YrTdGl4LNseX1e7stLg}$9AU)of& z@Zg!o^pIAQL@)?5L79c%*1x&OZtsvXDLO4v>bJa&M4~NXrHMo;KX!zKDoA=av1FqV zp4)jS)gs5u1>GpCXRHqek_!c&A=Dv;Drt9{Io~2*nX~Ns0k7n!y_{U1s5Cv8g8kN6 z*-C8c_jH*l2MD%kgfQ6jU_)XQIdK*wy+e+@-ESZyw~SyW7kZ37ETs}U=s;$W!u(?O zR8V0|ks7z(%kMtLZ%>Ys40RqAMP?vk<*V1)K{#j0W4{~tvPOVwi=0)z)aOB;C>te} zY4vq{YTFeZ>=>-MqkF!MS{a|&nY{FP67|FP!C@<#RymqPI+Rzddb`P5FNgTI|@&K zKghylO^g|hiEs}k2PGG0@alW^I~fWWSZBpssE%~tiG7DzCKs{5yoqR1?7|d6a>GL_U?^5VOa9hNu=1CaE@^BI+~KGy%gcmj%>-z zj&!FqiwhEY9PpzK{%+a$AmDRb*Hz7vl<@7o9T%v~5vxi6F^95J6RZHlJ2M0mi{zp&p%jDXX9uOFWR6P1-4nZ}JHUTR4z0w@ARe(H#-b1_hITXB7)&8f3a9G$)AHCI+rNf4 zsNlB~kgDYUZTfqPQaAW^Tmv3QRx7znJ-O2_-_+<yWhAd?{i&0)l~tLAQc5`MdlB{+edM>Pl&* z$8YB&IZ8L!l<1%3`xWw4gn^CxsgH#jN{YFYo8$a&FzlAib-(Dc+Fus0>rrUs%MvF`rv`Vg{LwrV)%*iAe)*86I?2bFrB3L~(aEQHR&t`VH`I+~ zF5p|AHEn%(@E$3`RJ5tkGE)g0s^TW!cirTTe<*ONdI?*x~;X7sfVYV<$u?}^o2n5 zvO`1nrg9hK!+rcCqwx0g!v_fTt4<@eQVm(NjvZ?sI=}f%P)Nuo{nZ#^W UQ?XPA{vb$BT1l!_!X)(n06ryC9smFU literal 0 HcmV?d00001 diff --git a/packaging/X11/xgps.desktop b/packaging/X11/xgps.desktop new file mode 100644 index 0000000..bdd31e2 --- /dev/null +++ b/packaging/X11/xgps.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=xgps +GenericName=GPS information +Comment=Display GPS information from a gpsd daemon +Exec=xgps +Icon=/usr/share/gpsd/gpsd-logo.png +Terminal=false +Type=Application +Categories=Application;Graphics; diff --git a/packaging/X11/xgpsspeed.desktop b/packaging/X11/xgpsspeed.desktop new file mode 100644 index 0000000..477e258 --- /dev/null +++ b/packaging/X11/xgpsspeed.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=xgpsspeed +GenericName=GPS speedometer +Comment=Display GPS speed from a gpsd daemon +Exec=xgpsspeed +Icon=/usr/share/gpsd/gpsd-logo.png +Terminal=false +Type=Application +Categories=Application;Graphics; diff --git a/packaging/deb/etc_default_gpsd b/packaging/deb/etc_default_gpsd new file mode 100644 index 0000000..54ebab6 --- /dev/null +++ b/packaging/deb/etc_default_gpsd @@ -0,0 +1,8 @@ +# Default settings for gpsd. +# Please do not edit this file directly - use `dpkg-reconfigure gpsd' to +# change the options. +START_DAEMON="true" +GPSD_OPTIONS="" +DEVICES="" +USBAUTO="true" +GPSD_SOCKET="/var/run/gpsd.sock" diff --git a/packaging/deb/etc_init.d_gpsd b/packaging/deb/etc_init.d_gpsd new file mode 100644 index 0000000..1c123b8 --- /dev/null +++ b/packaging/deb/etc_init.d_gpsd @@ -0,0 +1,160 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: gpsd +# Required-Start: $remote_fs $syslog $network +# Should-Start: bluetooth dbus udev +# Required-Stop: $remote_fs $syslog $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# X-Start-Before: ntp +# Short-Description: GPS (Global Positioning System) daemon start/stop script +# Description: Start/Stop script for the gpsd service daemon, +# which is able to monitor one or more GPS devices +# connected to a host computer, making all data on +# the location and movements of the sensors available +# to be queried on TCP port 2947. +### END INIT INFO + +# Author: Bernd Zeimetz +# +# Please remove the "Author" lines above and replace them +# with your own name if you copy and modify this script. + +# Do NOT "set -e" + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="GPS (Global Positioning System) daemon" +NAME=gpsd +DAEMON=/usr/sbin/$NAME +PIDFILE=/var/run/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +if [ -z "$GPSD_SOCKET" ] && [ -z "$DEVICES" ]; then + GPSD_SOCKET=/var/run/gpsd.sock +fi + +if [ -n "$GPSD_SOCKET" ]; then + GPSD_OPTIONS="$GPSD_OPTIONS -F $GPSD_SOCKET" +fi + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ + $GPSD_OPTIONS -P $PIDFILE $DEVICES \ + || return 2 +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME + return 0 +} + +case "$1" in + start) + if [ "$START_DAEMON" = "true" ]; then + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + else + [ "$VERBOSE" != no ] && \ + log_daemon_msg "Not starting $DESC" "$NAME" && \ + log_end_msg 0 + fi + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + reload|force-reload) + log_daemon_msg "Reloading $DESC" "$NAME" + do_reload + log_end_msg $? + ;; + restart) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 + exit 3 + ;; +esac + +: diff --git a/packaging/gpsd.changes b/packaging/gpsd.changes new file mode 100644 index 0000000..ef467df --- /dev/null +++ b/packaging/gpsd.changes @@ -0,0 +1,2 @@ +* Sat May 19 01:21:58 UTC 2012 - tu.c.truong@intel.com +- Initial commit to Gerrit diff --git a/packaging/gpsd.spec b/packaging/gpsd.spec new file mode 100644 index 0000000..fff6f9c --- /dev/null +++ b/packaging/gpsd.spec @@ -0,0 +1,91 @@ +Name: gpsd +Summary: GPS Daemon communication library +Version: 2.95 +Release: 1 +Group: TO_BE/FILLED_IN +License: BSD +Source0: %{name}-%{version}.tar.gz +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +BuildRequires: which +BuildRequires: pkgconfig(ncurses) +BuildRequires: pkgconfig(xt) +BuildRequires: pkgconfig(xaw7) +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: python + + +%description +GPS (Global Positioning System) daemon gpsd is a service daemon that monitors one or more GPSes attached to a host + computer through serial or USB ports, making all data on the location/course/ + velocity of the sensors available to be queried on TCP port 2947 of the host + computer. + . + With gpsd, multiple GPS client applications can share access to GPSes without + contention or loss of data. Also, gpsd responds to queries with a format that + is substantially easier to parse than the NMEA 0183 emitted by most GPSes. + + +%package -n libgps +Summary: C library for communicating with GPS devices +Group: TO_BE/FILLED + +%description -n libgps +libgps is a service library for querying GPS devices. There are two +interfaces supported by it: +monitors one or more GPS devices. It is intended for concurrent use by +several applications. +device to which the GPS is attached. + + +%package -n libgps-devel +Summary: C library for communicating with GPS devices (development files) +Group: TO_BE/FILLED + +%description -n libgps-devel +libgps is a service library for querying GPS devices. There are two +interfaces supported by it: +monitors one or more GPS devices. It is intended for concurrent use by +several applications. +device to which the GPS is attached. +. +This package contains the header and development files needed to build +programs and packages using libgps. + + +%prep +%setup -q + +%build + +export LDFLAGS+="-Wl,--no-as-needed -Wl,-z,defs" +./autogen.sh +./configure --prefix=/usr --disable-python --disable-static + +make %{?jobs:-j%jobs} + +%install +%make_install + + +%post -n libgps -p /sbin/ldconfig + +%postun -n libgps -p /sbin/ldconfig + + +%files + +%files +/usr/bin/* +/usr/sbin/* + +%files -n libgps +/usr/lib/*.so.* + +%files -n libgps-devel +/usr/lib/*.so +/usr/include/* +/usr/lib/pkgconfig/* + diff --git a/packaging/rpm/gpsd.init b/packaging/rpm/gpsd.init new file mode 100644 index 0000000..85fab36 --- /dev/null +++ b/packaging/rpm/gpsd.init @@ -0,0 +1,93 @@ +#!/bin/sh +# +# gpsd Service daemon for mediating access to a GPS +# +# chkconfig: - 44 66 +# description: gpsd is a service daemon that mediates access to a GPS sensor \ +# connected to the host computer by serial or USB interface, \ +# making its data on the location/course/velocity of the sensor \ +# available to be queried on TCP port 2947 of the host computer. +# processname: gpsd +# pidfile: /var/run/gpsd.pid + +# http://fedoraproject.org/wiki/FCNewInit/Initscripts +### BEGIN INIT INFO +# Provides: gpsd +# Required-Start: network +# Required-Stop: network +# Should-Start: +# Should-Stop: +# Default-Start: +# Default-Stop: +# Short-Description: Service daemon for mediating access to a GPS +# Description: gpsd is a service daemon that mediates access to a GPS sensor +# connected to the host computer by serial or USB interface, making its +# data on the location/course/velocity of the sensor available to be +# queried on TCP port 2947 of the host computer. +### END INIT INFO + +# Source function library. +. /etc/rc.d/init.d/functions + +exec="/usr/sbin/gpsd" +prog=$(basename $exec) +PIDFILE=/var/run/gpsd.pid +CONTROL_SOCKET=/var/run/gpsd.sock + +[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog +: ${OPTIONS:=-n} +: ${DEVICE:=/dev/ttyUSB0} + +lockfile=/var/lock/subsys/$prog + +start() { + [ "$EUID" != "0" ] && exit 4 + echo -n $"Starting $prog: " + daemon $exec -P $PIDFILE -F $CONTROL_SOCKET $OPTIONS $DEVICE + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop() { + [ "$EUID" != "0" ] && exit 4 + echo -n $"Stopping $prog: " + killproc $prog + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile + return $retval +} + +restart() { + stop + start +} + +case "$1" in + start|stop|restart) + $1 + ;; + force-reload) + restart + ;; + status) + status $prog + ;; + try-restart|condrestart) + if status $prog >/dev/null ; then + restart + fi + ;; + reload) + status $prog >/dev/null || exit 7 + # If config can be reloaded without restarting, implement it here, + # remove the "exit", and add "reload" to the usage message below. + action $"Service $prog does not support the reload action: " /bin/false + exit 3 + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|try-restart|force-reload}" + exit 2 +esac diff --git a/packaging/rpm/gpsd.spec b/packaging/rpm/gpsd.spec new file mode 100644 index 0000000..dfded5b --- /dev/null +++ b/packaging/rpm/gpsd.spec @@ -0,0 +1,370 @@ +%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} + +Name: gpsd +Version: 2.95 +Release: 3%{?dist} +Summary: Service daemon for mediating access to a GPS + +Group: System Environment/Daemons +License: BSD +URL: http://developer.berlios.de/projects/gpsd/ +Source0: http://download.berlios.de/gpsd/%{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +BuildRequires: dbus-devel dbus-glib-devel ncurses-devel xmlto python-devel +BuildRequires: libXaw-devel desktop-file-utils +BuildRequires: qt-devel + +Requires: udev +Requires(post): /sbin/ldconfig +Requires(post): /sbin/chkconfig +Requires(preun): initscripts +Requires(preun): /sbin/chkconfig +Requires(postun): /sbin/ldconfig + +%description +gpsd is a service daemon that mediates access to a GPS sensor +connected to the host computer by serial or USB interface, making its +data on the location/course/velocity of the sensor available to be +queried on TCP port 2947 of the host computer. With gpsd, multiple +GPS client applications (such as navigational and wardriving software) +can share access to a GPS without contention or loss of data. Also, +gpsd responds to queries with a format that is substantially easier to +parse than NMEA 0183. + +%package devel +Summary: Client libraries in C and Python for talking to a running gpsd or GPS +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: pkgconfig + +%description devel +This package provides C header files and python modules for the gpsd shared +libraries that manage access to a GPS for applications + +%package -n libQgpsmm +Summary: Qt Client libraries for talking to a running gpsd or GPS +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: qt +Requires: pkgconfig + +%description -n libQgpsmm +This package provides Qt shared libraries that manage access to a GPS +for Qt applications + +%package clients +Summary: Clients for gpsd +Group: Applications/System + +%description clients +xgps is a simple test client for gpsd with an X interface. It displays +current GPS position/time/velocity information and (for GPSes that +support the feature) the locations of accessible satellites. + +xgpsspeed is a speedometer that uses position information from the GPS. +It accepts an -h option and optional argument as for gps, or a -v option +to dump the package version and exit. Additionally, it accepts -rv +(reverse video) and -nc (needle color) options. + +cgps resembles xgps, but without the pictorial satellite display. It +can run on a serial terminal or terminal emulator. + +%prep +%setup -q + +%build +%configure \ + --enable-dbus \ + --disable-static +sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool +sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool + +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} +make DESTDIR=%{buildroot} pythondir=%{python_sitearch} install + +# init scripts +%{__install} -d -m 0755 %{buildroot}%{_sysconfdir}/init.d +%{__install} -p -m 0755 packaging/rpm/gpsd.init \ + %{buildroot}%{_sysconfdir}/init.d/gpsd + +%{__install} -d -m 0755 %{buildroot}%{_sysconfdir}/sysconfig +%{__install} -p -m 0644 packaging/rpm/gpsd.sysconfig \ + %{buildroot}%{_sysconfdir}/sysconfig/gpsd + +# udev rules +%{__install} -d -m 0755 %{buildroot}%{_sysconfdir}/udev/rules.d +%{__install} -p -m 0644 gpsd.rules \ + %{buildroot}%{_sysconfdir}/udev/rules.d/99-gpsd.rules + +# hotplug script +%{__install} -d -m 0755 %{buildroot}/lib/udev +%{__install} -p -m 0755 gpsd.hotplug gpsd.hotplug.wrapper \ + %{buildroot}/lib/udev + +# remove .la files +rm -f %{buildroot}%{_libdir}/libgps*.la + +# fix non-executable python script +%{__chmod} +x %{buildroot}%{python_sitearch}/gps/gps.py + +# Install the .desktop files +desktop-file-install --vendor fedora \ + --dir %{buildroot}%{_datadir}/applications \ + --add-category X-Fedora \ + packaging/X11/xgps.desktop +desktop-file-install --vendor fedora \ + --dir %{buildroot}%{_datadir}/applications \ + --add-category X-Fedora \ + packaging/X11/xgpsspeed.desktop + +# Install logo icon for .desktop files +%{__install} -d -m 0755 %{buildroot}%{_datadir}/gpsd +%{__install} -p -m 0644 packaging/X11/gpsd-logo.png %{buildroot}%{_datadir}/gpsd/gpsd-logo.png + +%clean +rm -rf %{buildroot} + +%post +/sbin/ldconfig +/sbin/chkconfig --add %{name} + +%preun +if [ $1 = 0 ]; then + /sbin/service %{name} stop > /dev/null 2>&1 || true + /sbin/chkconfig --del %{name} +fi + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +%doc README INSTALL COPYING +%config(noreplace) %{_sysconfdir}/init.d/%{name} +%config(noreplace) %{_sysconfdir}/sysconfig/%{name} +%config(noreplace) %{_sysconfdir}/udev/rules.d/* +%{_sbindir}/gpsd +%{_bindir}/gpsprof +%{_bindir}/gpsmon +%{_bindir}/gpsctl +%{_libdir}/libgps*.so.* +/lib/udev/gpsd* +%{python_sitearch}/gps* +%exclude %{python_sitearch}/gps/fake* +%{_mandir}/man8/gpsd.8* +%{_mandir}/man1/gpsprof.1* +%{_mandir}/man1/gpsmon.1* +%{_mandir}/man1/gpsctl.1* + +%files devel +%defattr(-,root,root,-) +%doc TODO +%{_bindir}/gpsfake +%{_libdir}/libgps*.so +%{_libdir}/pkgconfig/*.pc +%{python_sitearch}/gps/fake* +%{_includedir}/gps.h +%{_includedir}/libgpsmm.h +%{_includedir}/gpsd.h +%{_mandir}/man1/gpsfake.1* +%{_mandir}/man3/libgps.3* +%{_mandir}/man3/libgpsmm.3* +%{_mandir}/man3/libgpsd.3* +%{_mandir}/man5/rtcm-104.5* +%{_mandir}/man5/srec.5* + +%files -n libQgpsmm +%defattr(-,root,root,-) +%{_qt4_libdir}/libQgpsmm.so* + +%files clients +%defattr(-,root,root,-) +%{_bindir}/cgps +%{_bindir}/gpscat +%{_bindir}/gpsdecode +%{_bindir}/gpspipe +%{_bindir}/gpxlogger +%{_bindir}/lcdgps +%{_bindir}/xgps +%{_bindir}/xgpsspeed +%{_mandir}/man1/gps.1* +%{_mandir}/man1/gpsdecode.1* +%{_mandir}/man1/gpspipe.1* +%{_mandir}/man1/lcdgps.1* +%{_mandir}/man1/xgps.1* +%{_mandir}/man1/xgpsspeed.1* +%{_mandir}/man1/cgps.1* +%{_mandir}/man1/gpscat.1* +%{_datadir}/applications/*.desktop +%dir %{_datadir}/gpsd +%{_datadir}/gpsd/gpsd-logo.png + +%changelog +* Mon Jul 05 2010 Michael R. Davis - 2.95-3 +- Updated to move rpm files to packaging/rpm folder +- Renamed gpsd-qt to libQgpsmm + +* Sun Jul 04 2010 Michael R. Davis - 2.95-2 +- missing X11/app-defaults/xgpsspeed + +* Sat Jul 03 2010 Michael R. Davis - 2.95-1 +- back ported spec to gpsd from Fedora 14 +- updated to 2.95 +- added gpsd-qt package + +* Thu May 06 2010 Miroslav Lichvar - 2.94-1 +- update to 2.94 (#556642) + +* Tue Mar 02 2010 Miroslav Lichvar - 2.39-7 +- don't use deprecated SYSFS{} in udev rules (#569089) +- fix init script LSB compliance + +* Mon Feb 15 2010 Miroslav Lichvar - 2.39-6 +- fix linking with --no-add-needed (#564662) +- use %%global macro instead of %%define + +* Wed Aug 12 2009 Marek Mahut - 2.39-5 +- RHBZ#505588: gpsd has a broken initscript that fails to launch daemon + +* Fri Jul 24 2009 Fedora Release Engineering - 2.39-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Mar 31 2009 Tom "spot" Callaway - 2.39-3 +- some of the gpsd client bits went into gpsdclient.h, but that file wasn't getting installed + specifically, viking needs that header to build. + +* Wed Mar 25 2009 Douglas E. Warner - 2.39-2 +- adding patch to try to fix parallel make errors + +* Thu Mar 19 2009 Douglas E. Warner - 2.39-1 +- updating to 2.39 +- fixed potential core dump in C client handling of "K" responses +- Made device hotplugging work again; had been broken by changes in udev +- Introduced major and minor API version symbols into the public interfaces +- The sirfmon utility is gone, replaced by gpsmon which does the same job + for multiple GPS types +- Fixed a two-year old error in NMEA parsing that nobody noticed because its + only effect was to trash VDOP values from GSA sentences, and gpsd computes + those with an internal error model when they look wonky +- cgpxlogger has been merged into gpxlogger +- Speed-setting commands now allow parity and stop-bit setting if the GPS + chipset and adaptor can support it +- Specfile and other packaging paraphenalia now live in a packaging + subdirectory +- rtcmdecode becomes gpsdecode and can now de-armor and dump AIDVM packets +- The client library now work correctly in locales where the decimal separator + is not a period + +* Mon Mar 16 2009 Douglas E. Warner - 2.38-1 +- updating to 2.38 +- creating init script and sysconfig files +- migrating hotplug rules to udev + hotplug wrapper script from svn r5147 +- updating pyexecdir patch +- fixing udev rule subsystem match +- Regression test load for RoyalTek RGM3800 and Blumax GPS-009 added +- Scaling on E error-estimate fields fixed to match O +- Listen on localhost only by default to avoid security problems; this can be + overridden with the -G command-line option +- The packet-state machine can now recognize RTCM3 packets, though support is + not yet complete +- Added support for ublox5 and mkt-3301 devices +- Add a wrapper around gpsd_hexdump to save CPU +- Lots of little fixes to various packet parsers +- Always keep the device open: "-n" is not optional any more +- xgpsspeed no longer depends on Motif +- gpsctl can now ship arbitrary payloads to a device; + It's possible to send binary through the control channel with the + new "&" command +- Experimental new driver for Novatel SuperStarII +- The 'g' mode switch command now requires, and returns, 'rtcm104v2' rather + than 'rtcm104'; this is design forward for when RTCM104v2 is fully working + +* Tue Feb 24 2009 Fedora Release Engineering - 2.37-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Sat Nov 29 2008 Ignacio Vazquez-Abrams - 2.37-3 +- Rebuild for Python 2.6 + +* Wed Mar 19 2008 Douglas E. Warner - 2.37-2 +- moving gpspacket.so python lib to main package + +* Wed Feb 27 2008 Douglas E. Warner - 2.37-1 +- update to 2.37 +- removed install-gpsd_config.h.patch +- installed pkgconfig files in devel package +- added patch to install python modules in sitearch +- removing rpath from inclucded libtool +- moving X11 app-defaults to datadir +- using macros for commands in install; using install instead of cp and mkdir +- cleaning up spaces/tabs for rpmlint + +* Tue Feb 19 2008 Fedora Release Engineering - 2.34-9 +- Autorebuild for GCC 4.3 + +* Sun Aug 19 2007 Matthew Truch - 2.34-8 +- Patch Makefile to also install gpsd_config.h as needed by + libgpsmm.h. Redhat BZ 253433. + +* Sat Jun 30 2007 Matthew Truch - 2.34-7 +- Make sure the logo is actually included (via the spec file). + I need to wake up before I try even trivial updates. + +* Sat Jun 30 2007 Matthew Truch - 2.34-6 +- Learn how to use search and replace (aka fix all instances of + gpsd-logo.png spelled incorrectly as gspd-logo.png). + +* Sat Jun 30 2007 Matthew Truch - 2.34-5 +- Fix desktop file and logo file name. + +* Sat Jun 30 2007 Matthew Truch - 2.34-4 +- Include icon for .desktop files per BZ 241428 + +* Tue Mar 20 2007 Michael Schwendt - 2.34-3 +- Bump release for FE5 -> Fedora 7 upgrade path. + +* Tue Feb 27 2007 Matthew Truch - 2.34-2 +- BR python-devel instead of python to make it build. + +* Tue Feb 27 2007 Matthew Truch - 2.34-1 +- Upgrade to 2.34. +- Get rid of %%makeinstall (which was never needed). +- Possibly fix hotplug issuses (BZ 219750). +- Use %%python_sitelib for python site-files stuff. + +* Sat Dec 9 2006 Matthew Truch - 2.33-6 +- Rebuild to pull in new version of python. + +* Tue Sep 26 2006 Matthew Truch - 2.33-5 +- Remove openmotif requirment, and switch to lesstif. + +* Mon Aug 28 2006 Matthew Truch - 2.33-4 +- Bump release for rebuild in prep. for FC6. + +* Thu Jul 20 2006 Matthew Truch - 2.33-3 +- Actually, was a missing BR glib-dbus-devel. Ooops. + +* Thu Jul 20 2006 Matthew Truch - 2.33-2 +- Missing BR glib-devel + +* Thu Jul 20 2006 Matthew Truch - 2.33-1 +- Update to version 2.33 + +* Wed Apr 19 2006 Matthew Truch - 2.32-5 +- Don't --enable-tnt in build as it causes some gpses to not work + properly with sattelite view mode. See bugzilla bug 189220. + +* Thu Apr 13 2006 Matthew Truch - 2.32-4 +- Add dbus-glib to BuildRequires as needed for build. + +* Sun Apr 9 2006 Matthew Truch - 2.32-3 +- Include xmlto and python in buildrequires so things build right. +- Don't package static library file. + +* Wed Apr 5 2006 Matthew Truch - 2.32-2 +- Use ye olde %%{?dist} tag. + +* Wed Apr 5 2006 Matthew Truch - 2.32-1 +- Initial Fedora Extras specfile diff --git a/packaging/rpm/gpsd.spec.in b/packaging/rpm/gpsd.spec.in new file mode 100644 index 0000000..9b0aa89 --- /dev/null +++ b/packaging/rpm/gpsd.spec.in @@ -0,0 +1,370 @@ +%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} + +Name: gpsd +Version: @VERSION@ +Release: 3%{?dist} +Summary: Service daemon for mediating access to a GPS + +Group: System Environment/Daemons +License: BSD +URL: http://developer.berlios.de/projects/gpsd/ +Source0: http://download.berlios.de/gpsd/%{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +BuildRequires: dbus-devel dbus-glib-devel ncurses-devel xmlto python-devel +BuildRequires: libXaw-devel desktop-file-utils +BuildRequires: qt-devel + +Requires: udev +Requires(post): /sbin/ldconfig +Requires(post): /sbin/chkconfig +Requires(preun): initscripts +Requires(preun): /sbin/chkconfig +Requires(postun): /sbin/ldconfig + +%description +gpsd is a service daemon that mediates access to a GPS sensor +connected to the host computer by serial or USB interface, making its +data on the location/course/velocity of the sensor available to be +queried on TCP port 2947 of the host computer. With gpsd, multiple +GPS client applications (such as navigational and wardriving software) +can share access to a GPS without contention or loss of data. Also, +gpsd responds to queries with a format that is substantially easier to +parse than NMEA 0183. + +%package devel +Summary: Client libraries in C and Python for talking to a running gpsd or GPS +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: pkgconfig + +%description devel +This package provides C header files and python modules for the gpsd shared +libraries that manage access to a GPS for applications + +%package -n libQgpsmm +Summary: Qt Client libraries for talking to a running gpsd or GPS +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: qt +Requires: pkgconfig + +%description -n libQgpsmm +This package provides Qt shared libraries that manage access to a GPS +for Qt applications + +%package clients +Summary: Clients for gpsd +Group: Applications/System + +%description clients +xgps is a simple test client for gpsd with an X interface. It displays +current GPS position/time/velocity information and (for GPSes that +support the feature) the locations of accessible satellites. + +xgpsspeed is a speedometer that uses position information from the GPS. +It accepts an -h option and optional argument as for gps, or a -v option +to dump the package version and exit. Additionally, it accepts -rv +(reverse video) and -nc (needle color) options. + +cgps resembles xgps, but without the pictorial satellite display. It +can run on a serial terminal or terminal emulator. + +%prep +%setup -q + +%build +%configure \ + --enable-dbus \ + --disable-static +sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool +sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool + +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} +make DESTDIR=%{buildroot} pythondir=%{python_sitearch} install + +# init scripts +%{__install} -d -m 0755 %{buildroot}%{_sysconfdir}/init.d +%{__install} -p -m 0755 packaging/rpm/gpsd.init \ + %{buildroot}%{_sysconfdir}/init.d/gpsd + +%{__install} -d -m 0755 %{buildroot}%{_sysconfdir}/sysconfig +%{__install} -p -m 0644 packaging/rpm/gpsd.sysconfig \ + %{buildroot}%{_sysconfdir}/sysconfig/gpsd + +# udev rules +%{__install} -d -m 0755 %{buildroot}%{_sysconfdir}/udev/rules.d +%{__install} -p -m 0644 gpsd.rules \ + %{buildroot}%{_sysconfdir}/udev/rules.d/99-gpsd.rules + +# hotplug script +%{__install} -d -m 0755 %{buildroot}/lib/udev +%{__install} -p -m 0755 gpsd.hotplug gpsd.hotplug.wrapper \ + %{buildroot}/lib/udev + +# remove .la files +rm -f %{buildroot}%{_libdir}/libgps*.la + +# fix non-executable python script +%{__chmod} +x %{buildroot}%{python_sitearch}/gps/gps.py + +# Install the .desktop files +desktop-file-install --vendor fedora \ + --dir %{buildroot}%{_datadir}/applications \ + --add-category X-Fedora \ + packaging/X11/xgps.desktop +desktop-file-install --vendor fedora \ + --dir %{buildroot}%{_datadir}/applications \ + --add-category X-Fedora \ + packaging/X11/xgpsspeed.desktop + +# Install logo icon for .desktop files +%{__install} -d -m 0755 %{buildroot}%{_datadir}/gpsd +%{__install} -p -m 0644 packaging/X11/gpsd-logo.png %{buildroot}%{_datadir}/gpsd/gpsd-logo.png + +%clean +rm -rf %{buildroot} + +%post +/sbin/ldconfig +/sbin/chkconfig --add %{name} + +%preun +if [ $1 = 0 ]; then + /sbin/service %{name} stop > /dev/null 2>&1 || true + /sbin/chkconfig --del %{name} +fi + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +%doc README INSTALL COPYING +%config(noreplace) %{_sysconfdir}/init.d/%{name} +%config(noreplace) %{_sysconfdir}/sysconfig/%{name} +%config(noreplace) %{_sysconfdir}/udev/rules.d/* +%{_sbindir}/gpsd +%{_bindir}/gpsprof +%{_bindir}/gpsmon +%{_bindir}/gpsctl +%{_libdir}/libgps*.so.* +/lib/udev/gpsd* +%{python_sitearch}/gps* +%exclude %{python_sitearch}/gps/fake* +%{_mandir}/man8/gpsd.8* +%{_mandir}/man1/gpsprof.1* +%{_mandir}/man1/gpsmon.1* +%{_mandir}/man1/gpsctl.1* + +%files devel +%defattr(-,root,root,-) +%doc TODO +%{_bindir}/gpsfake +%{_libdir}/libgps*.so +%{_libdir}/pkgconfig/*.pc +%{python_sitearch}/gps/fake* +%{_includedir}/gps.h +%{_includedir}/libgpsmm.h +%{_includedir}/gpsd.h +%{_mandir}/man1/gpsfake.1* +%{_mandir}/man3/libgps.3* +%{_mandir}/man3/libgpsmm.3* +%{_mandir}/man3/libgpsd.3* +%{_mandir}/man5/rtcm-104.5* +%{_mandir}/man5/srec.5* + +%files -n libQgpsmm +%defattr(-,root,root,-) +%{_qt4_libdir}/libQgpsmm.so* + +%files clients +%defattr(-,root,root,-) +%{_bindir}/cgps +%{_bindir}/gpscat +%{_bindir}/gpsdecode +%{_bindir}/gpspipe +%{_bindir}/gpxlogger +%{_bindir}/lcdgps +%{_bindir}/xgps +%{_bindir}/xgpsspeed +%{_mandir}/man1/gps.1* +%{_mandir}/man1/gpsdecode.1* +%{_mandir}/man1/gpspipe.1* +%{_mandir}/man1/lcdgps.1* +%{_mandir}/man1/xgps.1* +%{_mandir}/man1/xgpsspeed.1* +%{_mandir}/man1/cgps.1* +%{_mandir}/man1/gpscat.1* +%{_datadir}/applications/*.desktop +%dir %{_datadir}/gpsd +%{_datadir}/gpsd/gpsd-logo.png + +%changelog +* Mon Jul 05 2010 Michael R. Davis - 2.95-3 +- Updated to move rpm files to packaging/rpm folder +- Renamed gpsd-qt to libQgpsmm + +* Sun Jul 04 2010 Michael R. Davis - 2.95-2 +- missing X11/app-defaults/xgpsspeed + +* Sat Jul 03 2010 Michael R. Davis - 2.95-1 +- back ported spec to gpsd from Fedora 14 +- updated to 2.95 +- added gpsd-qt package + +* Thu May 06 2010 Miroslav Lichvar - 2.94-1 +- update to 2.94 (#556642) + +* Tue Mar 02 2010 Miroslav Lichvar - 2.39-7 +- don't use deprecated SYSFS{} in udev rules (#569089) +- fix init script LSB compliance + +* Mon Feb 15 2010 Miroslav Lichvar - 2.39-6 +- fix linking with --no-add-needed (#564662) +- use %%global macro instead of %%define + +* Wed Aug 12 2009 Marek Mahut - 2.39-5 +- RHBZ#505588: gpsd has a broken initscript that fails to launch daemon + +* Fri Jul 24 2009 Fedora Release Engineering - 2.39-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Mar 31 2009 Tom "spot" Callaway - 2.39-3 +- some of the gpsd client bits went into gpsdclient.h, but that file wasn't getting installed + specifically, viking needs that header to build. + +* Wed Mar 25 2009 Douglas E. Warner - 2.39-2 +- adding patch to try to fix parallel make errors + +* Thu Mar 19 2009 Douglas E. Warner - 2.39-1 +- updating to 2.39 +- fixed potential core dump in C client handling of "K" responses +- Made device hotplugging work again; had been broken by changes in udev +- Introduced major and minor API version symbols into the public interfaces +- The sirfmon utility is gone, replaced by gpsmon which does the same job + for multiple GPS types +- Fixed a two-year old error in NMEA parsing that nobody noticed because its + only effect was to trash VDOP values from GSA sentences, and gpsd computes + those with an internal error model when they look wonky +- cgpxlogger has been merged into gpxlogger +- Speed-setting commands now allow parity and stop-bit setting if the GPS + chipset and adaptor can support it +- Specfile and other packaging paraphenalia now live in a packaging + subdirectory +- rtcmdecode becomes gpsdecode and can now de-armor and dump AIDVM packets +- The client library now work correctly in locales where the decimal separator + is not a period + +* Mon Mar 16 2009 Douglas E. Warner - 2.38-1 +- updating to 2.38 +- creating init script and sysconfig files +- migrating hotplug rules to udev + hotplug wrapper script from svn r5147 +- updating pyexecdir patch +- fixing udev rule subsystem match +- Regression test load for RoyalTek RGM3800 and Blumax GPS-009 added +- Scaling on E error-estimate fields fixed to match O +- Listen on localhost only by default to avoid security problems; this can be + overridden with the -G command-line option +- The packet-state machine can now recognize RTCM3 packets, though support is + not yet complete +- Added support for ublox5 and mkt-3301 devices +- Add a wrapper around gpsd_hexdump to save CPU +- Lots of little fixes to various packet parsers +- Always keep the device open: "-n" is not optional any more +- xgpsspeed no longer depends on Motif +- gpsctl can now ship arbitrary payloads to a device; + It's possible to send binary through the control channel with the + new "&" command +- Experimental new driver for Novatel SuperStarII +- The 'g' mode switch command now requires, and returns, 'rtcm104v2' rather + than 'rtcm104'; this is design forward for when RTCM104v2 is fully working + +* Tue Feb 24 2009 Fedora Release Engineering - 2.37-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Sat Nov 29 2008 Ignacio Vazquez-Abrams - 2.37-3 +- Rebuild for Python 2.6 + +* Wed Mar 19 2008 Douglas E. Warner - 2.37-2 +- moving gpspacket.so python lib to main package + +* Wed Feb 27 2008 Douglas E. Warner - 2.37-1 +- update to 2.37 +- removed install-gpsd_config.h.patch +- installed pkgconfig files in devel package +- added patch to install python modules in sitearch +- removing rpath from inclucded libtool +- moving X11 app-defaults to datadir +- using macros for commands in install; using install instead of cp and mkdir +- cleaning up spaces/tabs for rpmlint + +* Tue Feb 19 2008 Fedora Release Engineering - 2.34-9 +- Autorebuild for GCC 4.3 + +* Sun Aug 19 2007 Matthew Truch - 2.34-8 +- Patch Makefile to also install gpsd_config.h as needed by + libgpsmm.h. Redhat BZ 253433. + +* Sat Jun 30 2007 Matthew Truch - 2.34-7 +- Make sure the logo is actually included (via the spec file). + I need to wake up before I try even trivial updates. + +* Sat Jun 30 2007 Matthew Truch - 2.34-6 +- Learn how to use search and replace (aka fix all instances of + gpsd-logo.png spelled incorrectly as gspd-logo.png). + +* Sat Jun 30 2007 Matthew Truch - 2.34-5 +- Fix desktop file and logo file name. + +* Sat Jun 30 2007 Matthew Truch - 2.34-4 +- Include icon for .desktop files per BZ 241428 + +* Tue Mar 20 2007 Michael Schwendt - 2.34-3 +- Bump release for FE5 -> Fedora 7 upgrade path. + +* Tue Feb 27 2007 Matthew Truch - 2.34-2 +- BR python-devel instead of python to make it build. + +* Tue Feb 27 2007 Matthew Truch - 2.34-1 +- Upgrade to 2.34. +- Get rid of %%makeinstall (which was never needed). +- Possibly fix hotplug issuses (BZ 219750). +- Use %%python_sitelib for python site-files stuff. + +* Sat Dec 9 2006 Matthew Truch - 2.33-6 +- Rebuild to pull in new version of python. + +* Tue Sep 26 2006 Matthew Truch - 2.33-5 +- Remove openmotif requirment, and switch to lesstif. + +* Mon Aug 28 2006 Matthew Truch - 2.33-4 +- Bump release for rebuild in prep. for FC6. + +* Thu Jul 20 2006 Matthew Truch - 2.33-3 +- Actually, was a missing BR glib-dbus-devel. Ooops. + +* Thu Jul 20 2006 Matthew Truch - 2.33-2 +- Missing BR glib-devel + +* Thu Jul 20 2006 Matthew Truch - 2.33-1 +- Update to version 2.33 + +* Wed Apr 19 2006 Matthew Truch - 2.32-5 +- Don't --enable-tnt in build as it causes some gpses to not work + properly with sattelite view mode. See bugzilla bug 189220. + +* Thu Apr 13 2006 Matthew Truch - 2.32-4 +- Add dbus-glib to BuildRequires as needed for build. + +* Sun Apr 9 2006 Matthew Truch - 2.32-3 +- Include xmlto and python in buildrequires so things build right. +- Don't package static library file. + +* Wed Apr 5 2006 Matthew Truch - 2.32-2 +- Use ye olde %%{?dist} tag. + +* Wed Apr 5 2006 Matthew Truch - 2.32-1 +- Initial Fedora Extras specfile diff --git a/packaging/rpm/gpsd.sysconfig b/packaging/rpm/gpsd.sysconfig new file mode 100644 index 0000000..56d2e44 --- /dev/null +++ b/packaging/rpm/gpsd.sysconfig @@ -0,0 +1,3 @@ +OPTIONS="-n" +DEVICE="/dev/ttyUSB0" +USBAUTO="true" diff --git a/packet.c b/packet.c new file mode 100644 index 0000000..147a593 --- /dev/null +++ b/packet.c @@ -0,0 +1,1805 @@ +/**************************************************************************** + +NAME: + packet.c -- a packet-sniffing engine for reading from GPS devices + +DESCRIPTION: + +Initial conditions of the problem: + +1. We have a file descriptor open for (possibly non-blocking) read. The device + on the other end is sending packets at us. + +2. It may require more than one read to gather a packet. Reads may span packet + boundaries. + +3. There may be leading garbage before the first packet. After the first + start-of-packet, the input should be well-formed. + +The problem: how do we recognize which kind of packet we're getting? + +No need to handle Garmin USB binary, we know that type by the fact we're +connected to the Garmin kernel driver. But we need to be able to tell the +others apart and distinguish them from baud barf. + +PERMISSIONS + This file is Copyright (c) 2010 by the GPSD project + BSD terms apply: see the file COPYING in the distribution root for details. + +***************************************************************************/ +#include +#include "gpsd_config.h" +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#ifndef S_SPLINT_S +#ifdef HAVE_NETINET_IN_H +#include /* for htons() */ +#endif /* HAVE_NETNET_IN_H */ +#ifdef HAVE_ARPA_INET_H +#include /* for htons() */ +#endif /* HAVE_ARPA_INET_H */ +#endif /* S_SPLINT_S */ + +#include "bits.h" +#include "gpsd.h" +#include "crc24q.h" + +/* + * The packet-recognition state machine. This takes an incoming byte stream + * and tries to segment it into packets. There are three types of packets: + * + * 1) Comments. These begin with # and end with \r\n. + * + * 2) NMEA lines. These begin with $, and with \r\n, and have a checksum. + * + * 3) Binary packets. These begin with some fixed leader character(s), + * have a length embedded in them, and end with a checksum (and possibly) + * some fixed trailing bytes. + * + * 4) ISGPS packets. The input may be a bitstream containing IS-GPS-200 + * packets. Each includes a fixed leader byte, a length, and check bits. + * In this case, it is not guaranted that packet starts begin on byte + * bounaries; the recognizer has to run a separate state machine against + * each byte just to achieve synchronization lock with the bitstream. + * + * Adding support for a new GPS protocol typically reqires adding state + * transitions to support whatever binary packet structure it has. The + * goal is for the lexer to be able to cope with arbitrarily mixed packet + * types on the input stream. This is a requirement because (1) sometimes + * gpsd wants to switch a device that supports both NMEA and a binary + * packet protocol to the latter for more detailed reporting, and (b) in + * the presence of device hotplugging, the type of GPS report coming + * in is subject to change at any time. + * + * Caller should consume a packet when it sees one of the *_RECOGNIZED + * states. It's good practice to follow the _RECOGNIZED transition + * with one that recognizes a leader of the same packet type rather + * than dropping back to ground state -- this for example will prevent + * the state machine from hopping between recognizing TSIP and + * EverMore packets that both start with a DLE. + * + * Error handling is brutally simple; any time we see an unexpected + * character, go to GROUND_STATE and reset the machine (except that a + * $ in an NMEA payload only resets back to NMEA_DOLLAR state). Because + * another good packet will usually be along in less than a second + * repeating the same data, Boyer-Moore-like attempts to do parallel + * recognition beyond the headers would make no sense in this + * application, they'd just add complexity. + * + * The NMEA portion of the state machine allows the following talker IDs: + * GP -- Global Positioning System. + * GL -- GLONASS, according to IEIC 61162-1 + * GN -- Mixed GPS and GLONASS data, according to IEIC 61162-1 + * II -- Integrated Instrumentation (Raytheon's SeaTalk system). + * IN -- Integrated Navigation (Garmin uses this). + * + */ + +enum +{ +#include "packet_states.h" +}; + +#define SOH (unsigned char)0x01 +#define DLE (unsigned char)0x10 +#define STX (unsigned char)0x02 +#define ETX (unsigned char)0x03 + +static void character_pushback(struct gps_packet_t *lexer) +/* push back the last character grabbed */ +{ + /*@-modobserver@*//* looks like a splint bug */ + --lexer->inbufptr; + /*@+modobserver@*/ + --lexer->char_counter; + gpsd_report(LOG_RAW + 2, "%08ld: character pushed back\n", + lexer->char_counter); +} + +static void nextstate(struct gps_packet_t *lexer, unsigned char c) +{ +#ifdef RTCM104V2_ENABLE + enum isgpsstat_t isgpsstat; +#endif /* RTCM104V2_ENABLE */ +#ifdef SUPERSTAR2_ENABLE + static unsigned char ctmp; +#endif /* SUPERSTAR2_ENABLE */ +/*@ +charint -casebreak @*/ + switch (lexer->state) { + case GROUND_STATE: + if (c == '#') { + lexer->state = COMMENT_BODY; + break; + } +#ifdef NMEA_ENABLE + if (c == '$') { + lexer->state = NMEA_DOLLAR; + break; + } + if (c == '!') { + lexer->state = NMEA_BANG; + break; + } +#endif /* NMEA_ENABLE */ +#if defined(TNT_ENABLE) || defined(GARMINTXT_ENABLE) || defined(ONCORE_ENABLE) + if (c == '@') { + lexer->state = AT1_LEADER; + break; + } +#endif +#ifdef SIRF_ENABLE + if (c == 0xa0) { + lexer->state = SIRF_LEADER_1; + break; + } +#endif /* SIRF_ENABLE */ +#ifdef SUPERSTAR2_ENABLE + if (c == SOH) { + lexer->state = SUPERSTAR2_LEADER; + break; + } +#endif /* SUPERSTAR2_ENABLE */ +#if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(GARMIN_ENABLE) + if (c == DLE) { + lexer->state = DLE_LEADER; + break; + } +#endif /* TSIP_ENABLE || EVERMORE_ENABLE || GARMIN_ENABLE */ +#ifdef TRIPMATE_ENABLE + if (c == 'A') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = ASTRAL_1; + break; + } +#endif /* TRIPMATE_ENABLE */ +#ifdef EARTHMATE_ENABLE + if (c == 'E') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = EARTHA_1; + break; + } +#endif /* EARTHMATE_ENABLE */ +#ifdef ZODIAC_ENABLE + if (c == 0xff) { + lexer->state = ZODIAC_LEADER_1; + break; + } +#endif /* ZODIAC_ENABLE */ +#ifdef UBX_ENABLE + if (c == 0xb5) { + lexer->state = UBX_LEADER_1; + break; + } +#endif /* UBX_ENABLE */ +#ifdef ITRAX_ENABLE + if (c == '<') { + lexer->state = ITALK_LEADER_1; + break; + } +#endif /* ITRAX_ENABLE */ +#ifdef NAVCOM_ENABLE + if (c == 0x02) { + lexer->state = NAVCOM_LEADER_1; + break; + } +#endif /* NAVCOM_ENABLE */ +#ifdef RTCM104V2_ENABLE + if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_SYNC) { + lexer->state = RTCM2_SYNC_STATE; + break; + } else if (isgpsstat == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ +#ifdef RTCM104V3_ENABLE + if (c == 0xD3) { + lexer->state = RTCM3_LEADER_1; + break; + } +#endif /* RTCM104V3_ENABLE */ + break; + case COMMENT_BODY: + if (c == '\n') + lexer->state = COMMENT_RECOGNIZED; + else if (!isprint(c)) + lexer->state = GROUND_STATE; + break; +#ifdef NMEA_ENABLE + case NMEA_DOLLAR: + if (c == 'G') + lexer->state = NMEA_PUB_LEAD; + else if (c == 'P') /* vendor sentence */ + lexer->state = NMEA_VENDOR_LEAD; + else if (c == 'I') /* Seatalk */ + lexer->state = SEATALK_LEAD_1; + else if (c == 'A') /* SiRF Ack */ + lexer->state = SIRF_ACK_LEAD_1; +#ifdef OCEANSERVER_ENABLE + else if (c == 'C') + lexer->state = NMEA_LEADER_END; +#endif /* OCEANSERVER_ENABLE */ + else + lexer->state = GROUND_STATE; + break; + case NMEA_PUB_LEAD: + /* + * $GP == GPS, $GL = GLONASS only, $GN = mixed GPS and GLONASS, + * according to NMEA (IEIC 61162-1) DRAFT 02/06/2009. + */ + if (c == 'P' || c == 'N' || c == 'L') + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; + case NMEA_VENDOR_LEAD: + if (c == 'A') + lexer->state = NMEA_PASHR_A; + else if (isalpha(c)) + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; + /* + * Without the following six states, DLE in a $PASHR can fool the + * sniffer into thinking it sees a TSIP packet. Hilarity ensues. + */ + case NMEA_PASHR_A: + if (c == 'S') + lexer->state = NMEA_PASHR_S; + else if (isalpha(c)) + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; + case NMEA_PASHR_S: + if (c == 'H') + lexer->state = NMEA_PASHR_H; + else if (isalpha(c)) + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; + case NMEA_PASHR_H: + if (c == 'R') + lexer->state = NMEA_BINARY_BODY; + else if (isalpha(c)) + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; + case NMEA_BINARY_BODY: + if (c == '\r') + lexer->state = NMEA_BINARY_CR; + break; + case NMEA_BINARY_CR: + if (c == '\n') + lexer->state = NMEA_BINARY_NL; + else + lexer->state = NMEA_BINARY_BODY; + break; + case NMEA_BINARY_NL: + if (c == '$') { + character_pushback(lexer); + lexer->state = NMEA_RECOGNIZED; /* CRC will reject it */ + } else + lexer->state = NMEA_BINARY_BODY; + break; + case NMEA_BANG: + if (c == 'A') + lexer->state = AIS_LEAD_1; + else + lexer->state = GROUND_STATE; + break; + case AIS_LEAD_1: + if (c == 'I') + lexer->state = AIS_LEAD_2; + else + lexer->state = GROUND_STATE; + break; + case AIS_LEAD_2: + if (isalpha(c)) + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; +#if defined(TNT_ENABLE) || defined(GARMINTXT_ENABLE) || defined(ONCORE_ENABLE) + case AT1_LEADER: + switch (c) { +#ifdef ONCORE_ENABLE + case '@': + lexer->state = ONCORE_AT2; + break; +#endif /* ONCORE_ENABLE */ +#ifdef TNT_ENABLE + case '*': + /* + * TNT has similar structure to NMEA packet, '*' before + * optional checksum ends the packet. Since '*' cannot be + * received from GARMIN working in TEXT mode, use this + * difference to tell that this is not GARMIN TEXT packet, + * could be TNT. + */ + lexer->state = NMEA_LEADER_END; + break; +#endif /* TNT_ENABLE */ +#if defined(GARMINTXT_ENABLE) + case '\r': + /* stay in this state, next character should be '\n' */ + /* in the theory we can stop search here and don't wait for '\n' */ + lexer->state = AT1_LEADER; + break; + case '\n': + /* end of packet found */ + lexer->state = GTXT_RECOGNIZED; + break; +#endif /* GARMINTXT_ENABLE */ + default: + if (!isprint(c)) + lexer->state = GROUND_STATE; + } + break; +#endif /* defined(TNT_ENABLE) || defined(GARMINTXT_ENABLE) || defined(ONCORE_ENABLE) */ + case NMEA_LEADER_END: + if (c == '\r') + lexer->state = NMEA_CR; + else if (c == '\n') + /* not strictly correct, but helps for interpreting logfiles */ + lexer->state = NMEA_RECOGNIZED; + else if (c == '$') + /* faster recovery from missing sentence trailers */ + lexer->state = NMEA_DOLLAR; + else if (!isprint(c)) + lexer->state = GROUND_STATE; + break; + case NMEA_CR: + if (c == '\n') + lexer->state = NMEA_RECOGNIZED; + /* + * There's a GPS called a Jackson Labs Firefly-1a that emits \r\r\n + * at the end of each sentence. Don't be confused by this. + */ + else if (c == '\r') + lexer->state = NMEA_CR; + else + lexer->state = GROUND_STATE; + break; + case NMEA_RECOGNIZED: + if (c == '#') + lexer->state = COMMENT_BODY; + else if (c == '$') + lexer->state = NMEA_DOLLAR; + else if (c == '!') + lexer->state = NMEA_BANG; +#ifdef UBX_ENABLE + else if (c == 0xb5) /* LEA-5H can and will output NMEA and UBX back to back */ + lexer->state = UBX_LEADER_1; +#endif + else + lexer->state = GROUND_STATE; + break; + case SEATALK_LEAD_1: + if (c == 'I' || c == 'N') /* II or IN are accepted */ + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; +#ifdef TRIPMATE_ENABLE + case ASTRAL_1: + if (c == 'S') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = ASTRAL_2; + } else + lexer->state = GROUND_STATE; + break; + case ASTRAL_2: + if (c == 'T') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = ASTRAL_3; + } else + lexer->state = GROUND_STATE; + break; + case ASTRAL_3: + if (c == 'R') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = ASTRAL_5; + } else + lexer->state = GROUND_STATE; + break; + case ASTRAL_4: + if (c == 'A') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = ASTRAL_2; + } else + lexer->state = GROUND_STATE; + break; + case ASTRAL_5: + if (c == 'L') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = NMEA_RECOGNIZED; + } else + lexer->state = GROUND_STATE; + break; +#endif /* TRIPMATE_ENABLE */ +#ifdef EARTHMATE_ENABLE + case EARTHA_1: + if (c == 'A') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = EARTHA_2; + } else + lexer->state = GROUND_STATE; + break; + case EARTHA_2: + if (c == 'R') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = EARTHA_3; + } else + lexer->state = GROUND_STATE; + break; + case EARTHA_3: + if (c == 'T') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = EARTHA_4; + } else + lexer->state = GROUND_STATE; + break; + case EARTHA_4: + if (c == 'H') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = EARTHA_5; + } else + lexer->state = GROUND_STATE; + break; + case EARTHA_5: + if (c == 'A') { +#ifdef RTCM104V2_ENABLE + if (rtcm2_decode(lexer, c) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } +#endif /* RTCM104V2_ENABLE */ + lexer->state = NMEA_RECOGNIZED; + } else + lexer->state = GROUND_STATE; + break; +#endif /* EARTHMATE_ENABLE */ + case SIRF_ACK_LEAD_1: + if (c == 'c') + lexer->state = SIRF_ACK_LEAD_2; + else if (c == 'I') + lexer->state = AIS_LEAD_2; + else + lexer->state = GROUND_STATE; + break; + case SIRF_ACK_LEAD_2: + if (c == 'k') + lexer->state = NMEA_LEADER_END; + else + lexer->state = GROUND_STATE; + break; +#endif /* NMEA_ENABLE */ +#ifdef SIRF_ENABLE + case SIRF_LEADER_1: + if (c == 0xa2) + lexer->state = SIRF_LEADER_2; + else + lexer->state = GROUND_STATE; + break; + case SIRF_LEADER_2: + lexer->length = (size_t) (c << 8); + lexer->state = SIRF_LENGTH_1; + break; + case SIRF_LENGTH_1: + lexer->length += c + 2; + if (lexer->length <= MAX_PACKET_LENGTH) + lexer->state = SIRF_PAYLOAD; + else + lexer->state = GROUND_STATE; + break; + case SIRF_PAYLOAD: + if (--lexer->length == 0) + lexer->state = SIRF_DELIVERED; + break; + case SIRF_DELIVERED: + if (c == 0xb0) + lexer->state = SIRF_TRAILER_1; + else + lexer->state = GROUND_STATE; + break; + case SIRF_TRAILER_1: + if (c == 0xb3) + lexer->state = SIRF_RECOGNIZED; + else + lexer->state = GROUND_STATE; + break; + case SIRF_RECOGNIZED: + if (c == 0xa0) + lexer->state = SIRF_LEADER_1; + else + lexer->state = GROUND_STATE; + break; +#endif /* SIRF_ENABLE */ +#ifdef SUPERSTAR2_ENABLE + case SUPERSTAR2_LEADER: + ctmp = c; + lexer->state = SUPERSTAR2_ID1; + break; + case SUPERSTAR2_ID1: + if ((ctmp ^ 0xff) == c) + lexer->state = SUPERSTAR2_ID2; + else + lexer->state = GROUND_STATE; + break; + case SUPERSTAR2_ID2: + lexer->length = (size_t) c; /* how many data bytes follow this byte */ + if (lexer->length) + lexer->state = SUPERSTAR2_PAYLOAD; + else + lexer->state = SUPERSTAR2_CKSUM1; /* no data, jump to checksum */ + break; + case SUPERSTAR2_PAYLOAD: + if (--lexer->length == 0) + lexer->state = SUPERSTAR2_CKSUM1; + break; + case SUPERSTAR2_CKSUM1: + lexer->state = SUPERSTAR2_CKSUM2; + break; + case SUPERSTAR2_CKSUM2: + lexer->state = SUPERSTAR2_RECOGNIZED; + break; + case SUPERSTAR2_RECOGNIZED: + if (c == SOH) + lexer->state = SUPERSTAR2_LEADER; + else + lexer->state = GROUND_STATE; + break; +#endif /* SUPERSTAR2_ENABLE */ +#ifdef ONCORE_ENABLE + case ONCORE_AT2: + if (isupper(c)) { + lexer->length = (size_t) c; + lexer->state = ONCORE_ID1; + } else + lexer->state = GROUND_STATE; + break; + case ONCORE_ID1: + if (isalpha(c)) { + lexer->length = + oncore_payload_cksum_length((unsigned char)lexer->length, c); + if (lexer->length != 0) { + lexer->state = ONCORE_PAYLOAD; + break; + } + } + lexer->state = GROUND_STATE; + break; + case ONCORE_PAYLOAD: + if (--lexer->length == 0) + lexer->state = ONCORE_CHECKSUM; + break; + case ONCORE_CHECKSUM: + if (c != '\r') + lexer->state = GROUND_STATE; + else + lexer->state = ONCORE_CR; + break; + case ONCORE_CR: + if (c == '\n') + lexer->state = ONCORE_RECOGNIZED; + else + lexer->state = ONCORE_PAYLOAD; + break; + case ONCORE_RECOGNIZED: + if (c == '@') + lexer->state = AT1_LEADER; + else + lexer->state = GROUND_STATE; + break; +#endif /* ONCORE_ENABLE */ +#if defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(GARMIN_ENABLE) + case DLE_LEADER: +#ifdef EVERMORE_ENABLE + if (c == STX) { + lexer->state = EVERMORE_LEADER_2; + break; + } +#endif /* EVERMORE_ENABLE */ +#if defined(TSIP_ENABLE) || defined(GARMIN_ENABLE) || defined(NAVCOM_ENABLE) + /* garmin is special case of TSIP */ + /* check last because there's no checksum */ +#if defined(TSIP_ENABLE) + if (c >= 0x13) { + lexer->state = TSIP_PAYLOAD; + break; + } +#endif /* TSIP_ENABLE */ + if (c == DLE) { + lexer->state = GROUND_STATE; + break; + } + // FALL-THRU!!!!! no break here +#endif /* TSIP_ENABLE */ +#ifdef NAVCOM_ENABLE + case NAVCOM_LEADER_1: + if (c == 0x99) + lexer->state = NAVCOM_LEADER_2; + else + lexer->state = GROUND_STATE; + break; + case NAVCOM_LEADER_2: + if (c == 0x66) + lexer->state = NAVCOM_LEADER_3; + else + lexer->state = GROUND_STATE; + break; + case NAVCOM_LEADER_3: + lexer->state = NAVCOM_ID; + break; + case NAVCOM_ID: + lexer->length = (size_t) c - 4; + lexer->state = NAVCOM_LENGTH_1; + break; + case NAVCOM_LENGTH_1: + lexer->length += (c << 8); + lexer->state = NAVCOM_LENGTH_2; + break; + case NAVCOM_LENGTH_2: + if (--lexer->length == 0) + lexer->state = NAVCOM_PAYLOAD; + break; + case NAVCOM_PAYLOAD: + { + unsigned int n; + unsigned char csum = lexer->inbuffer[3]; + for (n = 4; + (unsigned char *)(lexer->inbuffer + n) < lexer->inbufptr - 1; + n++) + csum ^= lexer->inbuffer[n]; + if (csum != c) { + gpsd_report(LOG_IO, + "Navcom packet type 0x%hx bad checksum 0x%hx, expecting 0x%hx\n", + lexer->inbuffer[3], csum, c); + gpsd_report(LOG_RAW, "Navcom packet dump: %s\n", + gpsd_hexdump_wrapper(lexer->inbuffer, lexer->inbuflen, + LOG_RAW)); + lexer->state = GROUND_STATE; + break; + } + } + lexer->state = NAVCOM_CSUM; + break; + case NAVCOM_CSUM: + if (c == 0x03) + lexer->state = NAVCOM_RECOGNIZED; + else + lexer->state = GROUND_STATE; + break; + case NAVCOM_RECOGNIZED: + if (c == 0x02) + lexer->state = NAVCOM_LEADER_1; + else + lexer->state = GROUND_STATE; + break; +#endif /* NAVCOM_ENABLE */ +#endif /* TSIP_ENABLE || EVERMORE_ENABLE || GARMIN_ENABLE */ +#ifdef RTCM104V3_ENABLE + case RTCM3_LEADER_1: + if ((c & 0xFC) == 0) { + lexer->length = (size_t) (c << 8); + lexer->state = RTCM3_LEADER_2; + break; + } else + lexer->state = GROUND_STATE; + break; + case RTCM3_LEADER_2: + lexer->length |= c; + lexer->length += 3; /* to get the three checksum bytes */ + lexer->state = RTCM3_PAYLOAD; + break; + case RTCM3_PAYLOAD: + if (--lexer->length == 0) + lexer->state = RTCM3_RECOGNIZED; + break; +#endif /* RTCM104V3_ENABLE */ +#ifdef ZODIAC_ENABLE + case ZODIAC_EXPECTED: + case ZODIAC_RECOGNIZED: + if (c == 0xff) + lexer->state = ZODIAC_LEADER_1; + else + lexer->state = GROUND_STATE; + break; + case ZODIAC_LEADER_1: + if (c == 0x81) + lexer->state = ZODIAC_LEADER_2; + else + lexer->state = GROUND_STATE; + break; + case ZODIAC_LEADER_2: + lexer->state = ZODIAC_ID_1; + break; + case ZODIAC_ID_1: + lexer->state = ZODIAC_ID_2; + break; + case ZODIAC_ID_2: + lexer->length = (size_t) c; + lexer->state = ZODIAC_LENGTH_1; + break; + case ZODIAC_LENGTH_1: + lexer->length += (c << 8); + lexer->state = ZODIAC_LENGTH_2; + break; + case ZODIAC_LENGTH_2: + lexer->state = ZODIAC_FLAGS_1; + break; + case ZODIAC_FLAGS_1: + lexer->state = ZODIAC_FLAGS_2; + break; + case ZODIAC_FLAGS_2: + lexer->state = ZODIAC_HSUM_1; + break; + case ZODIAC_HSUM_1: + { +#define getword(i) (short)(lexer->inbuffer[2*(i)] | (lexer->inbuffer[2*(i)+1] << 8)) + short sum = getword(0) + getword(1) + getword(2) + getword(3); + sum *= -1; + if (sum != getword(4)) { + gpsd_report(LOG_IO, + "Zodiac Header checksum 0x%hx expecting 0x%hx\n", + sum, getword(4)); + lexer->state = GROUND_STATE; + break; + } + } + gpsd_report(LOG_RAW + 1, "Zodiac header id=%hd len=%hd flags=%hx\n", + getword(1), getword(2), getword(3)); +#undef getword + if (lexer->length == 0) { + lexer->state = ZODIAC_RECOGNIZED; + break; + } + lexer->length *= 2; /* word count to byte count */ + lexer->length += 2; /* checksum */ + /* 10 bytes is the length of the Zodiac header */ + if (lexer->length <= MAX_PACKET_LENGTH - 10) + lexer->state = ZODIAC_PAYLOAD; + else + lexer->state = GROUND_STATE; + break; + case ZODIAC_PAYLOAD: + if (--lexer->length == 0) + lexer->state = ZODIAC_RECOGNIZED; + break; +#endif /* ZODIAC_ENABLE */ +#ifdef UBX_ENABLE + case UBX_LEADER_1: + if (c == 0x62) + lexer->state = UBX_LEADER_2; + else + lexer->state = GROUND_STATE; + break; + case UBX_LEADER_2: + lexer->state = UBX_CLASS_ID; + break; + case UBX_CLASS_ID: + lexer->state = UBX_MESSAGE_ID; + break; + case UBX_MESSAGE_ID: + lexer->length = (size_t) c; + lexer->state = UBX_LENGTH_1; + break; + case UBX_LENGTH_1: + lexer->length += (c << 8); + if (lexer->length <= MAX_PACKET_LENGTH) + lexer->state = UBX_LENGTH_2; + else + lexer->state = GROUND_STATE; + break; + case UBX_LENGTH_2: + lexer->state = UBX_PAYLOAD; + break; + case UBX_PAYLOAD: + if (--lexer->length == 0) + lexer->state = UBX_CHECKSUM_A; + /* else stay in payload state */ + break; + case UBX_CHECKSUM_A: + lexer->state = UBX_RECOGNIZED; + break; + case UBX_RECOGNIZED: + if (c == 0xb5) + lexer->state = UBX_LEADER_1; +#ifdef NMEA_ENABLE + else if (c == '$') /* LEA-5H can and will output NMEA and UBX back to back */ + lexer->state = NMEA_DOLLAR; +#endif /* NMEA_ENABLE */ + else + lexer->state = GROUND_STATE; + break; +#endif /* UBX_ENABLE */ +#ifdef EVERMORE_ENABLE + case EVERMORE_LEADER_1: + if (c == STX) + lexer->state = EVERMORE_LEADER_2; + else + lexer->state = GROUND_STATE; + break; + case EVERMORE_LEADER_2: + lexer->length = (size_t) c; + if (c == DLE) + lexer->state = EVERMORE_PAYLOAD_DLE; + else + lexer->state = EVERMORE_PAYLOAD; + break; + case EVERMORE_PAYLOAD: + if (c == DLE) + lexer->state = EVERMORE_PAYLOAD_DLE; + else if (--lexer->length == 0) + lexer->state = GROUND_STATE; + break; + case EVERMORE_PAYLOAD_DLE: + switch (c) { + case DLE: + lexer->state = EVERMORE_PAYLOAD; + break; + case ETX: + lexer->state = EVERMORE_RECOGNIZED; + break; + default: + lexer->state = GROUND_STATE; + } + break; + case EVERMORE_RECOGNIZED: + if (c == DLE) + lexer->state = EVERMORE_LEADER_1; + else + lexer->state = GROUND_STATE; + break; +#endif /* EVERMORE_ENABLE */ +#ifdef ITRAX_ENABLE + case ITALK_LEADER_1: + if (c == '!') + lexer->state = ITALK_LEADER_2; + else + lexer->state = GROUND_STATE; + break; + case ITALK_LEADER_2: + lexer->length = (size_t) (lexer->inbuffer[6] & 0xff); + lexer->state = ITALK_LENGTH; + break; + case ITALK_LENGTH: + lexer->length += 1; /* fix number of words in payload */ + lexer->length *= 2; /* convert to number of bytes */ + lexer->length += 3; /* add trailer length */ + lexer->state = ITALK_PAYLOAD; + break; + case ITALK_PAYLOAD: + /* lookahead for "') && (lexer->inbufptr[0] == '<') && + (lexer->inbufptr[1] == '!')) { + lexer->state = ITALK_RECOGNIZED; + gpsd_report(LOG_IO, "ITALK: trying to process runt packet\n"); + break; + } else if (--lexer->length == 0) + lexer->state = ITALK_DELIVERED; + break; + case ITALK_DELIVERED: + if (c == '>') + lexer->state = ITALK_RECOGNIZED; + else + lexer->state = GROUND_STATE; + break; + case ITALK_RECOGNIZED: + if (c == '<') + lexer->state = ITALK_LEADER_1; + else + lexer->state = GROUND_STATE; + break; +#endif /* ITRAX_ENABLE */ +#ifdef TSIP_ENABLE + case TSIP_LEADER: + /* unused case */ + if (c >= 0x13) + lexer->state = TSIP_PAYLOAD; + else + lexer->state = GROUND_STATE; + break; + case TSIP_PAYLOAD: + if (c == DLE) + lexer->state = TSIP_DLE; + break; + case TSIP_DLE: + switch (c) { + case ETX: + lexer->state = TSIP_RECOGNIZED; + break; + case DLE: + lexer->state = TSIP_PAYLOAD; + break; + default: + lexer->state = GROUND_STATE; + break; + } + break; + case TSIP_RECOGNIZED: + if (c == DLE) + /* + * Don't go to TSIP_LEADER state -- TSIP packets aren't + * checksummed, so false positives are easy. We might be + * looking at another DLE-stuffed protocol like EverMore + * or Garmin streaming binary. + */ + lexer->state = DLE_LEADER; + else + lexer->state = GROUND_STATE; + break; +#endif /* TSIP_ENABLE */ +#ifdef RTCM104V2_ENABLE + case RTCM2_SYNC_STATE: + case RTCM2_SKIP_STATE: + if ((isgpsstat = rtcm2_decode(lexer, c)) == ISGPS_MESSAGE) { + lexer->state = RTCM2_RECOGNIZED; + break; + } else if (isgpsstat == ISGPS_NO_SYNC) + lexer->state = GROUND_STATE; + break; + + case RTCM2_RECOGNIZED: + if (rtcm2_decode(lexer, c) == ISGPS_SYNC) { + lexer->state = RTCM2_SYNC_STATE; + break; + } else + lexer->state = GROUND_STATE; + break; +#endif /* RTCM104V2_ENABLE */ + } +/*@ -charint +casebreak @*/ +} + +#define STATE_DEBUG + +static void packet_accept(struct gps_packet_t *lexer, int packet_type) +/* packet grab succeeded, move to output buffer */ +{ + size_t packetlen = lexer->inbufptr - lexer->inbuffer; + if (packetlen < sizeof(lexer->outbuffer)) { + memcpy(lexer->outbuffer, lexer->inbuffer, packetlen); + lexer->outbuflen = packetlen; + lexer->outbuffer[packetlen] = '\0'; + lexer->type = packet_type; +#ifdef STATE_DEBUG + gpsd_report(LOG_RAW + 1, "Packet type %d accepted %zu = %s\n", + packet_type, packetlen, + gpsd_hexdump_wrapper(lexer->outbuffer, lexer->outbuflen, + LOG_IO)); +#endif /* STATE_DEBUG */ + } else { + gpsd_report(LOG_ERROR, "Rejected too long packet type %d len %zu\n", + packet_type, packetlen); + } +} + +static void packet_discard(struct gps_packet_t *lexer) +/* shift the input buffer to discard all data up to current input pointer */ +{ + size_t discard = lexer->inbufptr - lexer->inbuffer; + size_t remaining = lexer->inbuflen - discard; + lexer->inbufptr = memmove(lexer->inbuffer, lexer->inbufptr, remaining); + lexer->inbuflen = remaining; +#ifdef STATE_DEBUG + gpsd_report(LOG_RAW + 1, + "Packet discard of %zu, chars remaining is %zu = %s\n", + discard, remaining, + gpsd_hexdump_wrapper(lexer->inbuffer, lexer->inbuflen, + LOG_RAW)); +#endif /* STATE_DEBUG */ +} + +static void character_discard(struct gps_packet_t *lexer) +/* shift the input buffer to discard one character and reread data */ +{ + memmove(lexer->inbuffer, lexer->inbuffer + 1, (size_t)-- lexer->inbuflen); + lexer->inbufptr = lexer->inbuffer; +#ifdef STATE_DEBUG + gpsd_report(LOG_RAW + 1, "Character discarded, buffer %zu chars = %s\n", + lexer->inbuflen, + gpsd_hexdump_wrapper(lexer->inbuffer, lexer->inbuflen, + LOG_RAW)); +#endif /* STATE_DEBUG */ +} + +/* get 0-origin big-endian words relative to start of packet buffer */ +#define getword(i) (short)(lexer->inbuffer[2*(i)] | (lexer->inbuffer[2*(i)+1] << 8)) + +/* entry points begin here */ + +void packet_init( /*@out@*/ struct gps_packet_t *lexer) +{ + lexer->char_counter = 0; + lexer->retry_counter = 0; + packet_reset(lexer); +} + +void packet_parse(struct gps_packet_t *lexer) +/* grab a packet from the input buffer */ +{ + lexer->outbuflen = 0; + while (packet_buffered_input(lexer) > 0) { + /*@ -modobserver @*/ + unsigned char c = *lexer->inbufptr++; + /*@ +modobserver @*/ + char *state_table[] = { +#include "packet_names.h" + }; + nextstate(lexer, c); + gpsd_report(LOG_RAW + 2, + "%08ld: character '%c' [%02x], new state: %s\n", + lexer->char_counter, (isprint(c) ? c : '.'), c, + state_table[lexer->state]); + lexer->char_counter++; + + if (lexer->state == GROUND_STATE) { + character_discard(lexer); + } else if (lexer->state == COMMENT_RECOGNIZED) { + packet_accept(lexer, COMMENT_PACKET); + packet_discard(lexer); + lexer->state = GROUND_STATE; + break; + } +#ifdef NMEA_ENABLE + else if (lexer->state == NMEA_RECOGNIZED) { + bool checksum_ok = true; + char csum[3] = { '0', '0', '0' }; + char *end; + /* + * Back up past any whitespace. Need to do this because + * at least one GPS (the Firefly 1a) emits \r\r\n + */ + for (end = (char *)lexer->inbufptr - 1; isspace(*end); end--) + continue; + while (strchr("0123456789ABCDEF", *end)) + --end; + if (*end == '*') { + unsigned int n, crc = 0; + for (n = 1; (char *)lexer->inbuffer + n < end; n++) + crc ^= lexer->inbuffer[n]; + (void)snprintf(csum, sizeof(csum), "%02X", crc); + checksum_ok = (csum[0] == toupper(end[1]) + && csum[1] == toupper(end[2])); + } + if (checksum_ok) { +#ifdef AIVDM_ENABLE + if (strncmp((char *)lexer->inbuffer, "!AIVDM", 6) == 0) + packet_accept(lexer, AIVDM_PACKET); + else +#endif /* AIVDM_ENABLE */ + packet_accept(lexer, NMEA_PACKET); + } else { + gpsd_report(LOG_WARN, + "bad checksum in NMEA packet; expected %s.\n", + csum); + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + } + packet_discard(lexer); + break; + } +#endif /* NMEA_ENABLE */ +#ifdef SIRF_ENABLE + else if (lexer->state == SIRF_RECOGNIZED) { + unsigned char *trailer = lexer->inbufptr - 4; + unsigned int checksum = + (unsigned)((trailer[0] << 8) | trailer[1]); + unsigned int n, crc = 0; + for (n = 4; n < (unsigned)(trailer - lexer->inbuffer); n++) + crc += (int)lexer->inbuffer[n]; + crc &= 0x7fff; + if (checksum == crc) + packet_accept(lexer, SIRF_PACKET); + else { + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + } + packet_discard(lexer); + break; + } +#endif /* SIRF_ENABLE */ +#ifdef SUPERSTAR2_ENABLE + else if (lexer->state == SUPERSTAR2_RECOGNIZED) { + unsigned a = 0, b; + size_t n; + lexer->length = 4 + (size_t) lexer->inbuffer[3] + 2; + for (n = 0; n < lexer->length - 2; n++) + a += (unsigned)lexer->inbuffer[n]; + b = (unsigned)getleuw(lexer->inbuffer, lexer->length - 2); + gpsd_report(LOG_IO, "SuperStarII pkt dump: type %u len %u: %s\n", + lexer->inbuffer[1], (unsigned int)lexer->length, + gpsd_hexdump_wrapper(lexer->inbuffer, lexer->length, + LOG_RAW)); + if (a != b) { + gpsd_report(LOG_IO, "REJECT SuperStarII packet type 0x%02x" + "%zd bad checksum 0x%04x, expecting 0x%04x\n", + lexer->inbuffer[1], lexer->length, a, b); + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + } else { + packet_accept(lexer, SUPERSTAR2_PACKET); + } + packet_discard(lexer); + break; + } +#endif /* SUPERSTAR2_ENABLE */ +#ifdef ONCORE_ENABLE + else if (lexer->state == ONCORE_RECOGNIZED) { + char a, b; + int i, len; + + len = lexer->inbufptr - lexer->inbuffer; + a = (char)(lexer->inbuffer[len - 3]); + b = '\0'; + for (i = 2; i < len - 3; i++) + b ^= lexer->inbuffer[i]; + if (a == b) { + gpsd_report(LOG_IO, "Accept OnCore packet @@%c%c len %d\n", + lexer->inbuffer[2], lexer->inbuffer[3], len); + packet_accept(lexer, ONCORE_PACKET); + } else { + gpsd_report(LOG_IO, "REJECT OnCore packet @@%c%c len %d\n", + lexer->inbuffer[2], lexer->inbuffer[3], len); + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + } + packet_discard(lexer); + break; + } +#endif /* ONCORE_ENABLE */ +#if defined(TSIP_ENABLE) || defined(GARMIN_ENABLE) + else if (lexer->state == TSIP_RECOGNIZED) { + size_t packetlen = lexer->inbufptr - lexer->inbuffer; +#ifdef TSIP_ENABLE + unsigned int pos, dlecnt; + /* don't count stuffed DLEs in the length */ + dlecnt = 0; + for (pos = 0; pos < (unsigned int)packetlen; pos++) + if (lexer->inbuffer[pos] == DLE) + dlecnt++; + if (dlecnt > 2) { + dlecnt -= 2; + dlecnt /= 2; + gpsd_report(LOG_RAW, "Unstuffed %d DLEs\n", dlecnt); + packetlen -= dlecnt; + } +#endif /* TSIP_ENABLE */ + if (packetlen < 5) { + lexer->state = GROUND_STATE; + } else { + unsigned int pkt_id, len; + size_t n; +#ifdef GARMIN_ENABLE + unsigned int ch, chksum; + n = 0; + /*@ +charint */ +#ifdef TSIP_ENABLE + /* shortcut garmin */ + if (TSIP_PACKET == lexer->type) + goto not_garmin; +#endif /* TSIP_ENABLE */ + if (lexer->inbuffer[n++] != DLE) + goto not_garmin; + pkt_id = lexer->inbuffer[n++]; /* packet ID */ + len = lexer->inbuffer[n++]; + chksum = len + pkt_id; + if (len == DLE) { + if (lexer->inbuffer[n++] != DLE) + goto not_garmin; + } + for (; len > 0; len--) { + chksum += lexer->inbuffer[n]; + if (lexer->inbuffer[n++] == DLE) { + if (lexer->inbuffer[n++] != DLE) + goto not_garmin; + } + } + /* check sum byte */ + ch = lexer->inbuffer[n++]; + chksum += ch; + if (ch == DLE) { + if (lexer->inbuffer[n++] != DLE) + goto not_garmin; + } + if (lexer->inbuffer[n++] != DLE) + goto not_garmin; + if (lexer->inbuffer[n++] != ETX) + goto not_garmin; + /*@ +charint */ + chksum &= 0xff; + if (chksum) { + gpsd_report(LOG_IO, + "Garmin checksum failed: %02x!=0\n", chksum); + goto not_garmin; + } + /* Debug + * gpsd_report(LOG_IO, "Garmin n= %#02x\n %s\n", n, + * gpsd_hexdump_wrapper(lexer->inbuffer, packetlen, LOG_IO)); + */ + packet_accept(lexer, GARMIN_PACKET); + packet_discard(lexer); + break; + not_garmin:; + gpsd_report(LOG_RAW + 1, "Not a Garmin packet\n"); +#endif /* GARMIN_ENABLE */ +#ifdef TSIP_ENABLE + /* check for some common TSIP packet types: + * 0x13, TSIP Parsing Error Notification + * 0x41, GPS time, data length 10 + * 0x42, Single Precision Fix, data length 16 + * 0x43, Velocity Fix, data length 20 + * 0x45, Software Version Information, data length 10 + * 0x46, Health of Receiver, data length 2 + * 0x48, GPS System Messages + * 0x49, Almanac Health Page + * 0x4a, LLA Position, data length 20 + * 0x4b, Machine Code Status, data length 3 + * 0x4c, Operating Parameters Report + * 0x54, One Satellite Bias + * 0x56, Velocity Fix (ENU), data length 20 + * 0x57, Last Computed Fix Report + * 0x5a, Raw Measurements + * 0x5b, Satellite Ephemeris Status + * 0x5c, Satellite Tracking Status, data length 24 + * 0x5e, Additional Fix Status Report + * 0x6d, All-In-View Satellite Selection, data length 16+numSV + * 0x82, Differential Position Fix Mode, data length 1 + * 0x83, Double Precision XYZ, data length 36 + * 0x84, Double Precision LLA, data length 36 + * 0xbb, GPS Navigation Configuration + * 0xbc, Receiver Port Configuration + * + * [pkt id] [data] + */ + /*@ +charint @*/ + pkt_id = lexer->inbuffer[1]; /* packet ID */ + /* *INDENT-OFF* */ + if (!((0x13 == pkt_id) || (0xbb == pkt_id) || (0xbc == pkt_id)) + && ((0x41 > pkt_id) || (0x8f < pkt_id))) { + gpsd_report(LOG_IO, + "Packet ID 0x%02x out of range for TSIP\n", + pkt_id); + goto not_tsip; + } + /* *INDENT-ON* */ + /*@ -ifempty */ + if ((0x13 == pkt_id) && (0x01 <= packetlen)) + /* pass */ ; + else if ((0x41 == pkt_id) + && ((0x0e == packetlen) || (0x0f == packetlen))) + /* pass */ ; + else if ((0x42 == pkt_id) && (0x14 == packetlen)) + /* pass */ ; + else if ((0x43 == pkt_id) && (0x18 == packetlen)) + /* pass */ ; + else if ((0x45 == pkt_id) && (0x0e == packetlen)) + /* pass */ ; + else if ((0x46 == pkt_id) && (0x06 == packetlen)) + /* pass */ ; + else if ((0x48 == pkt_id) && (0x1a == packetlen)) + /* pass */ ; + else if ((0x49 == pkt_id) && (0x24 == packetlen)) + /* pass */ ; + else if ((0x4a == pkt_id) && (0x18 == packetlen)) + /* pass */ ; + else if ((0x4b == pkt_id) && (0x07 == packetlen)) + /* pass */ ; + else if ((0x4c == pkt_id) && (0x15 == packetlen)) + /* pass */ ; + else if ((0x54 == pkt_id) && (0x10 == packetlen)) + /* pass */ ; + else if ((0x55 == pkt_id) && (0x08 == packetlen)) + /* pass */ ; + else if ((0x56 == pkt_id) && (0x18 == packetlen)) + /* pass */ ; + else if ((0x57 == pkt_id) && (0x0c == packetlen)) + /* pass */ ; + else if ((0x5a == pkt_id) + && ((0x1d <= packetlen) && (0x1f >= packetlen))) + /* pass */ ; + else if ((0x5b == pkt_id) && (0x24 == packetlen)) + /* pass */ ; + else if ((0x5c == pkt_id) + && ((0x1c <= packetlen) && (0x1e >= packetlen))) + /* pass */ ; + else if ((0x5e == pkt_id) && (0x06 == packetlen)) + /* pass */ ; + else if ((0x5f == pkt_id) && (70 == packetlen)) + /* pass */ ; + else if ((0x6d == pkt_id) + && ((0x14 <= packetlen) && (0x20 >= packetlen))) + /* pass */ ; + else if ((0x82 == pkt_id) && (0x05 == packetlen)) + /* pass */ ; + else if ((0x84 == pkt_id) + && ((0x28 <= packetlen) && (0x29 >= packetlen))) + /* pass */ ; + else if ((0x8e == pkt_id)) + /* pass */ ; + else if ((0x8f == pkt_id)) + /* pass */ ; + else if ((0xbb == pkt_id) && (0x2c == packetlen)) + /* pass */ ; + else { + gpsd_report(LOG_IO, + "TSIP REJECT pkt_id = %#02x, packetlen= %zu\n", + pkt_id, packetlen); + goto not_tsip; + } + /* Debug */ + gpsd_report(LOG_RAW, + "TSIP pkt_id = %#02x, packetlen= %zu\n", + pkt_id, packetlen); + /*@ -charint +ifempty @*/ + packet_accept(lexer, TSIP_PACKET); + packet_discard(lexer); + break; + not_tsip: + gpsd_report(LOG_RAW + 1, "Not a TSIP packet\n"); + /* + * More attempts to recognize ambiguous TSIP-like + * packet types could go here. + */ + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + packet_discard(lexer); + break; +#endif /* TSIP_ENABLE */ + } + } +#endif /* TSIP_ENABLE || GARMIN_ENABLE */ +#ifdef RTCM104V3_ENABLE + else if (lexer->state == RTCM3_RECOGNIZED) { + if (crc24q_check(lexer->inbuffer, + lexer->inbufptr - lexer->inbuffer)) { + packet_accept(lexer, RTCM3_PACKET); + packet_discard(lexer); + } else { + gpsd_report(LOG_IO, "RTCM3 data checksum failure, " + "%0x against %02x %02x %02x\n", + crc24q_hash(lexer->inbuffer, + lexer->inbufptr - lexer->inbuffer - + 3), lexer->inbufptr[-3], + lexer->inbufptr[-2], lexer->inbufptr[-1]); + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + packet_discard(lexer); + } + break; + } +#endif /* RTCM104V3_ENABLE */ +#ifdef ZODIAC_ENABLE + else if (lexer->state == ZODIAC_RECOGNIZED) { + short len, n, sum; + len = getword(2); + for (n = sum = 0; n < len; n++) + sum += getword(5 + n); + sum *= -1; + if (len == 0 || sum == getword(5 + len)) { + packet_accept(lexer, ZODIAC_PACKET); + } else { + gpsd_report(LOG_IO, + "Zodiac data checksum 0x%hx over length %hd, expecting 0x%hx\n", + sum, len, getword(5 + len)); + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + } + packet_discard(lexer); + break; + } +#endif /* ZODIAC_ENABLE */ +#ifdef UBX_ENABLE + else if (lexer->state == UBX_RECOGNIZED) { + /* UBX use a TCP like checksum */ + int n, len; + unsigned char ck_a = (unsigned char)0; + unsigned char ck_b = (unsigned char)0; + len = lexer->inbufptr - lexer->inbuffer; + gpsd_report(LOG_IO, "UBX: len %d\n", len); + for (n = 2; n < (len - 2); n++) { + ck_a += lexer->inbuffer[n]; + ck_b += ck_a; + } + if (ck_a == lexer->inbuffer[len - 2] && + ck_b == lexer->inbuffer[len - 1]) + packet_accept(lexer, UBX_PACKET); + else { + gpsd_report(LOG_IO, + "UBX checksum 0x%02hhx%02hhx over length %hd," + " expecting 0x%02hhx%02hhx (type 0x%02hhx%02hhx)\n", + ck_a, + ck_b, + len, + lexer->inbuffer[len - 2], + lexer->inbuffer[len - 1], + lexer->inbuffer[2], lexer->inbuffer[3]); + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + } + packet_discard(lexer); + break; + } +#endif /* UBX_ENABLE */ +#ifdef EVERMORE_ENABLE + else if (lexer->state == EVERMORE_RECOGNIZED) { + unsigned int n, crc, checksum, len; + n = 0; + /*@ +charint */ + if (lexer->inbuffer[n++] != DLE) + goto not_evermore; + if (lexer->inbuffer[n++] != STX) + goto not_evermore; + len = lexer->inbuffer[n++]; + if (len == DLE) { + if (lexer->inbuffer[n++] != DLE) + goto not_evermore; + } + len -= 2; + crc = 0; + for (; len > 0; len--) { + crc += lexer->inbuffer[n]; + if (lexer->inbuffer[n++] == DLE) { + if (lexer->inbuffer[n++] != DLE) + goto not_evermore; + } + } + checksum = lexer->inbuffer[n++]; + if (checksum == DLE) { + if (lexer->inbuffer[n++] != DLE) + goto not_evermore; + } + if (lexer->inbuffer[n++] != DLE) + goto not_evermore; + if (lexer->inbuffer[n++] != ETX) + goto not_evermore; + crc &= 0xff; + if (crc != checksum) { + gpsd_report(LOG_IO, + "EverMore checksum failed: %02x != %02x\n", + crc, checksum); + goto not_evermore; + } + /*@ +charint */ + packet_accept(lexer, EVERMORE_PACKET); + packet_discard(lexer); + break; + not_evermore: + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + packet_discard(lexer); + break; + } +#endif /* EVERMORE_ENABLE */ +/* XXX CSK */ +#ifdef ITRAX_ENABLE +#define getib(j) ((uint8_t)lexer->inbuffer[(j)]) +#define getiw(i) ((uint16_t)(((uint16_t)getib((i)+1) << 8) | (uint16_t)getib((i)))) + + else if (lexer->state == ITALK_RECOGNIZED) { + volatile uint16_t len, n, csum, xsum, tmpw; + volatile uint32_t tmpdw; + + /* number of words */ + len = (uint16_t) (lexer->inbuffer[6] & 0xff); + + /*@ -type @*/ + /* initialize all my registers */ + csum = tmpw = tmpdw = 0; + /* expected checksum */ + xsum = getiw(7 + 2 * len); + + for (n = 0; n < len; n++) { + tmpw = getiw(7 + 2 * n); + tmpdw = (csum + 1) * (tmpw + n); + csum ^= (tmpdw & 0xffff) ^ ((tmpdw >> 16) & 0xffff); + } + /*@ +type @*/ + if (len == 0 || csum == xsum) + packet_accept(lexer, ITALK_PACKET); + else { + gpsd_report(LOG_IO, + "ITALK: checksum failed - " + "type 0x%02x expected 0x%04x got 0x%04x\n", + lexer->inbuffer[4], xsum, csum); + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + } + packet_discard(lexer); + break; + } +#undef getiw +#undef getib +#endif /* ITRAX_ENABLE */ +#ifdef NAVCOM_ENABLE + else if (lexer->state == NAVCOM_RECOGNIZED) { + /* By the time we got here we know checksum is OK */ + packet_accept(lexer, NAVCOM_PACKET); + packet_discard(lexer); + break; + } +#endif /* NAVCOM_ENABLE */ +#ifdef RTCM104V2_ENABLE + else if (lexer->state == RTCM2_RECOGNIZED) { + /* + * RTCM packets don't have checksums. The six bits of parity + * per word and the preamble better be good enough. + */ + packet_accept(lexer, RTCM2_PACKET); + lexer->state = RTCM2_SYNC_STATE; + packet_discard(lexer); + break; + } +#endif /* RTCM104V2_ENABLE */ +#ifdef GARMINTXT_ENABLE + else if (lexer->state == GTXT_RECOGNIZED) { + size_t packetlen = lexer->inbufptr - lexer->inbuffer; + if (57 <= packetlen) { + packet_accept(lexer, GARMINTXT_PACKET); + packet_discard(lexer); + lexer->state = GROUND_STATE; + break; + } else { + packet_accept(lexer, BAD_PACKET); + lexer->state = GROUND_STATE; + } + } +#endif + } /* while */ +} + +#undef getword + +ssize_t packet_get(int fd, struct gps_packet_t *lexer) +/* grab a packet; return -1=>I/O error, 0=>EOF, BAD_PACKET or a length */ +{ + ssize_t recvd; + + /*@ -modobserver @*/ + errno = 0; + recvd = read(fd, lexer->inbuffer + lexer->inbuflen, + sizeof(lexer->inbuffer) - (lexer->inbuflen)); + /*@ +modobserver @*/ + if (recvd == -1) { + if ((errno == EAGAIN) || (errno == EINTR)) { +#ifdef STATE_DEBUG + gpsd_report(LOG_RAW + 2, "no bytes ready\n"); + recvd = 0; + /* fall through, input buffer may be nonempty */ +#endif /* STATE_DEBUG */ + } else { +#ifdef STATE_DEBUG + gpsd_report(LOG_RAW + 2, "errno: %s\n", strerror(errno)); +#endif /* STATE_DEBUG */ + return -1; + } + } else { +#ifdef STATE_DEBUG + gpsd_report(LOG_RAW + 1, + "Read %zd chars to buffer offset %zd (total %zd): %s\n", + recvd, lexer->inbuflen, lexer->inbuflen + recvd, + gpsd_hexdump_wrapper(lexer->inbufptr, (size_t) recvd, + LOG_RAW + 1)); +#endif /* STATE_DEBUG */ + lexer->inbuflen += recvd; + } + gpsd_report(LOG_SPIN, "packet_get() fd %d -> %zd (%d)\n", + fd, recvd, errno); + + /* + * Bail out, indicating no more input, only if we just received + * nothing from the device and there is nothing waiting in the + * packet input buffer. + */ + if (recvd <= 0 && packet_buffered_input(lexer) <= 0) + return recvd; + + /* Otherwise, consume from the packet input buffer */ + packet_parse(lexer); + + /* if input buffer is full, discard */ + if (sizeof(lexer->inbuffer) == (lexer->inbuflen)) { + packet_discard(lexer); + lexer->state = GROUND_STATE; + } + + /* + * If we gathered a packet, return its length; it will have been + * consumed out of the input buffer and moved to the output + * buffer. We don't care whether the read() returned 0 or -1 and + * gathered packet data was all buffered or whether ot was partly + * just physically read. + * + * Note: this choice greatly simplifies life for callers of + * packet_get(), but means that they cannot tell when a nonzero + * return means there was a successful physical read. They will + * thus credit a data source that drops out with being alive + * slightly longer than it actually was. This is unlikely to + * matter as long as any policy timeouts are large compared to + * the time required to consume the greatest possible amount + * of buffered input, but if you hack this code you need to + * be aware of the issue. It might also slightly affect + * performance profiling. + */ + if (lexer->outbuflen > 0) + return (ssize_t) lexer->outbuflen; + else + /* + * Otherwise recvd is the size of whatever packet fragment we got. + * It can still be 0 or -1 at this point even if buffer data + * was consumed. + */ + return recvd; +} + +void packet_reset( /*@out@*/ struct gps_packet_t *lexer) +/* return the packet machine to the ground state */ +{ + lexer->type = BAD_PACKET; + lexer->state = GROUND_STATE; + lexer->inbuflen = 0; + lexer->inbufptr = lexer->inbuffer; +#ifdef BINARY_ENABLE + isgps_init(lexer); +#endif /* BINARY_ENABLE */ +} + + +#ifdef __UNUSED__ +void packet_pushback(struct gps_packet_t *lexer) +/* push back the last packet grabbed */ +{ + if (lexer->outbuflen + lexer->inbuflen < MAX_PACKET_LENGTH) { + memmove(lexer->inbuffer + lexer->outbuflen, + lexer->inbuffer, lexer->inbuflen); + memmove(lexer->inbuffer, lexer->outbuffer, lexer->outbuflen); + lexer->inbuflen += lexer->outbuflen; + lexer->inbufptr += lexer->outbuflen; + lexer->outbuflen = 0; + } +} +#endif /* __UNUSED */ + +#ifdef ONCORE_ENABLE +size_t oncore_payload_cksum_length(unsigned char id1, unsigned char id2) +{ + size_t l; + + /* For the packet sniffer to not terminate the message due to + * payload data looking like a trailer, the known payload lengths + * including the checksum are given. Return -1 for unknown IDs. + */ + +#define ONCTYPE(id2,id3) ((((unsigned int)id2)<<8)|(id3)) + + /* *INDENT-OFF* */ + switch (ONCTYPE(id1,id2)) { + case ONCTYPE('A','b'): l = 10; break; /* GMT offset */ + case ONCTYPE('A','w'): l = 8; break; /* time mode */ + case ONCTYPE('A','c'): l = 11; break; /* date */ + case ONCTYPE('A','a'): l = 10; break; /* time of day */ + case ONCTYPE('A','d'): l = 11; break; /* latitude */ + case ONCTYPE('A','e'): l = 11; break; /* longitude */ + case ONCTYPE('A','f'): l = 15; break; /* height */ + case ONCTYPE('E','a'): l = 76; break; /* position/status/data */ + case ONCTYPE('A','g'): l = 8; break; /* satellite mask angle */ + case ONCTYPE('B','b'): l = 92; break; /* visible satellites status */ + case ONCTYPE('B','j'): l = 8; break; /* leap seconds pending */ + case ONCTYPE('A','q'): l = 8; break; /* atmospheric correction mode */ + case ONCTYPE('A','p'): l = 25; break; /* set user datum / select datum */ + /* Command "Ao" gives "Ap" response (select datum) */ + case ONCTYPE('C','h'): l = 9; break; /* almanac input ("Cb" response) */ + case ONCTYPE('C','b'): l = 33; break; /* almanac output ("Be" response) */ + case ONCTYPE('S','z'): l = 8; break; /* system power-on failure */ + case ONCTYPE('C','j'): l = 294; break; /* receiver ID */ + case ONCTYPE('F','a'): l = 9; break; /* self-test */ + case ONCTYPE('C','f'): l = 7; break; /* set-to-defaults */ + case ONCTYPE('E','q'): l = 96; break; /* ASCII position */ + case ONCTYPE('A','u'): l = 12; break; /* altitide hold height */ + case ONCTYPE('A','v'): l = 8; break; /* altitude hold mode */ + case ONCTYPE('A','N'): l = 8; break; /* velocity filter */ + case ONCTYPE('A','O'): l = 8; break; /* RTCM report mode */ + case ONCTYPE('C','c'): l = 80; break; /* ephemeris data input ("Bf") */ + case ONCTYPE('C','k'): l = 7; break; /* pseudorng correction inp. ("Ce")*/ + /* Command "Ci" (switch to NMEA, GT versions only) has no response */ + case ONCTYPE('B','o'): l = 8; break; /* UTC offset status */ + case ONCTYPE('A','z'): l = 11; break; /* 1PPS cable delay */ + case ONCTYPE('A','y'): l = 11; break; /* 1PPS offset */ + case ONCTYPE('A','P'): l = 8; break; /* pulse mode */ + case ONCTYPE('A','s'): l = 20; break; /* position-hold position */ + case ONCTYPE('A','t'): l = 8; break; /* position-hold mode */ + case ONCTYPE('E','n'): l = 69; break; /* time RAIM setup and status */ + default: + return 0; + } + /* *INDENT-ON* */ + + return l - 6; /* Subtract header and trailer. */ +} +#endif /* ONCORE_ENABLE */ diff --git a/packet_states.h b/packet_states.h new file mode 100644 index 0000000..9f206b9 --- /dev/null +++ b/packet_states.h @@ -0,0 +1,170 @@ +/* edit packet_states.h to add new packet types. */ + GROUND_STATE, /* we don't know what packet type to expect */ + + COMMENT_BODY, /* pound comment for a test load */ + COMMENT_RECOGNIZED, /* comment recognized */ + +#ifdef NMEA_ENABLE + NMEA_DOLLAR, /* we've seen first character of NMEA leader */ + NMEA_BANG, /* we've seen first character of an AIS message '!' */ + NMEA_PUB_LEAD, /* seen second character of NMEA G leader */ + NMEA_VENDOR_LEAD, /* seen second character of NMEA P leader */ + NMEA_LEADER_END, /* seen end char of NMEA leader, in body */ + NMEA_PASHR_A, /* grind through recognizing $PASHR */ + NMEA_PASHR_S, /* grind through recognizing $PASHR */ + NMEA_PASHR_H, /* grind through recognizing $PASHR */ + NMEA_BINARY_BODY, /* Ashtech-style binary packet body, skip until \r\n */ + NMEA_BINARY_CR, /* \r on end of Ashtech-style binary packet */ + NMEA_BINARY_NL, /* \n on end of Ashtech-style binary packet */ + NMEA_CR, /* seen terminating \r of NMEA packet */ + NMEA_RECOGNIZED, /* saw trailing \n of NMEA packet */ + + SIRF_ACK_LEAD_1, /* seen A of possible SiRF Ack */ + SIRF_ACK_LEAD_2, /* seen c of possible SiRF Ack */ + AIS_LEAD_1, /* seen A of possible marine AIS message */ + AIS_LEAD_2, /* seen I of possible marine AIS message */ + + SEATALK_LEAD_1, /* SeaTalk/Garmin packet leader 'I' */ +#endif /* NMEA_ENABLE */ + + DLE_LEADER, /* we've seen the TSIP/EverMore leader (DLE) */ + +#ifdef TRIPMATE_ENABLE + ASTRAL_1, /* ASTRAL leader A */ + ASTRAL_2, /* ASTRAL leader S */ + ASTRAL_3, /* ASTRAL leader T */ + ASTRAL_4, /* ASTRAL leader R */ + ASTRAL_5, /* ASTRAL leader A */ +#endif /* TRIPMATE_ENABLE */ + +#ifdef EARTHMATE_ENABLE + EARTHA_1, /* EARTHA leader E */ + EARTHA_2, /* EARTHA leader A */ + EARTHA_3, /* EARTHA leader R */ + EARTHA_4, /* EARTHA leader T */ + EARTHA_5, /* EARTHA leader H */ +#endif /* EARTHMATE_ENABLE */ + +#ifdef SIRF_ENABLE + SIRF_LEADER_1, /* we've seen first character of SiRF leader */ + SIRF_LEADER_2, /* seen second character of SiRF leader */ + SIRF_LENGTH_1, /* seen first byte of SiRF length */ + SIRF_PAYLOAD, /* we're in a SiRF payload part */ + SIRF_DELIVERED, /* saw last byte of SiRF payload/checksum */ + SIRF_TRAILER_1, /* saw first byte of SiRF trailer */ + SIRF_RECOGNIZED, /* saw second byte of SiRF trailer */ +#endif /* SIRF_ENABLE */ + +#ifdef ZODIAC_ENABLE + ZODIAC_EXPECTED, /* expecting Zodiac packet */ + ZODIAC_LEADER_1, /* saw leading 0xff */ + ZODIAC_LEADER_2, /* saw leading 0x81 */ + ZODIAC_ID_1, /* saw first byte of ID */ + ZODIAC_ID_2, /* saw second byte of ID */ + ZODIAC_LENGTH_1, /* saw first byte of Zodiac packet length */ + ZODIAC_LENGTH_2, /* saw second byte of Zodiac packet length */ + ZODIAC_FLAGS_1, /* saw first byte of FLAGS */ + ZODIAC_FLAGS_2, /* saw second byte of FLAGS */ + ZODIAC_HSUM_1, /* saw first byte of Header sum */ + ZODIAC_PAYLOAD, /* we're in a Zodiac payload */ + ZODIAC_RECOGNIZED, /* found end of the Zodiac packet */ +#endif /* ZODIAC_ENABLE */ + +#if defined(TNT_ENABLE) || defined(GARMINTXT_ENABLE) || defined(ONCORE_ENABLE) + AT1_LEADER, /* saw True North status leader '@' */ + /* Garmin Simple Text starts with @ leader */ + /* Oncore starts with @ leader */ + GTXT_RECOGNIZED, /* */ +#endif + +#ifdef EVERMORE_ENABLE + EVERMORE_LEADER_1, /* a DLE after having seen EverMore data */ + EVERMORE_LEADER_2, /* seen opening STX of EverMore packet */ + EVERMORE_PAYLOAD, /* in payload part of EverMore packet */ + EVERMORE_PAYLOAD_DLE,/* DLE in payload part of EverMore packet */ + EVERMORE_RECOGNIZED, /* found end of EverMore packet */ +#endif /* EVERMORE_ENABLE */ + +#ifdef ITRAX_ENABLE + ITALK_LEADER_1, /* saw leading < of iTalk packet */ + ITALK_LEADER_2, /* saw leading ! of iTalk packet */ + ITALK_LENGTH, /* saw packet length */ + ITALK_PAYLOAD, /* in payload part of iTalk Packet */ + ITALK_DELIVERED, /* seen end of payload */ + ITALK_TRAILER, /* saw iTalk trailer byte */ + ITALK_RECOGNIZED, /* found end of the iTalk packet */ +#endif /* ITRAX_ENABLE */ + +#ifdef NAVCOM_ENABLE + NAVCOM_EXPECTED, /* expecting Navcom packet */ + NAVCOM_LEADER_1, /* saw leading 0x02 */ + NAVCOM_LEADER_2, /* saw leading 0x99 */ + NAVCOM_LEADER_3, /* saw leading 0x66 */ + NAVCOM_ID, /* saw message ID */ + NAVCOM_LENGTH_1, /* saw first byte of Navcom packet length */ + NAVCOM_LENGTH_2, /* saw second byte of Navcom packet length */ + NAVCOM_PAYLOAD, /* we're in a Navcom payload */ + NAVCOM_CSUM, /* saw checksum */ + NAVCOM_RECOGNIZED, /* found end of the Navcom packet */ +#endif /* NAVCOM_ENABLE */ + +#ifdef UBX_ENABLE + UBX_LEADER_1, /* first constant leader byte found */ + UBX_LEADER_2, /* second constant leader byte found */ + UBX_CLASS_ID, /* classid read */ + UBX_MESSAGE_ID, /* message id read */ + UBX_LENGTH_1, /* first length byte read (le) */ + UBX_LENGTH_2, /* second length byte read (le) */ + UBX_PAYLOAD, /* payload eating */ + UBX_CHECKSUM_A, /* checksum A byte (tcp checksum) */ + UBX_RECOGNIZED, /* this is also UBX_CHECKSUM_B */ +#endif + +#ifdef SUPERSTAR2_ENABLE + SUPERSTAR2_LEADER, /* leading SOH */ + SUPERSTAR2_ID1, /* message type */ + SUPERSTAR2_ID2, /* message type xor 0xff */ + SUPERSTAR2_PAYLOAD, /* length of the actual packet data */ + SUPERSTAR2_CKSUM1, + SUPERSTAR2_CKSUM2, + SUPERSTAR2_RECOGNIZED, +#endif + +#ifdef ONCORE_ENABLE + ONCORE_AT2, /* second @ */ + ONCORE_ID1, /* first character of command type */ + ONCORE_PAYLOAD, /* payload eating */ + ONCORE_CHECKSUM, /* checksum byte */ + ONCORE_CR, /* closing CR */ + ONCORE_RECOGNIZED, /* closing LF */ +#endif + + +/* + * Packet formats without checksums start here. We list them last so + * that if a format with a conflicting structure *and* a checksum can + * be recognized, that will be preferred. + */ + +#if defined(TSIP_ENABLE) || defined(GARMIN_ENABLE) + TSIP_LEADER, /* a DLE after having seen TSIP data */ + TSIP_PAYLOAD, /* we're in TSIP payload */ + TSIP_DLE, /* we've seen a DLE in TSIP payload */ + TSIP_RECOGNIZED, /* found end of the TSIP packet */ + GARMIN_RECOGNIZED, /* found end of Garmin packet */ +#endif /* TSIP_ENABLE GARMIN_ENABLE */ + +#ifdef RTCM104V2_ENABLE + RTCM2_SYNC_STATE, /* we have sync lock */ + RTCM2_SKIP_STATE, /* we have sync lock, but this character is bad */ + RTCM2_RECOGNIZED, /* we have an RTCM packet */ +#endif /* RTCM104V2_ENABLE */ + +#ifdef RTCM104V3_ENABLE + RTCM3_LEADER_1, /* constant leader byte found */ + RTCM3_LEADER_2, /* second leader byte found (high 6 bits zero) */ + RTCM3_PAYLOAD, /* gathering payload */ + RTCM3_RECOGNIZED, /* RTCM3 packet recognized */ +#endif + +/* end of packet_states.h */ diff --git a/pseudonmea.c b/pseudonmea.c new file mode 100644 index 0000000..22f61f3 --- /dev/null +++ b/pseudonmea.c @@ -0,0 +1,270 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include "gpsd_config.h" +#include +#ifdef HAVE_SYS_IOCTL_H +#include +#endif /* HAVE_SYS_IOCTL_H */ +#ifndef S_SPLINT_S +#ifdef HAVE_SYS_SOCKET_H +#include +#endif /* HAVE_SYS_SOCKET_H */ +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#ifndef S_SPLINT_S +#ifdef HAVE_NETDB_H +#include +#endif /* HAVE_NETDB_H */ +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd.h" + +/* + * Support for generic binary drivers. These functions dump NMEA for passing + * to the client in raw mode. They assume that (a) the public gps.h structure + * members are in a valid state, (b) that the private members hours, minutes, + * and seconds have also been filled in, (c) that if the private member + * mag_var is not NAN it is a magnetic variation in degrees that should be + * passed on, and (d) if the private member separation does not have the + * value NAN, it is a valid WGS84 geoidal separation in meters for the fix. + */ + +static double degtodm(double angle) +/* decimal degrees to GPS-style, degrees first followed by minutes */ +{ + double fraction, integer; + fraction = modf(angle, &integer); + return floor(angle) * 100 + fraction * 60; +} + +/*@ -mustdefine @*/ +void gpsd_position_fix_dump(struct gps_device_t *session, + /*@out@*/ char bufp[], size_t len) +{ + struct tm tm; + time_t intfixtime; + + intfixtime = (time_t) session->gpsdata.fix.time; + (void)gmtime_r(&intfixtime, &tm); + if (session->gpsdata.fix.mode > 1) { + (void)snprintf(bufp, len, + "$GPGGA,%02d%02d%02d,%09.4f,%c,%010.4f,%c,%d,%02d,", + tm.tm_hour, + tm.tm_min, + tm.tm_sec, + degtodm(fabs(session->gpsdata.fix.latitude)), + ((session->gpsdata.fix.latitude > 0) ? 'N' : 'S'), + degtodm(fabs(session->gpsdata.fix.longitude)), + ((session->gpsdata.fix.longitude > 0) ? 'E' : 'W'), + session->gpsdata.status, + session->gpsdata.satellites_used); + if (isnan(session->gpsdata.dop.hdop)) + (void)strlcat(bufp, ",", len); + else + (void)snprintf(bufp + strlen(bufp), len - strlen(bufp), + "%.2f,", session->gpsdata.dop.hdop); + if (isnan(session->gpsdata.fix.altitude)) + (void)strlcat(bufp, ",", len); + else + (void)snprintf(bufp + strlen(bufp), len - strlen(bufp), + "%.2f,M,", session->gpsdata.fix.altitude); + if (isnan(session->gpsdata.separation)) + (void)strlcat(bufp, ",", len); + else + (void)snprintf(bufp + strlen(bufp), len - strlen(bufp), + "%.3f,M,", session->gpsdata.separation); + if (isnan(session->mag_var)) + (void)strlcat(bufp, ",", len); + else { + (void)snprintf(bufp + strlen(bufp), + len - strlen(bufp), + "%3.2f,", fabs(session->mag_var)); + (void)strlcat(bufp, (session->mag_var > 0) ? "E" : "W", len); + } + nmea_add_checksum(bufp); + } +} + +/*@ +mustdefine @*/ + +static void gpsd_transit_fix_dump(struct gps_device_t *session, + char bufp[], size_t len) +{ + struct tm tm; + time_t intfixtime; + + tm.tm_mday = tm.tm_mon = tm.tm_year = tm.tm_hour = tm.tm_min = tm.tm_sec = + 0; + if (isnan(session->gpsdata.fix.time) == 0) { + intfixtime = (time_t) session->gpsdata.fix.time; + (void)gmtime_r(&intfixtime, &tm); + tm.tm_mon++; + tm.tm_year %= 100; + } +#define ZEROIZE(x) (isnan(x)!=0 ? 0.0 : x) + /*@ -usedef @*/ + (void)snprintf(bufp, len, + "$GPRMC,%02d%02d%02d,%c,%09.4f,%c,%010.4f,%c,%.4f,%.3f,%02d%02d%02d,,", + tm.tm_hour, + tm.tm_min, + tm.tm_sec, + session->gpsdata.status ? 'A' : 'V', + ZEROIZE(degtodm(fabs(session->gpsdata.fix.latitude))), + ((session->gpsdata.fix.latitude > 0) ? 'N' : 'S'), + ZEROIZE(degtodm(fabs(session->gpsdata.fix.longitude))), + ((session->gpsdata.fix.longitude > 0) ? 'E' : 'W'), + ZEROIZE(session->gpsdata.fix.speed * MPS_TO_KNOTS), + ZEROIZE(session->gpsdata.fix.track), + tm.tm_mday, tm.tm_mon, tm.tm_year); + /*@ +usedef @*/ +#undef ZEROIZE + nmea_add_checksum(bufp); +} + +static void gpsd_binary_satellite_dump(struct gps_device_t *session, + char bufp[], size_t len) +{ + int i; + char *bufp2 = bufp; + bufp[0] = '\0'; + + for (i = 0; i < session->gpsdata.satellites_visible; i++) { + if (i % 4 == 0) { + bufp += strlen(bufp); + bufp2 = bufp; + len -= snprintf(bufp, len, + "$GPGSV,%d,%d,%02d", + ((session->gpsdata.satellites_visible - 1) / 4) + + 1, (i / 4) + 1, + session->gpsdata.satellites_visible); + } + bufp += strlen(bufp); + if (i < session->gpsdata.satellites_visible) + len -= snprintf(bufp, len, + ",%02d,%02d,%03d,%02.0f", + session->gpsdata.PRN[i], + session->gpsdata.elevation[i], + session->gpsdata.azimuth[i], + session->gpsdata.ss[i]); + if (i % 4 == 3 || i == session->gpsdata.satellites_visible - 1) { + nmea_add_checksum(bufp2); + len -= 5; + } + } + +#ifdef ZODIAC_ENABLE + if (session->packet.type == ZODIAC_PACKET + && session->driver.zodiac.Zs[0] != 0) { + bufp += strlen(bufp); + bufp2 = bufp; + (void)strlcpy(bufp, "$PRWIZCH", len); + for (i = 0; i < ZODIAC_CHANNELS; i++) { + len -= snprintf(bufp + strlen(bufp), len, + ",%02u,%X", + session->driver.zodiac.Zs[i], + session->driver.zodiac.Zv[i] & 0x0f); + } + nmea_add_checksum(bufp2); + } +#endif /* ZODIAC_ENABLE */ +} + +static void gpsd_binary_quality_dump(struct gps_device_t *session, + char bufp[], size_t len) +{ + int i, j; + char *bufp2 = bufp; + bool used_valid = (session->gpsdata.set & USED_IS) != 0; + + if (session->device_type != NULL && (session->gpsdata.set & MODE_IS) != 0) { + (void)snprintf(bufp, len - strlen(bufp), + "$GPGSA,%c,%d,", 'A', session->gpsdata.fix.mode); + j = 0; + for (i = 0; i < session->device_type->channels; i++) { + if (session->gpsdata.used[i]) { + bufp += strlen(bufp); + (void)snprintf(bufp, len - strlen(bufp), + "%02d,", + used_valid ? session->gpsdata.used[i] : 0); + j++; + } + } + for (i = j; i < session->device_type->channels; i++) { + bufp += strlen(bufp); + (void)strlcpy(bufp, ",", len); + } + bufp += strlen(bufp); +#define ZEROIZE(x) (isnan(x)!=0 ? 0.0 : x) + if (session->gpsdata.fix.mode == MODE_NO_FIX) + (void)strlcat(bufp, ",,,", len); + else + (void)snprintf(bufp, len - strlen(bufp), + "%.1f,%.1f,%.1f*", + ZEROIZE(session->gpsdata.dop.pdop), + ZEROIZE(session->gpsdata.dop.hdop), + ZEROIZE(session->gpsdata.dop.vdop)); + nmea_add_checksum(bufp2); + bufp += strlen(bufp); + } + if (finite(session->gpsdata.fix.epx) + && finite(session->gpsdata.fix.epy) + && finite(session->gpsdata.fix.epv) + && finite(session->gpsdata.epe)) { + struct tm tm; + time_t intfixtime; + + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + if (isnan(session->gpsdata.fix.time) == 0) { + intfixtime = (time_t) session->gpsdata.fix.time; + (void)gmtime_r(&intfixtime, &tm); + } + (void)snprintf(bufp, len - strlen(bufp), + "$GPGBS,%02d%02d%02d,%.2f,M,%.2f,M,%.2f,M", + tm.tm_hour, tm.tm_min, tm.tm_sec, + ZEROIZE(session->gpsdata.fix.epx), + ZEROIZE(session->gpsdata.fix.epy), + ZEROIZE(session->gpsdata.fix.epv)); + nmea_add_checksum(bufp); + } +#undef ZEROIZE +} + +/*@-compdef -mustdefine@*/ +/* *INDENT-OFF* */ +void nmea_tpv_dump(struct gps_device_t *session, + /*@out@*/ char bufp[], size_t len) +{ + bufp[0] = '\0'; + if ((session->gpsdata.set & LATLON_IS) != 0) { + gpsd_position_fix_dump(session, bufp, len); + gpsd_transit_fix_dump(session, bufp + strlen(bufp), + len - strlen(bufp)); + } + if ((session->gpsdata.set + & (MODE_IS | DOP_IS | USED_IS | HERR_IS | VERR_IS)) != 0) + gpsd_binary_quality_dump(session, bufp + strlen(bufp), + len - strlen(bufp)); +} +/* *INDENT-ON* */ + +void nmea_sky_dump(struct gps_device_t *session, + /*@out@*/ char bufp[], size_t len) +{ + bufp[0] = '\0'; + if ((session->gpsdata.set & SATELLITE_IS) != 0) + gpsd_binary_satellite_dump(session, bufp + strlen(bufp), + len - strlen(bufp)); +} + +/*@+compdef +mustdefine@*/ + +/* pseudonmea.c ends here */ diff --git a/py-compile b/py-compile new file mode 100755 index 0000000..3f9d05b --- /dev/null +++ b/py-compile @@ -0,0 +1,146 @@ +#!/bin/sh +# py-compile - Compile a Python program + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 2000, 2001, 2003, 2004, 2005, 2008, 2009 Free Software +# Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +if [ -z "$PYTHON" ]; then + PYTHON=python +fi + +basedir= +destdir= +files= +while test $# -ne 0; do + case "$1" in + --basedir) + basedir=$2 + if test -z "$basedir"; then + echo "$0: Missing argument to --basedir." 1>&2 + exit 1 + fi + shift + ;; + --destdir) + destdir=$2 + if test -z "$destdir"; then + echo "$0: Missing argument to --destdir." 1>&2 + exit 1 + fi + shift + ;; + -h|--h*) + cat <<\EOF +Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..." + +Byte compile some python scripts FILES. Use --destdir to specify any +leading directory path to the FILES that you don't want to include in the +byte compiled file. Specify --basedir for any additional path information you +do want to be shown in the byte compiled file. + +Example: + py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py + +Report bugs to . +EOF + exit $? + ;; + -v|--v*) + echo "py-compile $scriptversion" + exit $? + ;; + *) + files="$files $1" + ;; + esac + shift +done + +if test -z "$files"; then + echo "$0: No files given. Try \`$0 --help' for more information." 1>&2 + exit 1 +fi + +# if basedir was given, then it should be prepended to filenames before +# byte compilation. +if [ -z "$basedir" ]; then + pathtrans="path = file" +else + pathtrans="path = os.path.join('$basedir', file)" +fi + +# if destdir was given, then it needs to be prepended to the filename to +# byte compile but not go into the compiled file. +if [ -z "$destdir" ]; then + filetrans="filepath = path" +else + filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)" +fi + +$PYTHON -c " +import sys, os, py_compile + +files = '''$files''' + +sys.stdout.write('Byte-compiling python modules...\n') +for file in files.split(): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + sys.stdout.write(file) + sys.stdout.flush() + py_compile.compile(filepath, filepath + 'c', path) +sys.stdout.write('\n')" || exit $? + +# this will fail for python < 1.5, but that doesn't matter ... +$PYTHON -O -c " +import sys, os, py_compile + +files = '''$files''' +sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n') +for file in files.split(): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + sys.stdout.write(file) + sys.stdout.flush() + py_compile.compile(filepath, filepath + 'o', path) +sys.stdout.write('\n')" 2>/dev/null || : + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/regress-driver b/regress-driver new file mode 100755 index 0000000..793d909 --- /dev/null +++ b/regress-driver @@ -0,0 +1,155 @@ +#!/bin/sh +# +# The regression-test driver script. This used to be explicit in the +# makefile before we regrouped the regression tests by stable and unstable +# drivers. + +# Requires GNU date extensions +# Should return an empty blank string if tose are not present. +starttime=`date +"%s" 2>/dev/null` + +# We need to have the build directory in $GPSD_HOME to find the new gpsd +if [ "`dirname $0`" = "." ]; then + GPSD_HOME=`pwd` +else + GPSD_HOME=`dirname $0` +fi + +# Arrange to call a gpsfake in the source directory without fuss. +if [ -z ${PYTHON} ]; then + PYTHON="python" +fi +# For an explanation of what we define here, see the comment on +# PYTHON_DISTUTILS_LIBDIR/PYTHON_DISTUTILS_SCRIPTDIR in configure.ac +py_libdir=`pwd`/build/`${PYTHON} -c 'import distutils.util; import sys; print("lib.%s-%s" %(distutils.util.get_platform(), sys.version[0:3]))'` +py_scriptdir=`pwd`/build/`${PYTHON} -c 'import sys; print("scripts-%s" %(sys.version[0:3], ))'` +if [ -d ${py_libdir} ] && [ -d ${py_scriptdir} ]; then + PYTHONPATH=${py_libdir} + export PYTHONPATH + + PATH=${py_scriptdir}:${PATH} +fi +export GPSD_HOME PATH + +mode=regress +testing=daemon +opts="" +while getopts cstrbuvo opt +do + case $opt in + c) testing=clientlib ;; # Can be 'daemon' + s) mode=regress ;; # Run regression tests + t) opts="-b $opts" mode=regress ;; # Run regression tests w/baton + r) mode=superraw ;; # Run superraw regressions (r=2 mode) + b) mode=build ;; # Rebuild regression check files + u) opts="$opts -u" ;; # Force UDP + v) mode=view ;; # View result of generating a check file + o) opts="$opts $OPTARG" ;; # Pass options to gpsfake + esac +done +shift $(($OPTIND - 1)) + +# Enables us to turn debugging up high without screwing up the diff checks +# First and Second filter out gpsd log messages. +# Third filters out gps.py verbose loggging +# Fourth filters out WATCH responses +# Fifth filters out DEVICE responses +# Sixth filters out VERSION responses +# Seventh filters out device fields +GPSFILTER="sed -e /^gpsd:/d -e /^gpsfake/d -e /GPS-DATA/d -e /WATCH/d -e /DEVICE/d -e /VERSION/d -e s/,\"device\":[^,}]*//" + +# Use ALTFILTER to set up custom filtering when a regression test fails +# This example filters out altitude and some fields computed by gpsd's error +# modeling - these are fragile in the prsence of changes to the fix-buffering +# logic. Note that as the last attribute mode needs to be handled differently. +#ALTFILTER="-e s/\"alt\":[^,]*,// -e s/\"ep[vhs]\":[-+0-9.]*// -e s/,\"mode\":[^}]*//" + +TMP=/tmp + +# Only twirl the baton on a tty, avoids junk in transcripts. +if [ -t 1 ] +then + opts="$opts -b" +fi + +case $mode in + regress) + echo "Testing the $testing..." >&2 + errors=0; total=0; notfound=0; + for f in $*; do + if [ -r $f.chk ] + then + trap 'rm -f ${TMP}/test-$$.chk; exit $errors' EXIT HUP INT TERM + case $testing in + daemon) gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} ${ALTFILTER} >${TMP}/test-$$.chk ;; + clientlib) $GPSD_HOME/libgps -b <${f} >${TMP}/test-$$.chk ;; + esac + if [ "${ALTFILTER}" ] + then + trap 'rm -f ${TMP}/test-$$.chk ${TMP}/testout-$$.chk ${TMP}/testin-$$.chk ${TMP}/diff-$$; exit $errors' EXIT HUP INT TERM + sed -n <${f}.chk >${TMP}/testin-$$.chk ${ALTFILTER} -e 'p'; + sed -n <${TMP}/test-$$.chk >${TMP}/testout-$$.chk ${ALTFILTER} -e 'p'; + diff -ub ${TMP}/testin-$$.chk ${TMP}/testout-$$.chk >${TMP}/diff-$$; + else + diff -ub ${f}.chk ${TMP}/test-$$.chk >${TMP}/diff-$$; + fi + if test -s ${TMP}/diff-$$ ; then + errors=`expr $errors + 1`; + cat ${TMP}/diff-$$ + fi; + rm -f ${TMP}/test-$$.chk ${TMP}/testout-$$.chk ${TMP}/testin-$$.chk ${TMP}/diff-$$ + else + echo "*** No check log $f.chk exists" + notfound=`expr $notfound + 1`; + fi + total=`expr $total + 1`; + done; + if test $errors -gt 0; then + echo "Regression test FAILED: $errors errors in $total tests total ($notfound not found)."; + status=1; + else + echo "Regression test successful: no errors in $total tests ($notfound not found)."; + status=0; + fi + ;; + superraw) + echo "Testing super-raw mode..." >&2 + for f in $*; do + gpsfake -s 38400 -1 -p $opts -r '{"class":"WATCH","enable":False,"raw":2}' $opts ${f} \ + | ./devtools/striplog -1 >${TMP}/test1-$$.chk; + ./devtools/striplog <${f} >${TMP}/test2-$$.chk; + cmp ${TMP}/test[12]-$$.chk; + done; rm ${TMP}/test[12]-$$.chk + ;; + build) + echo "Rebuilding $testing regressions..." >&2 + for f in $*; do + case $testing in + daemon) gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} >${f}.chk;; + clientlib) $GPSD_HOME/libgps -b <${f} >${f}.chk ;; + esac + done + status=0 + ;; + view) + echo "Viewing..." >&2 + for f in $*; do + case $testing in + daemon) gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} ;; + clientlib) $GPSD_HOME/libgps -b <${f} ;; + esac + done + status=0 + ;; +esac + +# See starttime above +endtime=`date +"%s" 2>/dev/null` + +if [ "$starttime" -a "$endtime" ] +then + echo -n "Elapsed time: " + echo "scale=2; ${endtime} - ${starttime}" | bc +fi + +exit $status diff --git a/rtcm-104.xml b/rtcm-104.xml new file mode 100644 index 0000000..43f6b4f --- /dev/null +++ b/rtcm-104.xml @@ -0,0 +1,509 @@ + + + + +27 Aug 2009 + +rtcm-104 +5 +The GPSD Project +GPSD Documentation + + +rtcm-104 +RTCM-104 dump format emitted by GPSD tools + + +OVERVIEW + +RTCM-104 is a family of serial protocols used for broadcasting pseudorange +corrections from differential-GPS reference stations. This manual +page describes some aspects of the RTCM protocol, mainly in order to +explain the RTCM-104 dump formats emitted by +gpsdecode1. +It describes that dump format completely. + +RTCM-104 comes in two major and incompatible flavors, 2.x and +3.x. Each major flavor has minor (compatible) revisions. + +The applicable standard for RTCM Version 2.x is RTCM +Recommended Standards for Differential NAVSTAR GPS Service +RTCM Paper 194-93/SC 104-STD. For RTCM 3.1 it is RTCM Paper +177-2006-SC104-STD. Ordering instructions for both +standards are accessible from the website of the Radio Technical Commission for Maritime +Services under "Publications". + + +RTCM WIRE TRANSMISSIONS + +Differential-GPS correction stations consist of a GPS reference +receiver coupled to a low frequency (LF) transmitter. The GPS +reference receiver is a survey-grade GPS that does GPS carrier +tracking and can work out its own position to a few millimeters. It +generates range and range-rate corrections and encodes them into +RTCM104. It ships the RTCM104 to the LF transmitter over serial rs-232 +signal at 100 baud or 200 baud depending on the requirements of the +transmitter. + +The LF transmitter broadcasts the the approximately 300khz radio +signal that differential-GPS radio receivers pick up. Transmitters +that are meant to have a higher range will need to transmit at the +slower rate. The higher the data rate the harder it will be for the +remote radio receiver to receive with a good signal-to-noise ration. +(Higher data rate signals can't be averaged over as long a time frame, +hence they appear noisier.) + + +RTCM WIRE FORMATS + +An RTCM 2.x message consists of a sequence of up to 33 30-bit +words. The 24 most significant bits of each word are data and the six +least significant bits are parity. The parity algorithm used is the +same ISGPS-2000 as that used on GPS satellite downlinks. Each RTCM +2.x message consists of two header words followed by zero or more data +words, depending upon message type. + +An RTCM 3.x message begins with a fixed leader byte 0xD3. That +is followed by six bits of version information and 10 bits of payload +length information. Following that is the payload; following the +payload is a 3-byte checksum of the payload using the Qualcomm CRC-24Q +algorithm. + + +SAGER RTCM2 DUMP FORMAT + +For each message, the header is listed first, followed by zero +or more lines containing the specific data for that message, followed +by a trailing sentinel line containing a single dot. The general format is a +line beginning with a capital letter, followed by a tab, followed by +the fields of the message separated by tabs, terminated by a +newline. + +Header message (H) + + +H <message type> <reference station id> <modified z_count> <sequence number> + <message length> <station health> [T <useful length>] + + +Here is an example: + + +H 9 268 249.6 1 5 0 +S 13 0 3 249.6 -26.120 0.068 +S 2 0 73 249.6 1.220 -0.080 +S 8 0 22 249.6 23.760 0.030 +. + + +<message type> is one of + + + +1 +full corrections - one message containing corrections for +all satellites in view. This is not common. + + + +3 +reference station parameters - the position of the +reference station GPS antenna. + + + +4 +datum — the datum to which the DGPS data is +referred. + + + +5 +constellation health — information about the +satellites the beacon can see + + + +6 +null message — just a filler. + + + +7 +radio beacon almanac — information about this or other beacons. + + + +9 +subset corrections — a message containing corrections +for only a subset of the satellites in view. + + + +16 +special message — a text message from the beacon +operator. + + + +<reference station id> is the id of the GPS reference receiver. The +LF transmitters also have (different) id numbers. + +<modified z_count> is the reference time of the +corrections in the message in seconds within the current hour. Note +that it is in GPS time, which is some seconds ahead of UTC (see the +U.S. Naval Observatory's table of leap second +corrections). + +<sequence no> is a number which increments, modulo 8, for each +message transmitted. + +<message length> is the number of words after the header that +comprise the message. + +<station health> indicates the health of the beacon as a +reference source. Any nonzero value means the satellite is probably +transmitting bad data and should not be used in a fix. 6 means the +transmission is unmonitored. 7 means the station is not working +properly. Other values are defined by the beacon operator. + + +If the message contains a parity error after the header but before +the end of the message, then the extra fields [T <useful length>] +are appended to indicate a truncated message. + +Here is an example: + + +H 9 687 331.8 1 5 0 T 4 + + +<useful length> indicates the number of useful words before the +parity error. Depending on the message type, useful information +may still be extracted. + + +Correction data (S) + +One or more of these follow the header for type 1 or type 9 +messages. Here is the format: + + +S <satellite> <udre> <iod> <modified z_count> <range error> + <range error rate> + + +Here is an example: + + +S 7 0 199 331.8 -12.160 0.288 + + +<satellite> is the PRN number of the satellite for which this is +correction data. + +<udre> is User Differential Range Error with the following +values: + + +0 1-sigma error <= 1m +1 1-sigma error <= 4m +2 1-sigma error <= 8m +3 1-sigma error > 8m + + +<iod> is Issue Of Data, matching the IOD for the current +ephemeris of this satellite, as transmitted by the satellite. The IOD +is a unique tag that identifies the ephemeris; the GPS using the DGPS +correction and the DGPS generating the data must use the same orbital +positions for the satellite. + +<modified z_count> is just a copy of the same field from +the header. + +<range error> is the pseudorange error in meters for this satellite +as measured by the beacon reference receiver at the epoch indicated +by <modified z_count> + +<range error rate> is the rate of change of pseudorange error in +meters/sec for this satellite as measured by the beacon reference +receiver at the epoch indicated by <modified z_count>. This is +used to calculate pseudorange errors at other epochs, if +required by the GPS receiver. + + +Reference Station Parameters (R) + +Here is the format: + + +R <X-coordinate> <Y-coordinate> <Z-coordinate> + + +Here is an example: + + +R 3746729.40 -5086.23 5144450.67 + + +The coordinates are the position of the station, in meters to two +decimal places, in Earth Centred Earth Fixed coordinates. +These are usually referred to the WGS84 reference frame, but may +be referred to NAD83 in the US (essentially identical to WGS84 for +all except geodesists), or to some other reference frame in other +parts of the world. + + +Datum (D) + +Here is the format: + + +D <dgnss type> <dat> <datum name> [ <dx> <dy> <dz> ] + + +Here is an (artificial) example: + + +D GPS 0 ABC12 25.8 30.5 33.0 + + +<dgnss type> is either GPS or GLONASS. + +<dat> is 0 or 1 and indicates the sense of the offset +shift given by dx, dy, dz. dat = 0 means that the station coordinates +(in the reference message) are referred to a local datum and that +adding dx, dy, dz to that position will render it in GNSS coordinates +(WGS84 for GPS). If dat = 1 then the ref station position is in GNSS +coordinates and adding dx, dy, dz will give it referred to the local +datum. + +<datum name> is a standard name for the datum. + +<dx> <dy> <dz> are offsets to convert from +local datum to GNSS datum or vice versa. These fields are +optional. + + +Constellation Health (C) + +One or more of these follow the header for type 5 messages — one +for each satellite. + +Here is the format: + + +C <sat> <iodl> <health> <snr> <hlth en> <new data> <los warning> + <time to unhealthy> + + +Here is an example: + + +C 29 0 0 53 0 0 0 0 + + +<sat> is the PRN number of the satellite. + +<iodl> is 1 bit. 0 indicates that this information relates to the +satellite information in an accompanying type 1 or type 9 message. + +<health> 0 indicates that the satellite is healthy. Any other value +indicates a problem (coding is not known). + +<snr> gives the carrier/noise ratio of the received signal in the +range 25 to 55 dB(Hz). + +<health en> is 1 bit. If set to 1 it indicates that the +satellite is healthy even if the satellite navigation data says it is +unhealthy. + +<new data> is 1 bit. a 1 indicates that the IOD for this +satellite will soon be updated in type 1 or 9 messages. + +<los warning> is 1 bit. a 1 indicates that the satellite +will shortly go unhealthy. The healthy time remaining is given in the +<time to unhealthy> field. + + +Radio Beacon Almanac (A) + +Here is the format: + + +A <latitude> <longitude> <range> <frequency> <health> <station id> + <bitrate> + + +Here is an example: + + +A 54.1176 -0.0714 100 302.5 0 447 2 + + +<latitude> and <longitude> give the position, in +degrees, of the LF transmitter antenna for the station for which this +is an almanac. North and East are positive. + +<range> is the published range of the station in km. + +<frequency> is the broadcast frequency in kHz. + +<health> is the health of the station for which this is an +almanac. If it is non-zero, the station is issuing suspect data and +should not be used for fixes. The ITU and RTCM104 standards differ +about the mode detailed interpretation of +the <health> field and even about its bit width. + + + +<station id> is the id of the transmitter. This is not the same +as the reference id in the header, the latter being the id of +the reference receiver. + + +<bitrate> indicates the transmitted bitrate. + + +Special Message (T) + +Here is the format: + + +T <text> + + +Here is an example: + + +T THLS TRIAL SERVICE + + +<text> is just a text message sent by the beacon operator. + + +Null (N) + +This just indicates a null message. There are no fields. + +Unknown message (U) + + +This is used to dump message words in hexadecimal when the +message type field doesn't match any of the known ones. + +Here is the format: + + +U <hex-literal> + + +Here is an example: + + +U 0x76423055 + + +The <hex-literal> will represent 32 bits of information, +after parity checks and inversion. The high two bits should be +ignored. + + +Null (N) + +This just indicates a null message. There are no fields. + + + + + +JSON RTCM2 DUMP FORMAT + +Fields are dumped in the order and with the conversions +described above, except that they are wrapped in a single JSON +object per message and appear as attributes of that object. Arrays of +satellite, station, and constellation statistics become arrays of +JSON sub-objects. + +(One exception: The zcount field included in the Sager-format +per-satellite reports in type 1 and 9 messages is omitted from the +JSON version, as it is redundant with the zcount attribute of the +parent object.) + + +RTCM3 DUMP FORMAT + +The support for RTCM104v3 dumping is still incomplete and +buggy. Anyone interested in it should read the source code. + + +SEE ALSO + +gpsd8, +gps1, +libgps3, +libgpsd3, +gpsprof1, +gpsfake1. + + + +COMPATIBILITY NOTE + +In versions of the RTCM2 dump format prior to gpsd 2.28, there was +no trailing sentinel line after each stanza of the Sager-format dump. + + +AUTHOR + +Much of the portion of this text describing RTCM2 was originally +written by John Sager john.sager@btinternet.com in +association with his RTCM2 decoder. Other material comes from the GPSD +project. There is a project page for gpsd +here. + + + + diff --git a/rtcm2_json.c b/rtcm2_json.c new file mode 100644 index 0000000..87a450f --- /dev/null +++ b/rtcm2_json.c @@ -0,0 +1,225 @@ +/**************************************************************************** + +NAME + rtcm2_json.c - deserialize RTCM2 JSON + +DESCRIPTION + This module uses the generic JSON parser to get data from RTCM2 +representations to libgps structures. + +PERMISSIONS + This file is Copyright (c) 2010 by the GPSD project + BSD terms apply: see the file COPYING in the distribution root for details. + +***************************************************************************/ + +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "gps_json.h" + +/* common fields in every RTCM2 message */ + +int json_rtcm2_read(const char *buf, + char *path, size_t pathlen, struct rtcm2_t *rtcm2, + /*@null@*/ const char **endptr) +{ + + static char *stringptrs[NITEMS(rtcm2->words)]; + static char stringstore[sizeof(rtcm2->words) * 2]; + static int stringcount; + +/* *INDENT-OFF* */ +#define RTCM2_HEADER \ + {"class", t_check, .dflt.check = "RTCM2"}, \ + {"type", t_uinteger, .addr.uinteger = &rtcm2->type}, \ + {"device", t_string, .addr.string = path, \ + .len = pathlen}, \ + {"station_id", t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \ + {"zcount", t_real, .addr.real = &rtcm2->zcount, \ + .dflt.real = NAN}, \ + {"seqnum", t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \ + {"length", t_uinteger, .addr.uinteger = &rtcm2->length}, \ + {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth}, + + int status = 0, satcount = 0; + + /*@ -fullinitblock @*/ + const struct json_attr_t rtcm1_satellite[] = { + {"ident", t_uinteger, STRUCTOBJECT(struct rangesat_t, ident)}, + {"udre", t_uinteger, STRUCTOBJECT(struct rangesat_t, udre)}, + {"issuedata", t_uinteger, STRUCTOBJECT(struct rangesat_t, issuedata)}, + {"rangerr", t_real, STRUCTOBJECT(struct rangesat_t, rangerr)}, + {"rangerate", t_real, STRUCTOBJECT(struct rangesat_t, rangerate)}, + {NULL}, + }; + /*@-type@*//* STRUCTARRAY confuses splint */ + const struct json_attr_t json_rtcm1[] = { + RTCM2_HEADER + {"satellites", t_array, STRUCTARRAY(rtcm2->ranges.sat, + rtcm1_satellite, &satcount)}, + {NULL}, + }; + /*@+type@*/ + + const struct json_attr_t json_rtcm3[] = { + RTCM2_HEADER + {"x", t_real, .addr.real = &rtcm2->ecef.x, + .dflt.real = NAN}, + {"y", t_real, .addr.real = &rtcm2->ecef.y, + .dflt.real = NAN}, + {"z", t_real, .addr.real = &rtcm2->ecef.z, + .dflt.real = NAN}, + {NULL}, + }; + + /* + * Beware! Needs to stay synchronized with a corresponding + * nam,e array in the RTCM2 JSON dump code. This interpretation of + * NAVSYSTEM_GALILEO is assumed from RTCM3, it's not actually + * documented in RTCM 2.1. + */ + const struct json_enum_t system_table[] = { + {"GPS", 0}, {"GLONASS", 1}, {"GALILEO", 2}, {"UNKNOWN", 2}, {NULL} + }; + const struct json_attr_t json_rtcm4[] = { + RTCM2_HEADER + {"valid", t_boolean, .addr.boolean = &rtcm2->reference.valid}, + {"system", t_integer, .addr.integer = &rtcm2->reference.system, + .map=system_table}, + {"sense", t_integer, .addr.integer = &rtcm2->reference.sense}, + {"datum", t_string, .addr.string = rtcm2->reference.datum, + .len = sizeof(rtcm2->reference.datum)}, + {"dx", t_real, .addr.real = &rtcm2->reference.dx, + .dflt.real = NAN}, + {"dy", t_real, .addr.real = &rtcm2->reference.dy, + .dflt.real = NAN}, + {"dz", t_real, .addr.real = &rtcm2->reference.dz, + .dflt.real = NAN}, + {NULL}, + }; + + const struct json_attr_t rtcm5_satellite[] = { + {"ident", t_uinteger, STRUCTOBJECT(struct consat_t, ident)}, + {"iodl", t_boolean, STRUCTOBJECT(struct consat_t, iodl)}, + {"health", t_uinteger, STRUCTOBJECT(struct consat_t, health)}, + {"snr", t_integer, STRUCTOBJECT(struct consat_t, snr)}, + {"health_en", t_boolean, STRUCTOBJECT(struct consat_t, health_en)}, + {"new_data", t_boolean, STRUCTOBJECT(struct consat_t, new_data)}, + {"los_warning", t_boolean, STRUCTOBJECT(struct consat_t, los_warning)}, + {"tou", t_uinteger, STRUCTOBJECT(struct consat_t, tou)}, + {NULL}, + }; + /*@-type@*//* STRUCTARRAY confuses splint */ + const struct json_attr_t json_rtcm5[] = { + RTCM2_HEADER + {"satellites", t_array, STRUCTARRAY(rtcm2->conhealth.sat, + rtcm5_satellite, &satcount)}, + {NULL}, + }; + /*@+type@*/ + + const struct json_attr_t json_rtcm6[] = { + RTCM2_HEADER + // No-op or keepalive message + {NULL}, + }; + + const struct json_attr_t rtcm7_satellite[] = { + {"lat", t_real, STRUCTOBJECT(struct station_t, latitude)}, + {"lon", t_real, STRUCTOBJECT(struct station_t, longitude)}, + {"range", t_uinteger, STRUCTOBJECT(struct station_t, range)}, + {"frequency", t_real, STRUCTOBJECT(struct station_t, frequency)}, + {"health", t_uinteger, STRUCTOBJECT(struct station_t, health)}, + {"station_id", t_uinteger, STRUCTOBJECT(struct station_t, station_id)}, + {"bitrate", t_uinteger, STRUCTOBJECT(struct station_t, bitrate)}, + {NULL}, + }; + /*@-type@*//* STRUCTARRAY confuses splint */ + const struct json_attr_t json_rtcm7[] = { + RTCM2_HEADER + {"satellites", t_array, STRUCTARRAY(rtcm2->almanac.station, + rtcm7_satellite, &satcount)}, + {NULL}, + }; + /*@+type@*/ + + const struct json_attr_t json_rtcm16[] = { + RTCM2_HEADER + {"message", t_string, .addr.string = rtcm2->message, + .len = sizeof(rtcm2->message)}, + {NULL}, + }; + + /*@-type@*//* complex union array initislizations confuses splint */ + const struct json_attr_t json_rtcm2_fallback[] = { + RTCM2_HEADER + {"data", t_array, .addr.array.element_type = t_string, + .addr.array.arr.strings.ptrs = stringptrs, + .addr.array.arr.strings.store = stringstore, + .addr.array.arr.strings.storelen = sizeof(stringstore), + .addr.array.count = &stringcount, + .addr.array.maxlen = NITEMS(stringptrs)}, + {NULL}, + }; + /*@+type@*/ + /*@ +fullinitblock @*/ + +#undef RTCM2_HEADER +/* *INDENT-ON* */ + + memset(rtcm2, '\0', sizeof(struct rtcm2_t)); + + if (strstr(buf, "\"type\":1,") != NULL + || strstr(buf, "\"type\":9,") != NULL) { + status = json_read_object(buf, json_rtcm1, endptr); + if (status == 0) + rtcm2->ranges.nentries = (unsigned)satcount; + } else if (strstr(buf, "\"type\":3,") != NULL) { + status = json_read_object(buf, json_rtcm3, endptr); + if (status == 0) { + rtcm2->ecef.valid = (isnan(rtcm2->ecef.x) == 0) + && (isnan(rtcm2->ecef.y) == 0) && (isnan(rtcm2->ecef.z) == 0); + } + } else if (strstr(buf, "\"type\":4,") != NULL) { + status = json_read_object(buf, json_rtcm4, endptr); + if (status == 0) + rtcm2->reference.valid = (isnan(rtcm2->reference.dx) == 0) + && (isnan(rtcm2->reference.dy) == 0) + && (isnan(rtcm2->reference.dz) == 0); + } else if (strstr(buf, "\"type\":5,") != NULL) { + status = json_read_object(buf, json_rtcm5, endptr); + if (status == 0) + rtcm2->conhealth.nentries = (unsigned)satcount; + } else if (strstr(buf, "\"type\":6,") != NULL) { + status = json_read_object(buf, json_rtcm6, endptr); + } else if (strstr(buf, "\"type\":7,") != NULL) { + status = json_read_object(buf, json_rtcm7, endptr); + if (status == 0) + rtcm2->almanac.nentries = (unsigned)satcount; + } else if (strstr(buf, "\"type\":16,") != NULL) { + status = json_read_object(buf, json_rtcm16, endptr); + } else { + int n; + status = json_read_object(buf, json_rtcm2_fallback, endptr); + for (n = 0; n < NITEMS(rtcm2->words); n++) { + if (n >= stringcount) { + rtcm2->words[n] = 0; + } else { + unsigned int u; + int fldcount = sscanf(stringptrs[n], "0x%08x\n", &u); + if (fldcount != 1) + return JSON_ERR_MISC; + else + rtcm2->words[n] = (isgps30bits_t) u; + } + } + } + return status; +} + +/* rtcm2_json.c ends here */ diff --git a/serial.c b/serial.c new file mode 100644 index 0000000..ec37836 --- /dev/null +++ b/serial.c @@ -0,0 +1,518 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include +#include + +#include "gpsd_config.h" + +#ifdef HAVE_BLUEZ +#include +#include +#include + +#include +#include +#include +#include +#endif + +#if defined(HAVE_SYS_MODEM_H) +#include +#endif /* HAVE_SYS_MODEM_H */ + +#include "gpsd.h" + +/* Workaround for HP-UX 11.23, which is missing CRTSCTS */ +#ifndef CRTSCTS +# ifdef CNEW_RTSCTS +# define CRTSCTS CNEW_RTSCTS +# else +# define CRTSCTS 0 +# endif /* CNEW_RTSCTS */ +#endif /* !CRTSCTS */ + +static sourcetype_t gpsd_classify(const char *path) +/* figure out what kind of device we're looking at */ +{ + struct stat sb; + + if (stat(path, &sb) == -1) + return source_unknown; + else if (S_ISREG(sb.st_mode)) + return source_blockdev; + /* this assumes we won't get UDP from a filesystem socket */ + else if (S_ISSOCK(sb.st_mode)) + return source_tcp; + else if (S_ISCHR(sb.st_mode)) { + sourcetype_t devtype = source_unknown; +#ifdef __linux__ + /* Linux major device numbers live here + * ftp://ftp.kernel.org/pub/linux/docs/device-list/devices-2.6+.txt + */ + int devmajor = major(sb.st_rdev); + if (devmajor == 4) + devtype = source_rs232; + else if (devmajor == 188) + devtype = source_usb; + else if (devmajor == 216 || devtype == 217) + devtype = source_bluetooth; + else if (devmajor == 3 || (devmajor >= 136 && devmajor <= 143)) + devtype = source_pty; +#endif /* __linux__ */ + return devtype; + } else + return source_unknown; +} + +void gpsd_tty_init(struct gps_device_t *session) +/* to be called on allocating a device */ +{ + /* mark GPS fd closed and its baud rate unknown */ + session->gpsdata.gps_fd = -1; + session->saved_baud = -1; +#ifdef NTPSHM_ENABLE + /* mark NTPD shared memory segments as unused */ + session->shmindex = -1; +# ifdef PPS_ENABLE + session->shmTimeP = -1; +# endif /* PPS_ENABLE */ +#endif /* NTPSHM_ENABLE */ + session->zerokill = false; + session->reawake = 0; +} + +#if defined(__CYGWIN__) +/* Workaround for Cygwin, which is missing cfmakeraw */ +/* Pasted from man page; added in serial.c arbitrarily */ +void cfmakeraw(struct termios *termios_p) +{ + termios_p->c_iflag &= + ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + termios_p->c_oflag &= ~OPOST; + termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + termios_p->c_cflag &= ~(CSIZE | PARENB); + termios_p->c_cflag |= CS8; +} +#endif /* defined(__CYGWIN__) */ + +speed_t gpsd_get_speed(const struct termios *ttyctl) +{ + speed_t code = cfgetospeed(ttyctl); + switch (code) { + case B0: + return (0); + case B300: + return (300); + case B1200: + return (1200); + case B2400: + return (2400); + case B4800: + return (4800); + case B9600: + return (9600); + case B19200: + return (19200); + case B38400: + return (38400); + case B57600: + return (57600); + default: + return (115200); + } +} + +bool gpsd_set_raw(struct gps_device_t * session) +{ + (void)cfmakeraw(&session->ttyset); + if (tcsetattr(session->gpsdata.gps_fd, TCIOFLUSH, &session->ttyset) == -1) { + gpsd_report(LOG_ERROR, + "error changing port attributes: %s\n", strerror(errno)); + return false; + } + + return true; +} + +void gpsd_set_speed(struct gps_device_t *session, + speed_t speed, char parity, unsigned int stopbits) +{ + speed_t rate; + + /* + * Yes, you can set speeds that aren't in the hunt loop. If you + * do this, and you aren't on Linux where baud rate is preserved + * across port closings, you've screwed yourself. Don't do that! + */ + if (speed < 300) + rate = B0; + else if (speed < 1200) + rate = B300; + else if (speed < 2400) + rate = B1200; + else if (speed < 4800) + rate = B2400; + else if (speed < 9600) + rate = B4800; + else if (speed < 19200) + rate = B9600; + else if (speed < 38400) + rate = B19200; + else if (speed < 57600) + rate = B38400; + else if (speed < 115200) + rate = B57600; + else + rate = B115200; + + if (rate != cfgetispeed(&session->ttyset) + || parity != session->gpsdata.dev.parity + || stopbits != session->gpsdata.dev.stopbits) { + + /* + * Don't mess with this conditional! Speed zero is supposed to mean + * to leave the port speed at whatever it currently is. This leads + * to excellent behavior on Linux, which preserves baudrate across + * serial device closes - it means that if you've opended this + * device before you typically don't have to hunt at all because + * it's still at the same speed you left it - you'll typically + * get packet lock within 1.5 seconds. Alas, the BSDs and OS X + * aren't so nice. + */ + /*@ignore@*/ + if (rate != B0) { + (void)cfsetispeed(&session->ttyset, rate); + (void)cfsetospeed(&session->ttyset, rate); + } + /*@end@*/ + session->ttyset.c_iflag &= ~(PARMRK | INPCK); + session->ttyset.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD); + session->ttyset.c_cflag |= (stopbits == 2 ? CS7 | CSTOPB : CS8); + switch (parity) { + case 'E': + case (char)2: + session->ttyset.c_iflag |= INPCK; + session->ttyset.c_cflag |= PARENB; + break; + case 'O': + case (char)1: + session->ttyset.c_iflag |= INPCK; + session->ttyset.c_cflag |= PARENB | PARODD; + break; + } + if (tcsetattr(session->gpsdata.gps_fd, TCSANOW, &session->ttyset) != + 0) + return; + + /* + * Serious black magic begins here. Getting this code wrong can cause + * failures to lock to a correct speed, and not clean reproducible + * failures but flukey hardware- and timing-dependent ones. So + * be very sure you know what you're doing before hacking it, and + * test thoroughly. + * + * The fundamental problem here is that serial devices take time + * to settle into a new baud rate after tcsetattr() is issued. Until + * they do so, input will be arbitarily garbled. Normally this + * is not a big problem, but in our hunt loop the garbling can trash + * a long enough prefix of each sample to prevent detection of a + * packet header. We could address the symptom by making the sample + * size enough larger that subtracting the maximum length of garble + * would still leave a sample longer than the maximum packet size. + * But it's better (and more efficient) to address the disease. + * + * In theory, one might think that not even a tcflush() call would + * be needed, with tcsetattr() delaying its return until the device + * is in a good state. For simple devices like a 14550 UART that + * have fixed response timings this may even work, if the driver + * writer was smart enough to delay the return by the right number + * of milliseconds after poking the device port(s). + * + * Problems may arise if the driver's timings are off. Or we may + * be talking to a USB device like the pl2303 commonly used in GPS + * mice; on these, the change will not happen immediately because + * it has to be sent as a message to the external processor that + * has to act upon it, and that processor may still have buffered + * data in its own FIFO. In this case the expected delay may be + * too large and too variable (depending on the details of how the + * USB device is integrated with its symbiont hardware) to be put + * in the driver. + * + * So, somehow, we have to introduce a delay after tcsatattr() + * returns sufficient to allow *any* device to settle. On the other + * hand, a really long delay will make gpsd device registration + * unpleasantly laggy. + * + * The classic way to address this is with a tcflush(), counting + * on it to clear the device FIFO. But that call may clear only the + * kernel buffers, not the device's hardware FIFO, so it may not + * be sufficient by itself. + * + * flush followed by a 200-millisecond delay followed by flush has + * been found to work reliably on the pl2303. It is also known + * from testing that a 100-millisec delay is too short, allowing + * occasional failure to lock. + */ + (void)tcflush(session->gpsdata.gps_fd, TCIOFLUSH); + (void)usleep(200000); + (void)tcflush(session->gpsdata.gps_fd, TCIOFLUSH); + } + gpsd_report(LOG_INF, "speed %u, %d%c%d\n", + gpsd_get_speed(&session->ttyset), 9 - stopbits, parity, + stopbits); + + session->gpsdata.dev.baudrate = (unsigned int)speed; + session->gpsdata.dev.parity = parity; + session->gpsdata.dev.stopbits = stopbits; + + if (!session->context->readonly) { + /* + * The device might need a wakeup string before it will send data. + * If we don't know the device type, ship it every driver's wakeup + * in hopes it will respond. + */ + if (isatty(session->gpsdata.gps_fd) != 0 + && !session->context->readonly) { + const struct gps_type_t **dp; + if (session->device_type == NULL) { + for (dp = gpsd_drivers; *dp; dp++) + if ((*dp)->event_hook != NULL) + (*dp)->event_hook(session, event_wakeup); + } else if (session->device_type->event_hook != NULL) + session->device_type->event_hook(session, event_wakeup); + } + } + packet_reset(&session->packet); +} + +int gpsd_open(struct gps_device_t *session) +{ + mode_t mode = (mode_t) O_RDWR; + + session->sourcetype = gpsd_classify(session->gpsdata.dev.path); + + /*@ -boolops -type @*/ + if (session->context->readonly + || (session->sourcetype <= source_blockdev)) { + mode = (mode_t) O_RDONLY; + gpsd_report(LOG_INF, + "opening read-only GPS data source type %d and at '%s'\n", + (int)session->sourcetype, session->gpsdata.dev.path); + } else { + gpsd_report(LOG_INF, + "opening GPS data source type %d at '%s'\n", + (int)session->sourcetype, session->gpsdata.dev.path); + } + /*@ +boolops +type @*/ +#ifdef HAVE_BLUEZ + if (bachk(session->gpsdata.dev.path) == 0) { + session->gpsdata.gps_fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + struct sockaddr_rc addr = { 0 }; + addr.rc_family = AF_BLUETOOTH; + addr.rc_channel = (uint8_t) 1; + str2ba(session->gpsdata.dev.path, &addr.rc_bdaddr); + if (connect(session->gpsdata.gps_fd, (struct sockaddr *) &addr, sizeof (addr)) == -1) { + if (errno != EINPROGRESS && errno != EAGAIN) { + gpsd_report(LOG_ERROR, "bluetooth socket connect failed: %s\n", + strerror(errno)); + return -1; + } + gpsd_report(LOG_ERROR, "bluetooth socket connect in progress or again : %s\n", + strerror(errno)); + } + (void)fcntl(session->gpsdata.gps_fd, F_SETFL, (int)mode | O_NONBLOCK); + gpsd_report(LOG_PROG, "bluez device open success: %s %s\n", + session->gpsdata.dev.path, strerror(errno)); + } else +#endif /* BLUEZ */ + { + if ((session->gpsdata.gps_fd = + open(session->gpsdata.dev.path, + (int)(mode | O_NONBLOCK | O_NOCTTY))) == -1) { + gpsd_report(LOG_ERROR, + "device open failed: %s - retrying read-only\n", + strerror(errno)); + if ((session->gpsdata.gps_fd = + open(session->gpsdata.dev.path, + O_RDONLY | O_NONBLOCK | O_NOCTTY)) == -1) { + gpsd_report(LOG_ERROR, "read-only device open failed: %s\n", + strerror(errno)); + return -1; + } + gpsd_report(LOG_PROG, "file device open success: %s\n", + strerror(errno)); + } + } + +#ifdef FIXED_PORT_SPEED + session->saved_baud = FIXED_PORT_SPEED; +#endif + + if (session->saved_baud != -1) { + /*@i@*/ (void) + cfsetispeed(&session->ttyset, (speed_t) session->saved_baud); + /*@i@*/ (void) + cfsetospeed(&session->ttyset, (speed_t) session->saved_baud); + (void)tcsetattr(session->gpsdata.gps_fd, TCSANOW, &session->ttyset); + (void)tcflush(session->gpsdata.gps_fd, TCIOFLUSH); + } + + session->packet.type = BAD_PACKET; + if (isatty(session->gpsdata.gps_fd) != 0) { + /* Save original terminal parameters */ + if (tcgetattr(session->gpsdata.gps_fd, &session->ttyset_old) != 0) + return -1; + (void)memcpy(&session->ttyset, + &session->ttyset_old, sizeof(session->ttyset)); + /* + * Only block until we get at least one character, whatever the + * third arg of read(2) says. + */ + /*@ ignore @*/ + memset(session->ttyset.c_cc, 0, sizeof(session->ttyset.c_cc)); + session->ttyset.c_cc[VMIN] = 1; + /*@ end @*/ + /* + * Tip from Chris Kuethe: the FIDI chip used in the Trip-Nav + * 200 (and possibly other USB GPSes) gets completely hosed + * in the presence of flow control. Thus, turn off CRTSCTS. + */ + session->ttyset.c_cflag &= ~(PARENB | PARODD | CRTSCTS); + session->ttyset.c_cflag |= CREAD | CLOCAL; + session->ttyset.c_iflag = session->ttyset.c_oflag = + session->ttyset.c_lflag = (tcflag_t) 0; + + session->baudindex = 0; + gpsd_set_speed(session, gpsd_get_speed(&session->ttyset_old), 'N', 1); + } + session->is_serial = true; + gpsd_report(LOG_SPIN, "open(%s) -> %d in gpsd_open()\n", + session->gpsdata.dev.path, session->gpsdata.gps_fd); + return session->gpsdata.gps_fd; +} + +ssize_t gpsd_write(struct gps_device_t * session, void const *buf, size_t len) +{ + ssize_t status; + bool ok; + if (session == NULL || + session->context == NULL || session->context->readonly) + return 0; + status = write(session->gpsdata.gps_fd, buf, len); + ok = (status == (ssize_t) len); + (void)tcdrain(session->gpsdata.gps_fd); + /* no test here now, always print as hex */ + gpsd_report(LOG_IO, "=> GPS: %s%s\n", + gpsd_hexdump_wrapper(buf, len, LOG_IO), ok ? "" : " FAILED"); + return status; +} + +/* + * This constant controls how long the packet sniffer will spend looking + * for a packet leader before it gives up. It *must* be larger than + * MAX_PACKET_LENGTH or we risk never syncing up at all. Large values + * will produce annoying startup lag. + */ +#define SNIFF_RETRIES 256 + +bool gpsd_next_hunt_setting(struct gps_device_t * session) +/* advance to the next hunt setting */ +{ +#ifdef FIXED_PORT_SPEED + /* just the one fixed port speed... */ + static unsigned int rates[] = { FIXED_PORT_SPEED }; +#else /* FIXED_PORT_SPEED not defined */ + /* every rate we're likely to see on a GPS */ + static unsigned int rates[] = + { 0, 4800, 9600, 19200, 38400, 57600, 115200 }; +#endif /* FIXED_PORT_SPEED defined */ + + /* don't waste time in the hunt loop if this is not actually a tty */ + if (isatty(session->gpsdata.gps_fd) == 0) + return false; + + if (session->packet.retry_counter++ >= SNIFF_RETRIES) { + session->packet.retry_counter = 0; + if (session->baudindex++ >= + (unsigned int)(sizeof(rates) / sizeof(rates[0])) - 1) { + session->baudindex = 0; + if (session->gpsdata.dev.stopbits++ >= 2) + return false; /* hunt is over, no sync */ + } + gpsd_set_speed(session, + rates[session->baudindex], + session->gpsdata.dev.parity, + session->gpsdata.dev.stopbits); + } + + return true; /* keep hunting */ + +} + +void gpsd_assert_sync(struct gps_device_t *session) +/* to be called when we want to register that we've synced with a device */ +{ + /* + * We've achieved first sync with the device. Remember the + * baudrate so we can try it first next time this device + * is opened. + */ + if (session->saved_baud == -1) + session->saved_baud = (int)cfgetispeed(&session->ttyset); + +#ifdef NTPSHM_ENABLE + /* + * Now is the right time to grab the shared memory segment(s) + * to communicate the navigation message derived and (possibly) + * 1pps derived time data to ntpd. + */ + + /* do not start more than one ntp thread */ + if (!(session->shmindex >= 0)) + ntpd_link_activate(session); + + gpsd_report(LOG_INF, "NTPD ntpd_link_activate: %d\n", + (int)session->shmindex >= 0); + +#endif /* NTPSHM_ENABLE */ +} + +void gpsd_close(struct gps_device_t *session) +{ + if (session->gpsdata.gps_fd != -1) { + (void)tcdrain(session->gpsdata.gps_fd); + if (isatty(session->gpsdata.gps_fd) != 0) { + /* force hangup on close on systems that don't do HUPCL properly */ + /*@ ignore @*/ + (void)cfsetispeed(&session->ttyset, (speed_t) B0); + (void)cfsetospeed(&session->ttyset, (speed_t) B0); + /*@ end @*/ + (void)tcsetattr(session->gpsdata.gps_fd, TCSANOW, + &session->ttyset); + } + /* this is the clean way to do it */ + session->ttyset_old.c_cflag |= HUPCL; + /* keep the most recent baud rate */ + /*@ ignore @*/ + (void)cfsetispeed(&session->ttyset_old, + (speed_t) session->gpsdata.dev.baudrate); + (void)cfsetospeed(&session->ttyset_old, + (speed_t) session->gpsdata.dev.baudrate); + /*@ end @*/ + (void)tcsetattr(session->gpsdata.gps_fd, TCSANOW, + &session->ttyset_old); + gpsd_report(LOG_SPIN, "close(%d) in gpsd_close(%s)\n", + session->gpsdata.gps_fd, session->gpsdata.dev.path); + (void)close(session->gpsdata.gps_fd); + session->gpsdata.gps_fd = -1; + } +} diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..b4ddc6d --- /dev/null +++ b/setup.py @@ -0,0 +1,82 @@ +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# Creates build/lib.linux-${arch}-${pyvers}/gpspacket.so, +# where ${arch} is an architecture and ${pyvers} is a Python version. + +from distutils.core import setup, Extension + +import os +import sys + +# For VPATH builds, this script must be run from $(srcdir) with the +# abs_builddir environment variable set to the location of the build +# directory. This is necessary because Python's distutils package +# does not have built-in support for VPATH builds. + +# These dependencies are enforced here and not in the Makefile to make +# it easier to build the Python parts without building everything else +# (the user can run 'python setup.py' without having to run 'make'). +needed_files = ['gpsd.h', 'packet_names.h'] +created_files = [] + +manpages = [] +try: + where = sys.argv.index('--mangenerator') + # Doesn't matter what it is, just that we have one + if sys.argv[where+1]: + manpages=[('share/man/man1', ['gpscat.1', 'gpsfake.1','gpsprof.1', + 'xgps.1', 'xgpsspeed.1'])] + print("Installing manual pages, generator is %s" %( sys.argv[where+1])) + sys.argv = sys.argv[:where] + sys.argv[where+2:] +except ValueError: + pass +if not manpages: + print("No XML processor, omitting manual-page installation.") + +MAKE = ("MAKE" in os.environ) and os.environ["MAKE"] or "make" +if not 'clean' in sys.argv: + abs_builddir = ("abs_builddir" in os.environ) and os.environ["abs_builddir"] or "" + if not os.path.exists(os.path.join(abs_builddir, 'gpsd_config.h')): + sys.stderr.write('\nPlease run configure first!\n') + sys.exit(1) + + cdcmd = abs_builddir and ("cd '" + abs_builddir + "' && ") or "" + for f_name in needed_files: + # TODO: Shouldn't make be run unconditionally in case a + # dependency of f_name has been updated? + if not os.path.exists(os.path.join(abs_builddir, f_name)): + cmd = cdcmd + MAKE + " '" + f_name + "'" + print(cmd) + make_out = os.popen(cmd) + print(make_out.read()) + if make_out.close(): + sys.exit(1) + created_files.append(f_name) + +gpspacket_sources = ["gpspacket.c", "packet.c", "isgps.c", + "driver_rtcm2.c", "strl.c", "hex.c", "crc24q.c"] +include_dirs = [ os.path.realpath(os.path.dirname(__file__)) ] +version_out = os.popen(MAKE + " -s version") +version = version_out.read() +print(version) +if version_out.close(): + sys.exit(1) +version = version.split('\n')[-2] +version = version.strip() + +setup( name="gps", + version=version, + description='Python libraries for the gpsd service daemon', + url="http://gpsd.berlios.de/", + author='the GPSD project', + author_email="gpsd-dev@lists.berlios.de", + license="BSD", + ext_modules=[ + Extension("gps.packet", gpspacket_sources, include_dirs=include_dirs), + Extension("gps.clienthelpers", ["gpsclient.c", "geoid.c", "gpsdclient.c", "strl.c"], include_dirs=include_dirs) + ], + packages = ['gps'], + scripts = ['gpscat','gpsfake','gpsprof', 'xgps', 'xgpsspeed'], + data_files= manpages + ) diff --git a/shared_json.c b/shared_json.c new file mode 100644 index 0000000..f7a2f9f --- /dev/null +++ b/shared_json.c @@ -0,0 +1,100 @@ +/**************************************************************************** + +NAME + shared_json.c - move data between in-core and JSON structures + +DESCRIPTION + This module uses the generic JSON parser to get data from JSON +representations to gps.h structures. These functions are used in both +the daemon and the client library. + +PERMISSIONS + Written by Eric S. Raymond, 2009 + This file is Copyright (c) 2010 by the GPSD project + BSD terms apply: see the file COPYING in the distribution root for details. + +***************************************************************************/ + +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "gps_json.h" + +int json_device_read(const char *buf, + /*@out@*/ struct devconfig_t *dev, + /*@null@*/ const char **endptr) +{ + /*@ -fullinitblock @*/ + /* *INDENT-OFF* */ + const struct json_attr_t json_attrs_device[] = { + {"class", t_check, .dflt.check = "DEVICE"}, + + {"path", t_string, .addr.string = dev->path, + .len = sizeof(dev->path)}, + {"activated", t_real, .addr.real = &dev->activated}, + {"flags", t_integer, .addr.integer = &dev->flags}, + {"driver", t_string, .addr.string = dev->driver, + .len = sizeof(dev->driver)}, + {"subtype", t_string, .addr.string = dev->subtype, + .len = sizeof(dev->subtype)}, + {"native", t_integer, .addr.integer = &dev->driver_mode, + .dflt.integer = DEVDEFAULT_NATIVE}, + {"bps", t_uinteger, .addr.uinteger = &dev->baudrate, + .dflt.uinteger = DEVDEFAULT_BPS}, + {"parity", t_character, .addr.character = &dev->parity, + .dflt.character = DEVDEFAULT_PARITY}, + {"stopbits", t_uinteger, .addr.uinteger = &dev->stopbits, + .dflt.uinteger = DEVDEFAULT_STOPBITS}, + {"cycle", t_real, .addr.real = &dev->cycle, + .dflt.real = NAN}, + {"mincycle", t_real, .addr.real = &dev->mincycle, + .dflt.real = NAN}, + {NULL}, + }; + /* *INDENT-ON* */ + /*@ +fullinitblock @*/ + int status; + + status = json_read_object(buf, json_attrs_device, endptr); + if (status != 0) + return status; + + return 0; +} + +int json_watch_read(const char *buf, + /*@out@*/ struct policy_t *ccp, + /*@null@*/ const char **endptr) +{ + /*@ -fullinitblock @*/ + /* *INDENT-OFF* */ + struct json_attr_t chanconfig_attrs[] = { + {"class", t_check, .dflt.check = "WATCH"}, + + {"enable", t_boolean, .addr.boolean = &ccp->watcher, + .dflt.boolean = true}, + {"json", t_boolean, .addr.boolean = &ccp->json, + .nodefault = true}, + {"raw", t_integer, .addr.integer = &ccp->raw, + .nodefault = true}, + {"nmea", t_boolean, .addr.boolean = &ccp->nmea, + .nodefault = true}, + {"scaled", t_boolean, .addr.boolean = &ccp->scaled}, + {"timing", t_boolean, .addr.boolean = &ccp->timing}, + {"device", t_string, .addr.string = ccp->devpath, + .len = sizeof(ccp->devpath)}, + {NULL}, + }; + /* *INDENT-ON* */ + /*@ +fullinitblock @*/ + int status; + + status = json_read_object(buf, chanconfig_attrs, endptr); + return status; +} + +/* shared_json.c ends here */ diff --git a/sockaddr.h b/sockaddr.h new file mode 100644 index 0000000..61866d0 --- /dev/null +++ b/sockaddr.h @@ -0,0 +1,9 @@ +/* klugey def'n of a socket address struct helps hide IPV4 vs. IPV6 ugliness */ + +typedef union sockaddr_u { + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr_in6 sa_in6; +} sockaddr_t; + +/* sockaddr.h ends here */ diff --git a/srec.xml b/srec.xml new file mode 100644 index 0000000..987f84a --- /dev/null +++ b/srec.xml @@ -0,0 +1,310 @@ + + + + +15 Jul 2005 + +srec +5 +The GPSD Project +GPSD Documentation + + +srec +Motorola S-record record and file format + +DESCRIPTION + +Motorola S-records are a form of simple ASCII encoding for +binary data. This format is commonly used for firmware uploads to +GPSes, industrial robots, and other kinds of microcontroller-driven +hardware. It has several convenient properties, including +inspectability, easy editing with any text editor, and checksumming +for verification of transmission across noisy serial lines. + +An S-record file consists of a sequence of specially formatted +ASCII character strings. An S-record will be less than or equal to 78 +bytes in length. + +The order of S-records within a file is of no significance and +no particular order may be assumed. + +The general format of an S-record follows: + + ++-------------------//------------------//-----------------------+ +| type | count | address | data | checksum | ++-------------------//------------------//-----------------------+ + + + + +type +A char[2] field. These characters +describe the type of record (S0, S1, S2, S3, S5, S7, S8, or +S9). + + + +count +A char[2] field. These characters when paired and +interpreted as a big-endian hexadecimal integer, display the count of remaining +character pairs in the record. + + + +address +A char[4,6, or 8] field. These characters grouped and +interpreted as a big-endian hexadecimal integer, display the address +at which the data field is to be loaded into memory. The length of the +field depends on the number of bytes necessary to hold the address. A +2-byte address uses 4 characters, a 3-byte address uses 6 characters, +and a 4-byte address uses 8 characters. + + + +data +A char [0-64] field. These characters when paired and +interpreted as hexadecimal values represent the memory loadable data +or descriptive information. + + + +checksum +A char[2] field. These characters when paired and +interpreted as a big-endian hexadecimal integer display the least +significant byte of the ones complement of the sum of the byte values +represented by the pairs of characters making up the count, the +address, and the data fields. + + + +Each record is terminated with a line feed. If any additional or +different record terminator(s) or delay characters are needed during +transmission to the target system it is the responsibility of the +transmitting program to provide them. + +There are 9 record types, as follows: + + + +S0 + +The type of record is 'S0' (0x5330). The address field +is unused and will be filled with zeros (0x0000). The header +information within the data field is divided into the following +subfields. + + +mname is char[20] and is the module name. +ver is char[2] and is the version number. +rev is char[2] and is the revision number. +description is char[0-36] and is a text comment. + + +Each of the subfields is composed of ASCII bytes whose +associated characters, when paired, represent one byte hexadecimal +values in the case of the version and revision numbers, or represent +the hexadecimal values of the ASCII characters comprising the module +name and description. + + + + +S1 +The type of record field is 'S1' (0x5331). The address +field is interpreted as a 2-byte big-endian address. The data field is +composed of memory loadable data. + + + +S2 +The type of record field is 'S2' (0x5332). The address +field is interpreted as a 3-byte big-endian address. The data field is +composed of memory loadable data. + + + +S3 +The type of record field is 'S3' (0x5333). The address +field is interpreted as a 4-byte big-endian address. The data field is +composed of memory loadable data. + + + +S5 +The type of record field is 'S5' (0x5335). The address +field is interpreted as a 2-byte big-endian value and contains the +count of S1, S2, and S3 records previously transmitted. There is no +data field. + + + +S7 +The type of record field is 'S7' (0x5337). The address +field contains the starting execution address and is interpreted as a +4-byte big-endian address. There is no data field. + + + +S8 +The type of record field is 'S8' (0x5338). The address +field contains the starting execution address and is interpreted as a +3-byte big-endian address. There is no data field. + + + +S9 +The type of record field is 'S9' (0x5339). The address +field contains the starting execution address and is interpreted as a +2-byte big-endian address. There is no data field. + + + + +EXAMPLE + +Shown below is a typical S-record format file. + + + S00600004844521B + S1130000285F245F2212226A000424290008237C2A + S11300100002000800082629001853812341001813 + S113002041E900084E42234300182342000824A952 + S107003000144ED492 + S5030004F8 + S9030000FC + + +The file consists of one S0 record, four S1 records, one S5 +record and an S9 record. + +The S0 record is comprised as follows: + + +S0 S-record type S0, indicating it is a header +record. + +06 Hexadecimal 06 (decimal 6), indicating that six +character pairs (or ASCII bytes) follow. + +00 00 Four character 2-byte address field, zeroes in +this example. + +48 44 52 ASCII H, D, and R - "HDR". + +1B The checksum. + + + The first S1 record is comprised as follows: + + +S1 S-record type S1, indicating it is a data record to +be loaded at a 2-byte address. + +13 Hexadecimal 13 (decimal 19), indicating that +nineteen character pairs, representing a 2 byte address, 16 bytes of +binary data, and a 1 byte checksum, follow. + +00 00 Four character 2-byte address field; hexidecimal +address 0x0000, where the data which follows is to be +loaded. + +28 5F 24 5F 22 12 22 6A 00 04 24 29 00 08 23 7C +Sixteen character pairs representing the actual binary data. + + +2A The checksum. + + +The second and third S1 records each contain 0x13 (19) character +pairs and are ended with checksums of 13 and 52, respectively. The +fourth S1 record contains 07 character pairs and has a checksum of +92. + +The S5 record is comprised as follows: + + +S5 S-record type S5, indicating it is a count record +indicating the number of S1 records + +03 Hexadecimal 03 (decimal 3), indicating that three +character pairs follow. + +00 04 Hexadecimal 0004 (decimal 4), indicating that +there are four data records previous to this record. + +F8 The checksum. + + + +The S9 record is comprised as follows: + + +S9 S-record type S9, indicating it is a termination +record. + +03 Hexadecimal 03 (decimal 3), indicating that three +character pairs follow. + +00 00 The address field, hexadecimal 0 (decimal 0) +indicating the starting execution address. + +FC The checksum. + + + +NOTES + + + There isn't any evidence that Motorola ever + made use of the header information within the data field of the S0 + record, as described above. This may have been used by some third + party vendors. + +The Unix manual page on S-records is the only place that a + 78-byte limit on total record length or 64-byte limit on data + length is documented. These values shouldn't be trusted for the + general case. + + The count field can have values in the range of 0x3 + (2 bytes of address + 1 byte checksum = 3, a not very useful + record) to 0xff; this is the count of remaining character + pairs, including checksum. + + If you write code to convert S-Records, you should + always assume that a record can be as long as 514 (decimal) + characters in length (255 * 2 = 510, plus 4 characters for the + type and count fields), plus any terminating character(s). That + is, in establishing an input buffer in C, you would declare it to + be an array of 515 chars, thus leaving room for the terminating + null character. + + + +SEE ALSO + +gpsd8, +gps1, +libgps3, +libgpsd3, +gpsfake1. +gpsprof1. + + + +AUTHOR + +From an anonymous web page, itself claiming to have been derived +from an old Unix manual page. Now maintained by the the GPSD +project, which added endianness clarifications. +There is a project page for gpsd here. + + + diff --git a/srecord.c b/srecord.c new file mode 100644 index 0000000..259e0f3 --- /dev/null +++ b/srecord.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2005 Chris Kuethe + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include + +#include "gpsd.h" + +/* + * See srec(5) for a description of this format. + * We read and write 4-byte addresses. + * S0: Comments + * S3: Memory Loadable Data, 4byte address + * S5: Count of S1, S2 and S3 Records + * S7: starting execution address interpreted as a 4-byte address + */ +#define MAX_BYTES_PER_RECORD 16 + +/* + * bin2srec: turn a chunk of binary into an S-record + * offset: used to specify load address + * num: up to MAX_BYTES_PER_RECORD bytes can be encoded at one time + * bytes are read from bbuf and a ready-to-go srecord is placed in sbuf + */ +int +bin2srec(unsigned int type, unsigned int offset, unsigned int num, + unsigned char *bbuf, unsigned char *sbuf) +{ + unsigned char abuf[MAX_BYTES_PER_RECORD * 2 + 2], sum; + size_t len; + + if ((num < 1) || (num > MAX_BYTES_PER_RECORD)) + return -1; + + len = (size_t) (4 + num + 1); + memset(abuf, 0, sizeof(abuf)); + hexdump((size_t) num, bbuf, abuf); + sum = sr_sum((unsigned int)len, offset, bbuf); + (void)snprintf((char *)sbuf, MAX_BYTES_PER_RECORD * 2 + 17, + "S%u%02X%08X%s%02X\r\n", + type, (unsigned)len, offset, (char *)abuf, (unsigned)sum); + return 0; +} + +int srec_hdr(unsigned int num, unsigned char *bbuf, unsigned char *sbuf) +{ + return bin2srec(0, 0, num, bbuf, sbuf); +} + +int srec_fin(unsigned int num, unsigned char *sbuf) +{ + unsigned char bbuf[4], sum; + + memset(bbuf, 0, 4); + + bbuf[0] = (unsigned char)(num & 0xff); + bbuf[1] = (unsigned char)((num >> 8) & 0xff); + sum = sr_sum(3, 0, bbuf); + (void)snprintf((char *)sbuf, 13, "S503%04X%02X\r\n", num, (unsigned)sum); + return 0; +} + + +void hexdump(size_t len, unsigned char *bbuf, unsigned char *abuf) +{ + size_t i; + + memset(abuf, 0, MAX_BYTES_PER_RECORD * 2 + 2); + if (len > MAX_BYTES_PER_RECORD * 2) + len = MAX_BYTES_PER_RECORD * 2; + + for (i = 0; i < len; i++) { + abuf[i * 2] = hc((bbuf[i] & 0xf0) >> 4); + abuf[i * 2 + 1] = hc(bbuf[i] & 0x0f); + } +} + +/*@ -type @*/ +unsigned char hc(unsigned char x) +{ + switch (x) { + case 15: + case 14: + case 13: + case 12: + case 11: + case 10: + return ('A' + x - 10); + case 9: + case 8: + case 7: + case 6: + case 5: + case 4: + case 3: + case 2: + case 1: + case 0: + return ('0' + x); + + default: + return '0'; + } +} + +/*@ -type @*/ + +unsigned char +sr_sum(unsigned int count, unsigned int addr, unsigned char *bbuf) +{ + int i, j; + unsigned char k, sum = 0; + + sum = (count & 0xff); + sum += ((addr & 0x000000ff)); + sum += ((addr & 0x0000ff00) >> 8); + sum += ((addr & 0x00ff0000) >> 16); + sum += ((addr & 0xff000000) >> 24); + j = count - 5; + for (i = 0; i < j; i++) { + k = bbuf[i]; + sum += k; + } + return ~sum; +} diff --git a/strl.c b/strl.c new file mode 100644 index 0000000..0111bf1 --- /dev/null +++ b/strl.c @@ -0,0 +1,118 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include "gpsd_config.h" + +#ifndef HAVE_STRLCAT +/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +/*@ -usedef -mustdefine @*/ +size_t strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = (size_t) (d - dst); + n = siz - dlen; + + if (n == 0) + return (dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return (dlen + (s - src)); /* count does not include NUL */ +} + +/*@ +usedef +mustdefine @*/ +#endif /* HAVE_STRLCAT */ + +#ifndef HAVE_STRLCPY +/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++ != '\0') + continue; + } + + return ((size_t) (s - src - 1)); /* count does not include NUL */ +} +#endif /* HAVE_STRLCPY */ diff --git a/subframe.c b/subframe.c new file mode 100644 index 0000000..6eb2a9d --- /dev/null +++ b/subframe.c @@ -0,0 +1,222 @@ +/* subframe.c -- interpret satellite subframe data. + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include + +#include "gpsd.h" +#include "timebase.h" + +#ifdef __NOT_YET__ +static char sf4map[] = + { -1, 57, 25, 26, 27, 28, 57, 29, 30, 31, 32, 57, 62, 52, 53, 54, 57, 55, + 56, 58, 59, 57, 60, 61, 62, 63 +}; + +static char sf5map[] = + { -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 51 +}; +#endif + +/*@ -usedef @*/ +int gpsd_interpret_subframe_raw(struct gps_device_t *session, + unsigned int words[]) +{ + unsigned int i; + unsigned int preamble, parity; + + /* + * This function assumes an array of 10 ints, each of which carries + * a raw 30-bit GPS word use your favorite search engine to find the + * latest version of the specification: IS-GPS-200. + * + * Each raw 30-bit word is made of 24 data bits and 6 parity bits. The + * raw word and transport word are emitted from the GPS MSB-first and + * right justified. In other words, masking the raw word against 0x3f + * will return just the parity bits. Masking with 0x3fffffff and shifting + * 6 bits to the right returns just the 24 data bits. The top two bits + * (b31 and b30) are undefined; chipset designers may store copies of + * the bits D29* and D30* here to aid parity checking. + * + * Since bits D29* and D30* are not available in word 0, it is tested for + * a known preamble to help check its validity and determine whether the + * word is inverted. + * + */ + gpsd_report(LOG_IO, "50B: gpsd_interpret_subframe_raw: " + "%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", + words[0], words[1], words[2], words[3], words[4], + words[5], words[6], words[7], words[8], words[9]); + + preamble = (words[0] >> 22) & 0xff; + if (preamble == 0x8b) { /* preamble is inverted */ + words[0] ^= 0x3fffffc0; /* invert */ + } else if (preamble != 0x74) { + gpsd_report(LOG_WARN, + "50B: gpsd_interpret_subframe_raw: bad preamble 0x%x\n", + preamble); + return 0; + } + words[0] = (words[0] >> 6) & 0xffffff; + + for (i = 1; i < 10; i++) { + int invert; + /* D30* says invert */ + invert = (words[i] & 0x40000000) ? 1 : 0; + /* inverted data, invert it back */ + if (invert) { + words[i] ^= 0x3fffffc0; + } + parity = isgps_parity(words[i]); + if (parity != (words[i] & 0x3f)) { + gpsd_report(LOG_PROG, + "50B: gpsd_interpret_subframe_raw parity fail words[%d] 0x%x != 0x%x\n", + i, parity, (words[i] & 0x1)); + return 0; + } + words[i] = (words[i] >> 6) & 0xffffff; + } + + gpsd_interpret_subframe(session, words); + return 0; +} + +void gpsd_interpret_subframe(struct gps_device_t *session, + unsigned int words[]) +{ + /* + * Heavy black magic begins here! + * + * A description of how to decode these bits is at + * + * + * We're mostly looking for subframe 4 page 18 word 9, the leap second + * correction. This functions assumes an array of words without parity + * or inversion (inverted word 0 is OK). It may be called directly by a + * driver if the chipset emits acceptable data. + * + * To date this code has been tested on iTrax, SiRF and ublox. + */ + unsigned int pageid, subframe, data_id, leap, lsf, wnlsf, dn, preamble; + gpsd_report(LOG_IO, + "50B: gpsd_interpret_subframe: " + "%06x %06x %06x %06x %06x %06x %06x %06x %06x %06x\n", + words[0], words[1], words[2], words[3], words[4], + words[5], words[6], words[7], words[8], words[9]); + + preamble = (unsigned int)((words[0] >> 16) & 0xffL); + if (preamble == 0x8b) { + preamble ^= 0xff; + words[0] ^= 0xffffff; + } + if (preamble != 0x74) { + gpsd_report(LOG_WARN, + "50B: gpsd_interpret_subframe bad preamble: 0x%x header 0x%x\n", + preamble, words[0]); + return; + } + /* The subframe ID is in the Hand Over Word (page 80) */ + subframe = ((words[1] >> 2) & 0x07); + /* + * Consult the latest revision of IS-GPS-200 for the mapping + * between magic SVIDs and pages. + */ + pageid = (words[2] & 0x3F0000) >> 16; + data_id = (words[2] >> 22) & 0x3; + gpsd_report(LOG_PROG, + "50B: gpsd_interpret_subframe: Subframe %d SVID %d data_id %d\n", + subframe, pageid, data_id); + switch (subframe) { + case 1: + /* get Week Number WN) from subframe 1 */ + session->context->gps_week = + (unsigned short)((words[2] & 0xffc000) >> 14); + gpsd_report(LOG_PROG, "50B: WN: %u\n", session->context->gps_week); + break; + case 4: + switch (pageid) { + case 55: + /* + * "The requisite 176 bits shall occupy bits 9 through 24 of word + * TWO, the 24 MSBs of words THREE through EIGHT, plus the 16 MSBs + * of word NINE." (word numbers changed to account for zero-indexing) + * + * Since we've already stripped the low six parity bits, and shifted + * the data to a byte boundary, we can just copy it out. */ + { + char str[24]; + int j = 0; + /*@ -type @*/ + str[j++] = (words[2] >> 8) & 0xff; + str[j++] = (words[2]) & 0xff; + + str[j++] = (words[3] >> 16) & 0xff; + str[j++] = (words[3] >> 8) & 0xff; + str[j++] = (words[3]) & 0xff; + + str[j++] = (words[4] >> 16) & 0xff; + str[j++] = (words[4] >> 8) & 0xff; + str[j++] = (words[4]) & 0xff; + + str[j++] = (words[5] >> 16) & 0xff; + str[j++] = (words[5] >> 8) & 0xff; + str[j++] = (words[5]) & 0xff; + + str[j++] = (words[6] >> 16) & 0xff; + str[j++] = (words[6] >> 8) & 0xff; + str[j++] = (words[6]) & 0xff; + + str[j++] = (words[7] >> 16) & 0xff; + str[j++] = (words[7] >> 8) & 0xff; + str[j++] = (words[7]) & 0xff; + + str[j++] = (words[8] >> 16) & 0xff; + str[j++] = (words[8] >> 8) & 0xff; + str[j++] = (words[8]) & 0xff; + + str[j++] = (words[9] >> 16) & 0xff; + str[j++] = (words[9] >> 8) & 0xff; + str[j++] = '\0'; + /*@ +type @*/ + gpsd_report(LOG_INF, "50B: gps system message is %s\n", str); + } + break; + case 56: + leap = (words[8] & 0xff0000) >> 16; /* current leap seconds */ + /* careful WN is 10 bits, but WNlsf is 8 bits! */ + wnlsf = (words[8] & 0x00ff00) >> 8; /* WNlsf (Week Number of LSF) */ + dn = (words[8] & 0x0000FF); /* DN (Day Number of LSF) */ + lsf = (words[9] & 0xff0000) >> 16; /* leap second future */ + /* + * On SiRFs, the 50BPS data is passed on even when the + * parity fails. This happens frequently. So the driver + * must be extra careful that bad data does not reach here. + */ + if (LEAP_SECONDS > leap) { + /* something wrong */ + gpsd_report(LOG_ERROR, "50B: Invalid leap_seconds: %d\n", + leap); + leap = LEAP_SECONDS; + session->context->valid &= ~LEAP_SECOND_VALID; + } else { + gpsd_report(LOG_INF, + "50B: leap-seconds: %d, lsf: %d, WNlsf: %d, DN: %d \n", + leap, lsf, wnlsf, dn); + session->context->valid |= LEAP_SECOND_VALID; + if (leap != lsf) { + gpsd_report(LOG_PROG, "50B: leap-second change coming\n"); + } + } + session->context->leap_seconds = (int)leap; + break; + default: + ; /* no op */ + } + break; + } + return; +} + +/*@ +usedef @*/ diff --git a/test/README b/test/README new file mode 100644 index 0000000..65beb9e --- /dev/null +++ b/test/README @@ -0,0 +1,13 @@ +These are data logs from various weird GPSes. Use them to test +assumptions about NMEA formats and cycle regularities, or as +regression-test loads for gpsfake -p. + +Structured headers are as follows: + +# Name: Product name +# Chipset: chipset name and (if possible) firmware revision level. +# Description: product description (optional) +# Cycle time: sampling interval, time to repeat a sentence in seconds +# Submitted-by: who sent it +# Date: when it was received +# Location: city, state/province, country, approximate lat/lon diff --git a/test/clientlib/multipacket.log b/test/clientlib/multipacket.log new file mode 100644 index 0000000..190eee4 --- /dev/null +++ b/test/clientlib/multipacket.log @@ -0,0 +1,2 @@ +# Test the ability to parse multiple packets on the same line +{"class":"VERSION","release":"2.90dev","rev":"svn6614","proto_major":3,"proto_minor":1}{"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyS0","activated":1259438908.99,"flags":1,"driver":"SiRF binary","native":1,"bps":4800,"parity":"N","stopbits":1,"cycle":1.00}]}{"class":"WATCH","enable":true,"nmea":false,"raw":0,"scaled":false,"timing":false} diff --git a/test/clientlib/multipacket.log.chk b/test/clientlib/multipacket.log.chk new file mode 100644 index 0000000..a2d2d4e --- /dev/null +++ b/test/clientlib/multipacket.log.chk @@ -0,0 +1,4 @@ +flags: (0x808000) {POLICY|DEVICELIST} +POLICY: watcher=true nmea=false raw=0 scaled=false timing=false, devpath= +DEVICELIST:1 devices: +1: path='/dev/ttyS0' driver='SiRF binary' diff --git a/test/clientlib/oldstyle.log b/test/clientlib/oldstyle.log new file mode 100644 index 0000000..29f41d2 --- /dev/null +++ b/test/clientlib/oldstyle.log @@ -0,0 +1,2 @@ +GPSD,O=RMC 1207318966.000 0.005 49.026225 12.188348 375.20 19.20 10.40 70.8900 24.899 0.000 75.6699 38.40 ? 3 +$GPVTG,70.89,T,,M,48.40,N,89.6,K,A*34 diff --git a/test/clientlib/oldstyle.log.chk b/test/clientlib/oldstyle.log.chk new file mode 100644 index 0000000..7d1318a --- /dev/null +++ b/test/clientlib/oldstyle.log.chk @@ -0,0 +1,9 @@ +flags: (0x833fe) {TIME|TIMERR|LATLON|ALTITUDE|SPEED|TRACK|CLIMB|STATUS|MODE|HERR|VERR|SPEEDERR} +TIME: 1207318966.000000 +LATLON: lat/lon: 49.026225 12.188348 +ALTITUDE: altitude: 375.200000 U: climb: 0.000000 +SPEED: 24.899000 +TRACK: track: 70.890000 +CLIMB: climb: 0.000000 +STATUS: status: 1 (FIX) +MODE: mode: 3 (MODE_3D) diff --git a/test/daemon/ac12.log b/test/daemon/ac12.log new file mode 100644 index 0000000..391849e --- /dev/null +++ b/test/daemon/ac12.log @@ -0,0 +1,60 @@ +# Name: Magellan Professional (formerly Thales/Ashtech) AC12 +# Chipset: AC12 +# Submitted-by: Chris Kuethe +# Date: 23 Dec 2007 +# Location: Playa del Carmen, Mexico. 20.63N/87.07W +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGGA,193221.00,2037.72792,N,08704.08478,W,1,04,1.7,-30.40,M,-13.9,M,,*7D +$GPGSA,A,3,10,28,09,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,3,1,12,28,14,150,41,09,15,254,41,10,43,192,47,13,06,081,36*7A +$GPGSV,3,2,12,02,56,323,,04,41,024,,12,31,317,,17,31,085,*72 +$GPGSV,3,3,12,05,15,318,,24,02,246,,33,08,096,,35,45,118,*7D +$GPRMC,193221.00,A,2037.7279,N,08704.0848,W,00.1,201.8,231207,01,W,A*2D +$GPZDA,193223.00,23,12,2007,00,00*69 +$GPGGA,193222.00,2037.72832,N,08704.08469,W,1,04,1.7,-30.00,M,-13.9,M,,*7F +$GPGSA,A,3,10,09,28,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,3,1,12,28,14,150,40,09,15,254,41,10,43,192,47,13,06,081,36*7B +$GPGSV,3,2,12,02,56,323,,04,41,024,,12,31,317,,17,31,085,*72 +$GPGSV,3,3,12,05,15,318,,24,02,246,,33,08,096,39,35,45,118,*77 +$GPRMC,193222.00,A,2037.7283,N,08704.0847,W,00.0,201.8,231207,01,W,A*25 +$GPZDA,193224.00,23,12,2007,00,00*6E +$GPGGA,193223.00,2037.72880,N,08704.08455,W,1,04,1.7,-29.55,M,-13.9,M,,*70 +$GPGSA,A,3,10,09,28,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,3,1,12,28,14,150,39,09,15,254,41,10,43,192,47,13,06,081,36*75 +$GPGSV,3,2,12,02,56,323,,04,41,024,,12,31,317,,17,31,085,*72 +$GPGSV,3,3,12,05,15,318,,24,02,246,,33,08,096,,35,45,118,*7D +$GPRMC,193223.00,A,2037.7288,N,08704.0846,W,00.1,201.8,231207,01,W,A*2F +$GPZDA,193225.00,23,12,2007,00,00*6F +$GPGGA,193224.00,2037.72912,N,08704.08451,W,1,04,1.7,-29.53,M,-13.9,M,,*7F +$GPGSA,A,3,10,09,28,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,3,1,12,28,14,150,39,09,15,254,41,10,43,192,47,13,06,081,36*75 +$GPGSV,3,2,12,02,56,323,,04,41,024,,12,31,317,,17,31,085,*72 +$GPGSV,3,3,12,05,15,318,,24,02,246,,33,08,096,,35,45,118,*7D +$GPRMC,193224.00,A,2037.7291,N,08704.0845,W,00.0,201.8,231207,01,W,A*22 +$GPZDA,193226.00,23,12,2007,00,00*6C +$GPGGA,193225.00,2037.72949,N,08704.08443,W,1,04,1.7,-29.21,M,-13.9,M,,*76 +$GPGSA,A,3,10,09,28,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,4,1,13,28,13,151,39,09,15,253,42,10,43,192,48,13,06,081,36*7E +$GPGSV,4,2,13,02,56,325,,04,41,024,,12,32,317,,17,30,086,*73 +$GPGSV,4,3,13,05,16,318,,24,03,247,,30,00,323,,33,08,096,*76 +$GPGSV,4,4,13,35,45,118,*44 +$GPRMC,193225.00,A,2037.7295,N,08704.0844,W,00.1,201.8,231207,01,W,A*27 +$GPZDA,193227.00,23,12,2007,00,00*6D +$GPGGA,193226.00,2037.72992,N,08704.08433,W,1,04,1.7,-28.69,M,-13.9,M,,*79 +$GPGSA,A,3,10,09,28,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,4,1,13,28,13,151,41,09,15,253,41,10,43,192,48,13,06,081,36*72 +$GPGSV,4,2,13,02,56,325,,04,41,024,,12,32,317,,17,30,086,*73 +$GPGSV,4,3,13,05,16,318,,24,03,247,,30,00,323,,33,08,096,*76 +$GPGSV,4,4,13,35,45,118,*44 +$GPRMC,193226.00,A,2037.7299,N,08704.0843,W,00.1,201.8,231207,01,W,A*2F +$GPZDA,193228.00,23,12,2007,00,00*62 +$GPGGA,193227.00,2037.73032,N,08704.08423,W,1,04,1.7,-28.28,M,-13.9,M,,*7E +$GPGSA,A,3,10,28,09,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,4,1,13,28,13,151,41,09,15,253,41,10,43,192,48,13,06,081,36*72 +$GPGSV,4,2,13,02,56,325,,04,41,024,,12,32,317,,17,30,086,*73 +$GPGSV,4,3,13,05,16,318,,24,03,247,,30,00,323,,33,08,096,*76 +$GPGSV,4,4,13,35,45,118,*44 +$GPRMC,193227.00,A,2037.7303,N,08704.0842,W,00.0,201.8,231207,01,W,A*2C diff --git a/test/daemon/ac12.log.chk b/test/daemon/ac12.log.chk new file mode 100644 index 0000000..6f34850 --- /dev/null +++ b/test/daemon/ac12.log.chk @@ -0,0 +1,67 @@ +$GPGGA,193221.00,2037.72792,N,08704.08478,W,1,04,1.7,-30.40,M,-13.9,M,,*7D +{"class":"TPV","tag":"GGA","lat":20.628798667,"lon":-87.068079667,"alt":-30.400,"mode":3} +$GPGSA,A,3,10,28,09,13,,,,,,,,,03.4,01.7,03.0*00 +{"class":"TPV","tag":"GSA","lat":20.628798667,"lon":-87.068079667,"alt":-30.400,"epv":69.000,"mode":3} +$GPGSV,3,1,12,28,14,150,41,09,15,254,41,10,43,192,47,13,06,081,36*7A +$GPGSV,3,2,12,02,56,323,,04,41,024,,12,31,317,,17,31,085,*72 +$GPGSV,3,3,12,05,15,318,,24,02,246,,33,08,096,,35,45,118,*7D +{"class":"SKY","tag":"GSV","xdop":0.76,"ydop":1.60,"vdop":3.10,"tdop":0.99,"hdop":1.78,"gdop":3.70,"pdop":3.57,"satellites":[{"PRN":28,"el":14,"az":150,"ss":41,"used":true},{"PRN":9,"el":15,"az":254,"ss":41,"used":true},{"PRN":10,"el":43,"az":192,"ss":47,"used":true},{"PRN":13,"el":6,"az":81,"ss":36,"used":true},{"PRN":2,"el":56,"az":323,"ss":0,"used":false},{"PRN":4,"el":41,"az":24,"ss":0,"used":false},{"PRN":12,"el":31,"az":317,"ss":0,"used":false},{"PRN":17,"el":31,"az":85,"ss":0,"used":false},{"PRN":5,"el":15,"az":318,"ss":0,"used":false},{"PRN":24,"el":2,"az":246,"ss":0,"used":false},{"PRN":33,"el":8,"az":96,"ss":0,"used":false},{"PRN":35,"el":45,"az":118,"ss":0,"used":false}]} +$GPRMC,193221.00,A,2037.7279,N,08704.0848,W,00.1,201.8,231207,01,W,A*2D +{"class":"TPV","tag":"RMC","time":1198438341.000,"ept":0.005,"lat":20.628798333,"lon":-87.068080000,"alt":-30.400,"epx":11.444,"epy":24.060,"epv":69.000,"track":201.8000,"speed":0.051,"mode":3} +$GPZDA,193223.00,23,12,2007,00,00*69 +$GPGGA,193222.00,2037.72832,N,08704.08469,W,1,04,1.7,-30.00,M,-13.9,M,,*7F +$GPGSA,A,3,10,09,28,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,3,1,12,28,14,150,40,09,15,254,41,10,43,192,47,13,06,081,36*7B +$GPGSV,3,2,12,02,56,323,,04,41,024,,12,31,317,,17,31,085,*72 +$GPGSV,3,3,12,05,15,318,,24,02,246,,33,08,096,39,35,45,118,*77 +{"class":"SKY","tag":"GSV","xdop":0.76,"ydop":1.60,"vdop":3.10,"tdop":0.99,"hdop":1.78,"gdop":3.70,"pdop":3.57,"satellites":[{"PRN":28,"el":14,"az":150,"ss":40,"used":true},{"PRN":9,"el":15,"az":254,"ss":41,"used":true},{"PRN":10,"el":43,"az":192,"ss":47,"used":true},{"PRN":13,"el":6,"az":81,"ss":36,"used":true},{"PRN":2,"el":56,"az":323,"ss":0,"used":false},{"PRN":4,"el":41,"az":24,"ss":0,"used":false},{"PRN":12,"el":31,"az":317,"ss":0,"used":false},{"PRN":17,"el":31,"az":85,"ss":0,"used":false},{"PRN":5,"el":15,"az":318,"ss":0,"used":false},{"PRN":24,"el":2,"az":246,"ss":0,"used":false},{"PRN":33,"el":8,"az":96,"ss":39,"used":false},{"PRN":35,"el":45,"az":118,"ss":0,"used":false}]} +$GPRMC,193222.00,A,2037.7283,N,08704.0847,W,00.0,201.8,231207,01,W,A*25 +{"class":"TPV","tag":"RMC","time":1198438342.000,"ept":0.005,"lat":20.628805000,"lon":-87.068078333,"alt":-30.000,"epx":11.444,"epy":24.060,"epv":71.191,"track":201.8000,"speed":0.000,"climb":-0.400,"mode":3} +$GPZDA,193224.00,23,12,2007,00,00*6E +$GPGGA,193223.00,2037.72880,N,08704.08455,W,1,04,1.7,-29.55,M,-13.9,M,,*70 +$GPGSA,A,3,10,09,28,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,3,1,12,28,14,150,39,09,15,254,41,10,43,192,47,13,06,081,36*75 +$GPGSV,3,2,12,02,56,323,,04,41,024,,12,31,317,,17,31,085,*72 +$GPGSV,3,3,12,05,15,318,,24,02,246,,33,08,096,,35,45,118,*7D +{"class":"SKY","tag":"GSV","xdop":0.76,"ydop":1.60,"vdop":3.10,"tdop":0.99,"hdop":1.78,"gdop":3.70,"pdop":3.57,"satellites":[{"PRN":28,"el":14,"az":150,"ss":39,"used":true},{"PRN":9,"el":15,"az":254,"ss":41,"used":true},{"PRN":10,"el":43,"az":192,"ss":47,"used":true},{"PRN":13,"el":6,"az":81,"ss":36,"used":true},{"PRN":2,"el":56,"az":323,"ss":0,"used":false},{"PRN":4,"el":41,"az":24,"ss":0,"used":false},{"PRN":12,"el":31,"az":317,"ss":0,"used":false},{"PRN":17,"el":31,"az":85,"ss":0,"used":false},{"PRN":5,"el":15,"az":318,"ss":0,"used":false},{"PRN":24,"el":2,"az":246,"ss":0,"used":false},{"PRN":33,"el":8,"az":96,"ss":0,"used":false},{"PRN":35,"el":45,"az":118,"ss":0,"used":false}]} +$GPRMC,193223.00,A,2037.7288,N,08704.0846,W,00.1,201.8,231207,01,W,A*2F +{"class":"TPV","tag":"RMC","time":1198438343.000,"ept":0.005,"lat":20.628813333,"lon":-87.068076667,"alt":-29.550,"epx":11.444,"epy":24.060,"epv":71.191,"track":201.8000,"speed":0.051,"climb":-0.450,"mode":3} +$GPZDA,193225.00,23,12,2007,00,00*6F +$GPGGA,193224.00,2037.72912,N,08704.08451,W,1,04,1.7,-29.53,M,-13.9,M,,*7F +$GPGSA,A,3,10,09,28,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,3,1,12,28,14,150,39,09,15,254,41,10,43,192,47,13,06,081,36*75 +$GPGSV,3,2,12,02,56,323,,04,41,024,,12,31,317,,17,31,085,*72 +$GPGSV,3,3,12,05,15,318,,24,02,246,,33,08,096,,35,45,118,*7D +{"class":"SKY","tag":"GSV","xdop":0.76,"ydop":1.60,"vdop":3.10,"tdop":0.99,"hdop":1.78,"gdop":3.70,"pdop":3.57,"satellites":[{"PRN":28,"el":14,"az":150,"ss":39,"used":true},{"PRN":9,"el":15,"az":254,"ss":41,"used":true},{"PRN":10,"el":43,"az":192,"ss":47,"used":true},{"PRN":13,"el":6,"az":81,"ss":36,"used":true},{"PRN":2,"el":56,"az":323,"ss":0,"used":false},{"PRN":4,"el":41,"az":24,"ss":0,"used":false},{"PRN":12,"el":31,"az":317,"ss":0,"used":false},{"PRN":17,"el":31,"az":85,"ss":0,"used":false},{"PRN":5,"el":15,"az":318,"ss":0,"used":false},{"PRN":24,"el":2,"az":246,"ss":0,"used":false},{"PRN":33,"el":8,"az":96,"ss":0,"used":false},{"PRN":35,"el":45,"az":118,"ss":0,"used":false}]} +$GPRMC,193224.00,A,2037.7291,N,08704.0845,W,00.0,201.8,231207,01,W,A*22 +{"class":"TPV","tag":"RMC","time":1198438344.000,"ept":0.005,"lat":20.628818333,"lon":-87.068075000,"alt":-29.530,"epx":11.444,"epy":24.060,"epv":71.191,"track":201.8000,"speed":0.000,"climb":-0.020,"mode":3} +$GPZDA,193226.00,23,12,2007,00,00*6C +$GPGGA,193225.00,2037.72949,N,08704.08443,W,1,04,1.7,-29.21,M,-13.9,M,,*76 +$GPGSA,A,3,10,09,28,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,4,1,13,28,13,151,39,09,15,253,42,10,43,192,48,13,06,081,36*7E +$GPGSV,4,2,13,02,56,325,,04,41,024,,12,32,317,,17,30,086,*73 +$GPGSV,4,3,13,05,16,318,,24,03,247,,30,00,323,,33,08,096,*76 +$GPGSV,4,4,13,35,45,118,*44 +{"class":"SKY","tag":"GSV","xdop":0.77,"ydop":1.55,"vdop":2.98,"tdop":0.98,"hdop":1.73,"gdop":3.58,"pdop":3.44,"satellites":[{"PRN":28,"el":13,"az":151,"ss":39,"used":true},{"PRN":9,"el":15,"az":253,"ss":42,"used":true},{"PRN":10,"el":43,"az":192,"ss":48,"used":true},{"PRN":13,"el":6,"az":81,"ss":36,"used":true},{"PRN":2,"el":56,"az":325,"ss":0,"used":false},{"PRN":4,"el":41,"az":24,"ss":0,"used":false},{"PRN":12,"el":32,"az":317,"ss":0,"used":false},{"PRN":17,"el":30,"az":86,"ss":0,"used":false},{"PRN":5,"el":16,"az":318,"ss":0,"used":false},{"PRN":24,"el":3,"az":247,"ss":0,"used":false},{"PRN":30,"el":0,"az":323,"ss":0,"used":false},{"PRN":33,"el":8,"az":96,"ss":0,"used":false},{"PRN":35,"el":45,"az":118,"ss":0,"used":false}]} +$GPRMC,193225.00,A,2037.7295,N,08704.0844,W,00.1,201.8,231207,01,W,A*27 +{"class":"TPV","tag":"RMC","time":1198438345.000,"ept":0.005,"lat":20.628825000,"lon":-87.068073333,"alt":-29.210,"epx":11.444,"epy":24.060,"epv":71.191,"track":201.8000,"speed":0.051,"climb":-0.320,"mode":3} +$GPZDA,193227.00,23,12,2007,00,00*6D +$GPGGA,193226.00,2037.72992,N,08704.08433,W,1,04,1.7,-28.69,M,-13.9,M,,*79 +$GPGSA,A,3,10,09,28,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,4,1,13,28,13,151,41,09,15,253,41,10,43,192,48,13,06,081,36*72 +$GPGSV,4,2,13,02,56,325,,04,41,024,,12,32,317,,17,30,086,*73 +$GPGSV,4,3,13,05,16,318,,24,03,247,,30,00,323,,33,08,096,*76 +$GPGSV,4,4,13,35,45,118,*44 +{"class":"SKY","tag":"GSV","xdop":0.77,"ydop":1.55,"vdop":2.98,"tdop":0.98,"hdop":1.73,"gdop":3.58,"pdop":3.44,"satellites":[{"PRN":28,"el":13,"az":151,"ss":41,"used":true},{"PRN":9,"el":15,"az":253,"ss":41,"used":true},{"PRN":10,"el":43,"az":192,"ss":48,"used":true},{"PRN":13,"el":6,"az":81,"ss":36,"used":true},{"PRN":2,"el":56,"az":325,"ss":0,"used":false},{"PRN":4,"el":41,"az":24,"ss":0,"used":false},{"PRN":12,"el":32,"az":317,"ss":0,"used":false},{"PRN":17,"el":30,"az":86,"ss":0,"used":false},{"PRN":5,"el":16,"az":318,"ss":0,"used":false},{"PRN":24,"el":3,"az":247,"ss":0,"used":false},{"PRN":30,"el":0,"az":323,"ss":0,"used":false},{"PRN":33,"el":8,"az":96,"ss":0,"used":false},{"PRN":35,"el":45,"az":118,"ss":0,"used":false}]} +$GPRMC,193226.00,A,2037.7299,N,08704.0843,W,00.1,201.8,231207,01,W,A*2F +{"class":"TPV","tag":"RMC","time":1198438346.000,"ept":0.005,"lat":20.628831667,"lon":-87.068071667,"alt":-28.690,"epx":11.544,"epy":23.220,"epv":68.453,"track":201.8000,"speed":0.051,"climb":-0.520,"mode":3} +$GPZDA,193228.00,23,12,2007,00,00*62 +$GPGGA,193227.00,2037.73032,N,08704.08423,W,1,04,1.7,-28.28,M,-13.9,M,,*7E +$GPGSA,A,3,10,28,09,13,,,,,,,,,03.4,01.7,03.0*00 +$GPGSV,4,1,13,28,13,151,41,09,15,253,41,10,43,192,48,13,06,081,36*72 +$GPGSV,4,2,13,02,56,325,,04,41,024,,12,32,317,,17,30,086,*73 +$GPGSV,4,3,13,05,16,318,,24,03,247,,30,00,323,,33,08,096,*76 +$GPGSV,4,4,13,35,45,118,*44 +{"class":"SKY","tag":"GSV","xdop":0.77,"ydop":1.55,"vdop":2.98,"tdop":0.98,"hdop":1.73,"gdop":3.58,"pdop":3.44,"satellites":[{"PRN":28,"el":13,"az":151,"ss":41,"used":true},{"PRN":9,"el":15,"az":253,"ss":41,"used":true},{"PRN":10,"el":43,"az":192,"ss":48,"used":true},{"PRN":13,"el":6,"az":81,"ss":36,"used":true},{"PRN":2,"el":56,"az":325,"ss":0,"used":false},{"PRN":4,"el":41,"az":24,"ss":0,"used":false},{"PRN":12,"el":32,"az":317,"ss":0,"used":false},{"PRN":17,"el":30,"az":86,"ss":0,"used":false},{"PRN":5,"el":16,"az":318,"ss":0,"used":false},{"PRN":24,"el":3,"az":247,"ss":0,"used":false},{"PRN":30,"el":0,"az":323,"ss":0,"used":false},{"PRN":33,"el":8,"az":96,"ss":0,"used":false},{"PRN":35,"el":45,"az":118,"ss":0,"used":false}]} +$GPRMC,193227.00,A,2037.7303,N,08704.0842,W,00.0,201.8,231207,01,W,A*2C +{"class":"TPV","tag":"RMC","time":1198438347.000,"ept":0.005,"lat":20.628838333,"lon":-87.068070000,"alt":-28.280,"epx":11.544,"epy":23.220,"epv":68.453,"track":201.8000,"speed":0.000,"climb":-0.410,"mode":3} diff --git a/test/daemon/ac12_binary.log b/test/daemon/ac12_binary.log new file mode 100644 index 0000000000000000000000000000000000000000..a25a3b0305a032c04a29f10e9207bac261debc40 GIT binary patch literal 25807 zcmd_yd0Z369suwS7Ee4|)Cy`UcwriHlE6j*K~XD+w^C8jpkP4|(27<~pIXaNpH*9} zSFNphmV(9mqSktV2P*cdv6a@^dRuR?guLI(W|!GWvWEJwKK-M9)@CM~+5P4>^PAts zLmUvxfkARbT@P_kOl)Fubc!E)+<)Sz_}G+`X#Ja`QvKlnCdDR;-k8l_~gL@tpjB?_rR zBGV|OO0^_Z@}^uV^@YDBUOru!zWN7B0wwSYg+vbTsFiSkWVj*vkC$9!dF>zxoRZ~* zO07h$^p&W5(6L-2k^3qoYB)`WM6H%6G%9?clK99aO0`zvrI8VR;5UOd(1%Q|l1OB} z5``SzT`obN82VEx6cYI4==^2yA}>vMqBWcYyaN6YwD$FpK>rezS|XRT?-Cx^zehhw zc%S|f+yNd?p`ntgwNe#)dZpS|s)DhG*GoDvf1x43V*&pJ*G1B`FI)-*^Ktrx1~C^5 z_YVWfUJTx~fJ=cpWI9(UXQBxr<&%3(CVc=$Lpxc@4l(Qvm;+nfn)aMwr<>5>2P9F4q!Q1DbJLPta{m1vh8u4b(uXRSO=P zhEYL*!vKwTiQmj*b6Q3;peZ`ZwP4W9xXhv%Rdi}FLL+PL`6WX0N{tl*kP-UE&)w-^ zjkP*a!31k!00|1Y0!j$Y5r7^#;rDqW=F)qM?F3SG{HHoCfyZf z49x~K+BIC42#s597L6PtO^3RE-_0BiXo7~dOwgDLOwIKMDm=@o1&O9xACKAFjsqH* ze%#0_=Cn1(08Q3Lt_6c;W)X{KdCrGdF`A)~8iYo)?o$tBg#PW7oAmgweYys7SD|Cd zxa2l;LZE>uR%O#O=If0^!_cyzfhi6#J%d@1!1PRx-|^W-ntv`Dp`mgZ4Vv|YgmY+c z|2EK|?=RcavuZ};PNLa$Y2`)dA%JG2RutD>l<{`C-r$s(%-zr!jXR0PGhv=ekqKzr z{`&CnO;f>*#d-sE@+YenB%0uPgUqja0GbYcqsk=aw5(t~j`a2p4<}xHXNsax|82Yj%3Z&|=YONi?vG z5I_@*-|=NZBQ#VFqd`j%0uAoJN@yw;B|_7)XA)^-B$~Z3msSql0cfV?pZA_4%9y(c zBF&Nt#u$x^L?b?`@=Qzi&r7%$)$GI9O@$3&^akqloiG?oxMNz7Xo3#^8QOLoplSWR zQ*lFc+K=NQ(sZqW$)L$tX+iU+RQX2{Msru(7ojP09#;<;+2Oo)qu=kJ2GUCv`RJH3 z%D%+cfJ5U`IU392okhdYV$o=LXjDRIUaskx&`>>zMs7b5pys2&{o6pJwi{_s#IMHb zSuly_yZehCOTGa#i>8QfH5Fz2>jQ{19(%bn!UTdzG%ZzLk-Mh=nxiehEr~J}+F*IG|~^Y|DT}=Cnf}>nUpPRIUYs=HDN(XyP_4JdDv4HxEH*{#w%S z4`f8wzNnO5P&Z#E(Vaxcl+h~+7%MFDq47|jq8&Fdeh z4gN|8Xjac@ct6`z*mSbqKqbtvYC)pu+Wp;Qx3U3EL&fGlkDAjSCjputQR0jF)C`&h zi7c8Wxy~~%ngg>kFq#%4zC%XneeUP!Ed7tVKC@%dF=bRWgH8xE+RD)|UvC^5h8By4 zH$8*&slfE?<%%>yL-iyYft0gVA^`VaB{bDMJ&PmJ9250B#`Rw7u^Uu?W_sJkU0Rw7Zlmm(q_b5E5>4Rjo)6|ihOTDK`!_%JGpAjW z0-F7waV;1$i-xdh&bAKdi_ydkj=*Tj7tKOO==7_pey4vvL{Gdq6&+K?cU<{sd@D!8 zTqzC>LyJYjo1Q_6UjWUsN(5+#eHwd_#*)N%PT4b|p>i0FRU!cQUnMkX@6A@E(eU>HyuP$m)AB}QW)(KH#{;k|<& z1DZj(yB2gb6_odY7Bf?}KQNO*z{{g9H(qn=I1jlX4asDu>Z9%S$eMhWoD)8kCT!5*lR4OI11=J;s5{0F8HpIjy9yrpbdAX}h@3fSE01 z(LjG!$nY@H+!JzrPg9XiPQBQwgjAre5yrwBFT{RCG z(YY-gNhhCo(zz_c*)+EDgs^z zG=f9rFdBaLjOo8hXzWeT>_(cZp;=3!Iriy<>`fB^%^Qi@GqXh*r?vorp?A3(8WUJc zqN&$3*AQP5(9~K|7P$dZ&Jt+x@4i+ocxXDexdz*+rtMH7(<~PU@dGzGQf-F=kU?quS6SGs3C`iKdHTq486A59do4{AzSJ zr|Wh@iwV8C77UuKM=Y8*+DH6|(F`ex!qc;66SP2tqW{YNn(iiRM_+t91|3tzeW&?o zY*YkT)&-X7nTof~4V73V8o|v?%lgQYJ^O!;G(tn=Fd8P0!cNbaOJO6@*hhn=$<;VL zD)M$LU(xFg zROlG179^U^`92H2YzSz6`eB3DF>|_q9hjc^OyXKFXx5joXd)@MSqP2yg`%YhP1z^u z&5;qh+~pAMxw;p<_2+}=m@;~7g-(d+nT?77ei@C5zs=1<1Lb}K(=*Fd?{BA^pL?W% zk4lzoqR++LguIeX!NGEv4L|A3^j{@5XthVMQK4Bfs)a=*n}QQGT)7HmtMHu(uYc3a z2hB#9-kxre^Bbw?M`i3+*&9Gn%FtHpeidc9odiYAtQ7r5Dxv~Bk5BgiMIXQ8lG?^p z=oF`iMUFpr64>2uq#|9}`d-6Ff}+#Yf4aWToZjmmC|dYC*Md=$eTY>wOZr|LM$y4? z9D1%rY)5G5tA-eQZqLp-$&mtdOc|%OgH8xVHcAAT?>jb~rsD5=^X6+x!F1ZQny-;% z&nOwdl|5T!2G~r*bIA+{4wb`(tQI-;N(AhO9@G(G2rBg|4DrjJ(W-_hduA3n71O<^ zL-UA5gUX)I?47!(jT@ku*Ye-r1^}9_fX1_;x)Kw3M4*W%TRlyAEfvs=bFbg!s;S@> z%0bVsn0+xVcxbv@oUs>nRGp8GlurJ^oE|~}n*Kw%PtBm&l*6J~KO!R4)!+eJ}S!WlLKg4-r#O%j7ChNxj*i+E7BW)#%*9kR$o&gRirmiEzo_* zL`$XxiNX>&^fXc9&5c36*$ zZ2x`zBtL(TrnFP`T69bqUqd-LVtQtyL;z*!E1pVI@%O!Xkp`aX5?JKCT#-g-s2oOP z6>0312%t-0JJM7$8WoAAWcc!g3>0ZDz7{*iS(Mqk7@>KaPe4VYxqbZLqYWSV=f&SO z$4u)957?k|TFCoWEqG|Ckwx$B2Q-_T^f`6IoSwJ}DmbSkaxEA%dtz8L>&s^2x*Dl_ z=xl_B3chv#8KKYZ?nC!!;78xPb{`#6#s{l02eyJ!WuruZ`Fi8lH2i&U9vZn|qcJGXFW(Xzg~`CI^!XrDbM~aB21K-xCzjFF`v7kaop%Z zqPeMvUsux=&>UHEwAVCg!h^`IS!fz-t`JSnnzijoL@5JsB zWzHP{XtJhrXN1uVBhg%4Flt=pT|l$CaqaJ6dR9LZ&?MfnYC)pWPM^QX6bfj*TG=|S zz?{DEI-rTX!nI(~9MH08#yz;y2~E%5+@KtV*EA8q4KSK7-!G!&otn|bhceMIWo#Y| zom5QE)HX^4_;ocFT5O2`4-M>n3QW)V8#h(o?R+872o9CQXqZGMn+Ra~w~>LikEVLF zXYPq4nmdznMIcqXLo2ApjoI1%MCZD=S~D>cPjRR7&OOfThQEd{U;F2VhypBfb9R@I$6TcQid~{~`AoFtf!xGyyvXH-rqG zbEf;byJyYme<%UX`Lh}v^Zmu4!Iz?PGz#=fLAKX4)tm^} zNTRv*+04%Cy#P(x8=KEXiZVB4L8Ormv7-{%us$PutVytO| zhU!T)0?$7)Gi45qor(YfG!=C~)v`~MPolZw*(dY(&w%Eu?^9Pa6lGpQiGV{M+zpM< zT#?is&?Lu(9L|90Sq!w$Ry@bXp!sPni{|rAXYh{(boABXHBJ49ojJ&e z&gI%tI_B{{U9HHg=$JC*4&kG*Q4zo|qp{Fp69Hrer$Xak_N?k?G`1e)v|7`kIz@<* z&*xE2!J&E*jX3#kSf*5Lq~UFI%gL1UKLQQ>j4bgeC$q8fywC^@)stu(i!@dh0S=%+ z+X%KIjeRs)^e88~C79+ccp*VKTJ%u^DA=Ty<#1i%NK;0l zIlA&ty#mOd#l?BTxV0L`epIYrs#4A(BuV)H_- z1%u|&WEM?9)Y72{P5bH7Ya=wSg;#=s2t|J|ayI?h^})KJI(yJDW%OpY8aXsJDgyXr zH1K=G=tpcUkp>E9Dr(OZ8o_4;EK%!k*PhvqH2)+tLPPZ=8i7c|uLxi+MMWZjcP;Es z&+KK-o;{kDjYu?QT`wy`;HP7Dz52nrOX;GIT3?3sM(a)74UN#WY(%0tY^L3otpYTG zg|7NSh%~77Ea{k43lfcd%feOlOn@dr*7s4EIiu|bSU1%{*mm=psaxNHg{?=!Dzc^g+3n%6`+yYE8r2=2oa2L&L8K zct+DRa8mJT03Xfsot_B|)stuhA`QPH0DeauE?AY&pta>wMj8k$>N zPZCY}N%_xv>i`<>;SnEn6@8@I0R)Cm<+{XZJXtglHzE#?&Q{>pEp?gnW34V>+I$eiH=r8=VC6%T(hXm0di(R>piYlhIYefJFh zo!U1<>nB58q398+@wD5bHuPSfYv`CV&M1YqCD7QY2;i-0SXykP;i1u@%>lbV8oXXoQE#VKlsyv!(wkp>beM^DNM42{a?AuUmdEh0V=fZ`D=>7(^e1=0T*X z%YUS-rItjq?}sgQr{D3zGCQdod;H1S~(yhDk8$MmkRHt(i($|1{Lhu znO2#MDqWDus5NTo-n5!lX=zQ6hE^FhL0UZ>Nw-vMgM#6AI?&LjYUN4F!SS(4Ny-pq zkEmWsS~({6E%-AW9{qXPh&W}4S{-cCX?4L`bSf3Cj7uD&3_*X^)5`c*__Ib8WY7d_ z;U#Oe@K*^Vl_4!n#vql!XbRTrQIpts*bSc_Hbx{^;HcWk?EB~*PKVR*>NK<(-mQt| zf2r_`M*j;`>m2*`qTzBlcGQ|^wKka68PK-cNUMXjv>q;zhSuw8jZud;bhJTDYxO2N z(5NDgflmf);20{sj;2+?v_=hQSJUWf!|}8l4GmWvT{{)*6lm-~w1(FJd%(Xy>tF*7 z$ES6ATCH}R#d$@$|D&(-igrg=Hz{^ZTzvenF>!Fg-<+h3>ed-9p9!vMJX{g@J$52o zZ+KTq^b>)%rW~6TXHkZX89g>`GVRzOPLB77*U#<`ZyfIr@4le@HSF$iRq*cU(iFBk z{407jaNY3k=;Gns`GXIMjZY$84ZI5S)x+g1Yo z^m8d}fB2EHug0-^;jbNiT+yp>TzL3d7Itj-G2^}AXN_MA`hgd;e+>F$M}>Fq*o}_r z(w)X1BHW?Hx~fWV3erIj(CUMObkNsff4T+x8|ntQKfqtXeSvP%6>bF@_9NXbvMqbV zz{iKq#N7-8_X4;T-~+M;*J#xmbW2ggUxx>34DRj&aBL6m1Nb)Kav#8dC%6y9C5~h7 zBk(gDGdgzg+wkK>?;P)$lo*FT_~^__1S#C5&u5E;fFc zB~Ta6e+DDlhST*gc=b6InmJcrtWT z`LMIEys5D#Pn=<)6fex-TST?#Oqa`jmkNbn;kCZJ)hMj#!tZ)z`nEcu?j9aqDY5+g zkP#I8VkWMMX6l@%&1|hu2W?Zfqn+R&1d|#JU_K@tH*Ahc7E`WgsL8Hj2o_^fgU=Wt zQzcUcEW`bXRoMl?zY|qr-9<80!MF?YRN>=$M3s@eZIfSF3#1C22Yn@Q`;`^{a|uw@ z(jk{@m1L{#kydRzX4x3A4XkSZWW%T)iqzocVAZTYct@~q_eiT+tbFZS;tH^8_|{`g zliaME(=Ar2XOK$^fmPLG+lKc8t4s?+rX|^vQ{%v@oa1~8)~czOIjaWcoal|LQq>Fi z0$KG!xurc2P0Wp-J23rfn#_u4M#dRVMbecSoVw-!rU&cQ1!kWjL%7>n@V5VzUjrRrvTGSp^4jCIdvRLg#t5 ztb(4AKdutwluA9WDq3fiYL#zA(yATN`yX}u0IX`aq2ai@iqyX8V3lbV?+CKWw<2ei z8se(vl|#OpHW;jG+pj@_F*hr>p2bQ?O)%c9X8&}Cz6_7HNQ-JQGwo*<3igg#sR-rskL=a%n+Y)oyk#`%C^{Rr9W~PicGd z%61mYiyF_jV6B?DjkD@u60;gxwYld*uqq*s=^lb;V$vQSW2T;LWo}$|EZU}Q1AOqu zp0`S0uvL!Ogv$Z4qH$K4NULCwL&U0f_>8hu#W!44w6AL1XqY@)D#6f=Xk3NPBU|Mdv-EUqxoDkLa$Kb%t=c{G(z3ogz^X}^=UUBFq|W*l z;;MxxN@s`vuvIG3s>X+P0m(_B8434d>wfTZZg#by7Ay7HH!dwmtJ)s?J+jFfu&UAb zUMH*DlYbluaa9|qhpbhp%N$ny9;E#(2U~TwaaUy3Q}5wb5KTM0SFaEG^^?;y77WW5Mv)gKGH{f1~VH_Lg<%&nYh zrp?FEHf0M;#vgm$Dk$PBC)Bv^&cBU|-s#Z`SstM-mRk}>#Yu5BLtz#O(1q$E>vcXzns&7}}<6 zy1GKEOa)uTev#v?VnySu6664(^j0JXD92TDTm|{h=cr^|th?m5N~C1nrM3be-y^G} zqs`kA`Z>`gTRa2VO ze62xl)@@V=NVj%rL0T0)qtk;~P-|Ge{QaAsgxHfW1%Xw2KjmAnan<}joK}VN z4ecF`t;(A}9nr+3T%8bd>gNN@*qf8kHf4Lew$Q5Jf~{gZ2X7TC8fTRt2M7}!M64>V z+6p5vy{fRd%25~cEY$%*)}(-13AfX$x0e$~O0(HR?(!K$lWwjKCfk-BGy z#Y*KWct@~RR?@0ky_>(g|0A%f*T$W5U(Lj*8Tjd5u~S{1f;<*|!(LN|HmeLeH_ z^7dqVd$7u4<6E#+EehkTdZK965nDAdYZSI>{`$v=CT7Pm6*FOWEpxr&ucB?rHvMIR zRXRMYF#j}UN8XOBtzbp-&?;_fZc%I2-CBjm~c~cSD<8TLJgsg64V^ zxwb;AyGXW*9X{sAtMKtXvI^>)oVRV!+6r`@XWA-6SD;>y_$=#IxpY>^R?Q==I#f-+ z>DDiyn|64g9~5O(r0ySNu~ObHR?Q==s+RGst>)%>kC`7fZ=j zttPEH^2w<5O=H2TR}xL9XDCunYyo-t-sK&^@~kGUs#0g8bwqivs=~sjG3%gaorV_w z>gv)$U{&jeSEwUk)s4GLPSmxhRDoJU%I^{1g0yy0EJcoRKS&Nm0*dbQvLXI zw8>VLlvRRtD`0^mVmhJ@b(f-ARoJ=}`1p`5ajf6uvc!@!t2|k^0wOWEtff~6SZEIL zIgG1zl2#q_-*`J=6=^rU z)B(zIRRPNZ%2xfImID;+E|RTc%agbqAbWf_aaG|~K|cP^=K%3}q{daURgO5Uc#_SWX6x!EsR zELJLVh)WC7s@9o?xnEQVtA6@nUEmRWN@yj>0UE~fEm*78Uf`^Xp?s$!t6H7US%j>5 z`f*A6fgO+|q%h!sAR(Sbom{bSfvSI(0fd)t$Ij;fPbv;|n_AlwYZsuXQexfB~ z_X~;LkJ@2hrmq9+#`JBt=6{Mb-{XK?T^H9@H`^=T0s~&5 zJYAT_Ur6lCPuITQe;{CYYRXU7*Vt2DzX#aO`;~9OVwZk^!)|)eyGjD`m&D}BML*$w{nbr@LH z2CNEjE=-H%c|=$h{dC1-?X?MD)o{P6uU*Z}x`m3~=QvY>Yzu)^uU(wF8zwA!A08Mq z{s((X1O--g@9SdKrVX4`tAck^*s6n5yI`vh8X6&*m|BOnGCq|jF<KCVLe*Fq5q+p1g!S;8ns4Ux;=W$yTv>5y0MWqV^*M)^#zYF);-uU0G4S}S4Ui*4WXjv#sb zd`PPvSJ}RK!FjN%&Gq^*rrc~rJ&Tp9;Oo+Yw2JxX%Oh_52dw%b^8Clk>?uR`gH;U! z_!ewjwPk_BsykHWU7e6sL0gjhBdhF>FE&6lF&E;}m^MrOn2W2@(KcmUeobf@ZJOIeiV30gX_?jqSLhzy7Y1=-`f z$siVPl_10rjjKFZ_(HY{GK%=&cE!_KrN&i$jY+G1IvyJt&=#!P|AuwfVMSV(4PaG+ z8@wafs>Y;M_lJLaCFllN<=ZoQW!KznD#v1_>LU)EOAz`sCantjw(`on9$?k3DhbSe zd&=1EU{$8G^pLe`hn2Ic-?&p-uvN-i8n7x+@lNx#h^Fnot{oQ=>R*TPN?(n(Dceh^ z8j&b^XXicUvkK-k5DNn@V5a*3<( z@!eR3x}*EJN}5&ZJQ7E{OopDSLsNrF7#iLkc#4}i!Tiu;;l$~<0P``O`$wG z(yH4>_dimR#5|U-q{OQZLZbj#0`5&;&NF0c48vm zg0z7Jw?nX1 zYF#r#6XWw@a7Y&YKW2hI9>1b&RjvxG(z{vs!euhCa3;UdD$(((;wmJRbAZK@R*=W5 zN_xCXth-3I%B6}BAK#5ts5`oks~|v=P+Nh{Bh@NBZc=&^wB*_fUIi>qKhmm8iL1{l zehS_6P5n-HhV4|O&FTSGt(@Z0g0$-D+(E* zq*cG(@77|>f5EEB8FMBNhq$U9j6S_u!=(jjm2ubY3HzFWRf`8V^#9$SlD-+NYP^VV z!CIBon6qkQr^YI5Rks1nu~qiNtq@H+F07rqy7-Q``=rL6GlEsUBA&d| zEH~@k1&fucy4a-!X_X;w!>-8AVAVWh=Z#VJl#OFSw>!=`T&z_`DmtvX=ly&6$H*%B zOg|IK0V-EPUbc#Zd>S7c6|CRugrA8tC^T zR^8-aTVa`ArK}oom9kV68g#J7?AS4PmXYRg^}F ztSa|erRs<#<|E@t=4EXPvvuMCv`yK*XM|R{S@=RY7g#S?_`=01(YVS{ryY z52;p_sRs)`hjG<<(yCjZPHVk35UfgmW%Jn>McSs75LX5D6r)q2vZa}6tICvF6* zD)bNXUj=o5H7r(Y#VVH;q*eN<))neKVAZr!BlkmX#l9G@YI+3Ug098 zbt}|*(kdhRB3I}`MTE5#vQ@HGe|M|Ix=VhmL>?^cQd@zK@3cxo_D8h7r~5iU2+$QhSO@62RYrFY7Iqo0g4I1yOejBC7}i8nCM79D z;QAEw++ukyFx*s2BnK#5w<3Rc$#0cNT*an2__zum-y^G}#Z_YKR+I&+L|49jz8==- zcbT&aJy`gmF0_dj9@hBHx!|7Za}{ZMoh?@C4jKj`R-w2|T6HY!Nwp#2VAbqLv7_J1 z%`R_+7J;9+v>>h0n(I%Gd``;m=%Z+xvQ@5$@8o=3g)day9u z%$#q!=xf)OYG;)kS3M=Idc0Gcd@~uWdU!rTJ6Q2yHCVfrTD*aG1jkiRNvjSoJ5VJH z>Hy=14f5*Q5FRSB4O&c%bZNm^rGf_wYbHFtSg9OXH7H|dPP#p{_G{2$^E|!vO5dVw%GQdVnaf+nPFu_uR|(fx z(hDZy!>UTo^#C$F~ZIBq*YJbT-HXUhi=;W;`?hZr6@jZbQ#8y8g1eo zK~^=WL0Wat&iF1~4pxO{*S2IsT!q#H9DT&41!`Pa>1%-Ro6$I?Ws-9!-F#NLj8_RJ;%ju$tP-wUQA{~N;7Nm4{ntREODDAIImiJPjE~!z^@4Yo{D&e{ndVGA3tb(y)XNVzMTY=8=j9CSN6!}aL99O{?Z|9pX{kW>&-uEXv ztJJuvK>%r0-f{KMyDNcJt@=m5-$wDFZU@NIe-iHqwkm+L3ZkUweM6c}4Lc52)t|TU z>e}4wifDdSM^upK%o;WbAgxmUky%6E9<1utb4Kk0_EZC`sAQHt2ogdIY6ORCN!a= z(Ao-N9iZoPfd%7LvQ@Z1L6Fq@lOKP1E^x`lRpQ-6vQ>hbb;t2NvP#l;l>vQ`m8~jj zTvfVOnFy-}QvYu7eGtqA-uaJ;x-hHa!^jMXt11hhoY=rbTD9kgEtRL-3C(!>&V>gP QHbNcXNsy=KfvT1N4|R{D00000 literal 0 HcmV?d00001 diff --git a/test/daemon/ait250.log b/test/daemon/ait250.log new file mode 100644 index 0000000..6c8b782 --- /dev/null +++ b/test/daemon/ait250.log @@ -0,0 +1,155 @@ +# Name: Digital Yacht AIT250 +# Chipset: Unknown +# Description: Class B Marine AIS receiver +# Submitted-by: Jan Veninga +# Date: July 30 2009 +# Location: Enkhuizen, The Netherlands, 52.69997N/5.290465E +# +# Device is described here: +# http://www.yachtronics.com/yachtronics/manuals/DIGITAL%20YACHT%20AIT250%20OPERATION.pdf +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPRMC,194907.00,A,5241.99815,N,00517.56525,E,0.005,,010809,,,A*7B +!AIVDO,1,1,,,B3aC3LP00063aj7RNpl03wSUwP06,0*43 +!AIVDM,1,1,,B,13njCt031t0DA=lN2:jKmad60l1p,0*12 +$GPGBS,194907.00,3.0,1.9,4.2,,,,*4E +$GPRMC,194908.00,A,5241.99805,N,00517.56503,E,0.003,,010809,,,A*77 +!AIVDO,1,1,,,B3aC3LP00063ai7RNph03wT5wP06,0*23 +!AIVDM,1,1,,B,33meMd50000EoJPMvw?:Ubp@0000,0*4F +$GPGBS,194908.00,3.0,1.9,4.2,,,,*41 +$GPRMC,194909.00,A,5241.99792,N,00517.56477,E,0.004,,010809,,,A*72 +!AIVDO,1,1,,,B3aC3LP00063agWRNpd03wTUwP06,0*21 +$GPGBS,194909.00,3.0,1.9,4.2,,,,*40 +!AIVDM,1,1,,A,B3`gaQ000062PeWRIt403wTUoP06,0*11 +!AIVDM,1,1,,A,13b?ED00000E2`dN1S9=oS0@00Sb,0*6E +$GPRMC,194910.00,A,5241.99782,N,00517.56453,E,0.006,,010809,,,A*7F +!AIVDO,1,1,,,B3aC3LP00063afWRNp`03wU5wP06,0*45 +!AIVDM,1,1,,A,D02E3:0Alg6D000000000000001,2*17 +$GPGBS,194910.00,3.0,1.9,4.2,,,,*48 +!AIVDM,1,1,,A,139QcE7P?w4?wv0PS<,0*5A +$GPRMC,194911.00,A,5241.99772,N,00517.56430,E,0.020,229.98,010809,,,A*66 +!AIVDM,1,1,,B,402E3:0000HttPGEahN7pi700p6T,0*09 +!AIVDM,1,1,,A,14S64>51ASPEeIpN05::v`lF086a,0*3B +!AIVDO,1,1,,,B3aC3LP00063aeWRNpV?gwUUwP06,0*4B +$GPGBS,194911.00,3.0,1.9,4.2,,,,*49 +!AIVDM,1,1,,B,13bf9v00010IaB5OP1S0GmF@N0OLBF?vL00SQ,0*35 +$GPRMC,194916.00,A,5241.99726,N,00517.56385,E,0.007,,010809,,,A*7A +!AIVDO,1,1,,,B3aC3LP00063ac7RNp@03w`5wP06,0*35 +$GPGBS,194916.00,3.0,1.9,4.2,,,,*4E +!AIVDM,1,1,,B,100001?P?w4?wp0W3h,0*28 +$GPRMC,194917.00,A,5241.99721,N,00517.56389,E,0.003,,010809,,,A*74 +!AIVDO,1,1,,,B3aC3LP00063ac7RNp@03w`UwP06,0*55 +$GPGBS,194917.00,3.0,1.9,4.2,,,,*4F +$GPRMC,194918.00,A,5241.99715,N,00517.56394,E,0.004,,010809,,,A*77 +!AIVDO,1,1,,,B3aC3LP00063acWRNp<03wa5wP06,0*28 +$GPGBS,194918.00,3.0,1.9,4.2,,,,*40 +!AIVDM,2,1,8,B,54S64>02;dlqK8@cL00lDADl0000000000000016;0<:65wj0?hCDm1DQ0C@,0*63 +!AIVDM,2,2,8,B,00000000002,2*2D +$GPRMC,194919.00,A,5241.99711,N,00517.56399,E,0.004,,010809,,,A*7F +!AIVDO,1,1,,,B3aC3LP00063acWRNp<03waUwP06,0*48 +$GPGBS,194919.00,3.0,1.9,4.2,,,,*41 +$GPRMC,194920.00,A,5241.99711,N,00517.56409,E,0.005,,010809,,,A*7A +!AIVDM,1,1,,B,13`g5:0P0`0E9MbN1FgDE?vV06K4,0*45 +!AIVDO,1,1,,,B3aC3LP00063ad7RNp<03wb5wP06,0*4C +!AIVDM,1,1,,A,13BE3l001n0DJHVN1fQJrHjb00SU,0*35 +$GPGBS,194920.00,3.0,1.9,4.2,,,,*4B +$GPRMC,194921.00,A,5241.99708,N,00517.56417,E,0.007,,010809,,,A*7E +!AIVDM,1,1,,A,13bf9v00010IaApN8IK3uSvd0Hf>428b0D1S,0*43 +$GPRMC,194923.00,A,5241.99704,N,00517.56423,E,0.007,,010809,,,A*77 +$GPGBS,194923.00,3.0,1.9,4.2,,,,*48 +!AIVDO,1,1,,,B3aC3LP00063ae7RNp803wcUwP06,0*28 +$GPRMC,194924.00,A,5241.99705,N,00517.56425,E,0.006,,010809,,,A*76 +$GPGBS,194924.00,3.0,1.9,4.2,,,,*4F +!AIVDO,1,1,,,B3aC3LP00063ae7RNp803wd5wP06,0*4F +!AIVDM,1,1,,B,100001?P?w4?wp0PS6,0*11 +!AIVDM,1,1,,B,13aC225P130HqQ@N3tfQ5OvfP6K4,0*37 +$GPRMC,194925.00,A,5241.99714,N,00517.56429,E,0.002,,010809,,,A*7F +$GPGBS,194925.00,3.0,1.9,4.2,,,,*4E +!AIVDO,1,1,,,B3aC3LP00063ae7RNp<03wdUwP06,0*2B +!AIVDM,1,1,,B,D02E3:1FTg6D000000000000001,2*2A +$GPRMC,194926.00,A,5241.99718,N,00517.56440,E,0.010,,010809,,,A*7C +$GPGBS,194926.00,3.0,1.9,4.2,,,,*4D +!AIVDO,1,1,,,B3aC3LP00063af7RNp<03we5wP06,0*49 +$GPRMC,194927.00,A,5241.99723,N,00517.56454,E,0.009,,010809,,,A*78 +$GPGBS,194927.00,3.0,1.9,4.2,,,,*4C +!AIVDO,1,1,,,B3aC3LP00063afWRNp@03weUsP06,0*31 +!AIVDM,1,1,,A,13`p;<0P0`0E8p0N1GU4G?vl@@@G,0*32 +$GPRMC,194928.00,A,5241.99730,N,00517.56469,E,0.005,,010809,,,A*77 +$GPGBS,194928.00,3.0,1.9,4.2,,,,*43 +!AIVDO,1,1,,,B3aC3LP00063ag7RNpD03wf5sP06,0*37 +!AIVDM,1,1,,B,100001?P?w4?wp0PS3,0*14 +$GPRMC,194929.00,A,5241.99738,N,00517.56482,E,0.002,,010809,,,A*7C +$GPGBS,194929.00,3.0,1.9,4.2,,,,*42 +!AIVDO,1,1,,,B3aC3LP00063ah7RNpD03wfUsP06,0*58 +!AIVDM,1,1,,A,139QcE7P?w4?wv0URP,0*32 +$GPRMC,194930.00,A,5241.99745,N,00517.56492,E,0.006,,010809,,,A*7B +$GPGBS,194930.00,3.0,1.9,4.2,,,,*4A +!AIVDO,1,1,,,B3aC3LP00063ahWRNpH03wg5sP06,0*55 +!AIVDM,1,1,,B,402E3:0000HttPGEahN7pi700pBB,0*6B +$GPRMC,194931.00,A,5241.99750,N,00517.56500,E,0.002,,010809,,,A*70 +$GPGBS,194931.00,3.0,1.9,4.2,,,,*4B +!AIVDM,1,1,,B,13bcuF0P000H@F2N:0tLH03wkUoP06,0*00 +$GPGBS,194939.00,3.0,1.9,4.2,,,,*43 +!AIVDM,1,1,,B,B3`gaQ000062Pc7RIt403wkUoP06,0*4B +!AIVDM,1,1,,B,139QcE7P?w4?wv0l08,0*02 +!AIVDO,1,1,,,B3aC3LP00063ajWRNph03wkUsP06,0*1B +$GPRMC,194940.00,A,5241.99812,N,00517.56549,E,0.005,,010809,,,A*75 diff --git a/test/daemon/ait250.log.chk b/test/daemon/ait250.log.chk new file mode 100644 index 0000000..ba4a826 --- /dev/null +++ b/test/daemon/ait250.log.chk @@ -0,0 +1,215 @@ +$GPRMC,194907.00,A,5241.99815,N,00517.56525,E,0.005,,010809,,,A*7B +{"class":"TPV","tag":"RMC","time":1249156147.000,"ept":0.005,"lat":52.699969167,"lon":5.292754167,"track":0.0000,"speed":0.003,"mode":2} +!AIVDO,1,1,,,B3aC3LP00063aj7RNpl03wSUwP06,0*43 +!AIVDM,1,1,,B,13njCt031t0DA=lN2:jKmad60l1p,0*12 +{"class":"AIS","type":1,"repeat":0,"mmsi":258774000,"scaled":false,"status":0,"turn":12,"speed":124,"accuracy":false,"lon":2656698,"lat":31492809,"course":3030,"heading":310,"second":3,"maneuver":0,"raim":false,"radio":426224} +$GPGBS,194907.00,3.0,1.9,4.2,,,,*4E +$GPRMC,194908.00,A,5241.99805,N,00517.56503,E,0.003,,010809,,,A*77 +!AIVDO,1,1,,,B3aC3LP00063ai7RNph03wT5wP06,0*23 +!AIVDM,1,1,,B,33meMd50000EoJPMvw?:Ubp@0000,0*4F +{"class":"AIS","type":3,"repeat":0,"mmsi":257646000,"scaled":false,"status":5,"turn":0,"speed":0,"accuracy":false,"lon":2866000,"lat":31440700,"course":2710,"heading":348,"second":8,"maneuver":0,"raim":false,"radio":0} +$GPGBS,194908.00,3.0,1.9,4.2,,,,*41 +{"class":"TPV","tag":"GBS","time":1249156148.000,"ept":0.005,"lat":52.699967500,"lon":5.292750500,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.002,"mode":2} +$GPRMC,194909.00,A,5241.99792,N,00517.56477,E,0.004,,010809,,,A*72 +!AIVDO,1,1,,,B3aC3LP00063agWRNpd03wTUwP06,0*21 +$GPGBS,194909.00,3.0,1.9,4.2,,,,*40 +{"class":"TPV","tag":"GBS","time":1249156149.000,"ept":0.005,"lat":52.699965333,"lon":5.292746167,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.002,"mode":2} +!AIVDM,1,1,,A,B3`gaQ000062PeWRIt403wTUoP06,0*11 +{"class":"AIS","type":18,"repeat":0,"mmsi":244050308,"scaled":false,"reserved":0,"speed":0,"accuracy":false,"lon":3166299,"lat":31614913,"course":0,"heading":511,"second":9,"regional":0,"cs":true,"display":false,"dsc":true,"band":true,"msg22":true,"raim":true,"radio":917510} +!AIVDM,1,1,,A,13b?ED00000E2`dN1S9=oS0@00Sb,0*6E +{"class":"AIS","type":1,"repeat":0,"mmsi":245618000,"scaled":false,"status":0,"turn":0,"speed":0,"accuracy":false,"lon":2757910,"lat":31482660,"course":3550,"heading":96,"second":8,"maneuver":0,"raim":false,"radio":4564} +$GPRMC,194910.00,A,5241.99782,N,00517.56453,E,0.006,,010809,,,A*7F +!AIVDO,1,1,,,B3aC3LP00063afWRNp`03wU5wP06,0*45 +!AIVDM,1,1,,A,D02E3:0Alg6D000000000000001,2*17 +{"class":"AIS","type":20,"repeat":0,"mmsi":2442024,"scaled":false,"offset1":285,"number1":2,"timeout1":7,"increment1":1125,"offset2":0,"number2":0,"timeout2":0,"increment2":0,"offset3":0,"number3":0,"timeout3":0,"increment3":0,"offset4":0,"number4":0,"timeout4":0,"increment4":0} +$GPGBS,194910.00,3.0,1.9,4.2,,,,*48 +{"class":"TPV","tag":"GBS","time":1249156150.000,"ept":0.005,"lat":52.699963667,"lon":5.292742167,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.003,"mode":2} +!AIVDM,1,1,,A,139QcE7P?w4?wv0PS<,0*5A +{"class":"AIS","type":1,"repeat":0,"mmsi":211315540,"scaled":false,"status":7,"turn":-128,"speed":1023,"accuracy":false,"lon":108600000,"lat":54600000,"course":3600,"heading":511,"second":63,"maneuver":0,"raim":false,"radio":266648} +$GPRMC,194911.00,A,5241.99772,N,00517.56430,E,0.020,229.98,010809,,,A*66 +!AIVDM,1,1,,B,402E3:0000HttPGEahN7pi700p6T,0*09 +{"class":"AIS","type":4,"repeat":0,"mmsi":2442024,"scaled":false,"timestamp":"0000-00-00T24:60:60Z","accuracy":true,"lon":3059000,"lat":31586500,"epfd":7,"raim":false,"radio":229796} +!AIVDM,1,1,,A,14S64>51ASPEeIpN05::v`lF086a,0*3B +{"class":"AIS","type":1,"repeat":0,"mmsi":305235000,"scaled":false,"status":5,"turn":5,"speed":99,"accuracy":true,"lon":2845500,"lat":31458600,"course":2810,"heading":282,"second":11,"maneuver":0,"raim":false,"radio":66386} +!AIVDO,1,1,,,B3aC3LP00063aeWRNpV?gwUUwP06,0*4B +$GPGBS,194911.00,3.0,1.9,4.2,,,,*49 +{"class":"TPV","tag":"GBS","time":1249156151.000,"ept":0.005,"lat":52.699962000,"lon":5.292738333,"epx":1.900,"epy":3.000,"track":229.9800,"speed":0.010,"mode":2} +!AIVDM,1,1,,B,13bf9v00010IaB5OP1S0GmF@N0OLBF?vL00SQ,0*35 +{"class":"AIS","type":1,"repeat":0,"mmsi":244010517,"scaled":false,"status":15,"turn":-128,"speed":99,"accuracy":false,"lon":3123912,"lat":31465329,"course":600,"heading":511,"second":14,"maneuver":0,"raim":false,"radio":4546} +$GPRMC,194916.00,A,5241.99726,N,00517.56385,E,0.007,,010809,,,A*7A +!AIVDO,1,1,,,B3aC3LP00063ac7RNp@03w`5wP06,0*35 +$GPGBS,194916.00,3.0,1.9,4.2,,,,*4E +{"class":"TPV","tag":"GBS","time":1249156156.000,"ept":0.005,"lat":52.699954333,"lon":5.292730833,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.004,"mode":2} +!AIVDM,1,1,,B,100001?P?w4?wp0W3h,0*28 +{"class":"AIS","type":1,"repeat":0,"mmsi":4,"scaled":false,"status":15,"turn":-128,"speed":1023,"accuracy":false,"lon":108600000,"lat":54600000,"course":3600,"heading":511,"second":60,"maneuver":0,"raim":false,"radio":319968} +$GPRMC,194917.00,A,5241.99721,N,00517.56389,E,0.003,,010809,,,A*74 +!AIVDO,1,1,,,B3aC3LP00063ac7RNp@03w`UwP06,0*55 +$GPGBS,194917.00,3.0,1.9,4.2,,,,*4F +{"class":"TPV","tag":"GBS","time":1249156157.000,"ept":0.005,"lat":52.699953500,"lon":5.292731500,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.002,"mode":2} +$GPRMC,194918.00,A,5241.99715,N,00517.56394,E,0.004,,010809,,,A*77 +!AIVDO,1,1,,,B3aC3LP00063acWRNp<03wa5wP06,0*28 +$GPGBS,194918.00,3.0,1.9,4.2,,,,*40 +{"class":"TPV","tag":"GBS","time":1249156158.000,"ept":0.005,"lat":52.699952500,"lon":5.292732333,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.002,"mode":2} +!AIVDM,2,1,8,B,54S64>02;dlqK8@cL00lDADl0000000000000016;0<:65wj0?hCDm1DQ0C@,0*63 +!AIVDM,2,2,8,B,00000000002,2*2D +{"class":"AIS","type":5,"repeat":0,"mmsi":305235000,"scaled":false,"imo":9155406,"ais_version":0,"callsign":"V2DJ7","shipname":"MEDUM","shiptype":70,"to_bow":88,"to_stern":12,"to_port":10,"to_starboard":6,"epfd":1,"eta":"07-31T18:00Z","draught":63,"destination":"AMSTERDAM","dte":0} +$GPRMC,194919.00,A,5241.99711,N,00517.56399,E,0.004,,010809,,,A*7F +!AIVDO,1,1,,,B3aC3LP00063acWRNp<03waUwP06,0*48 +$GPGBS,194919.00,3.0,1.9,4.2,,,,*41 +{"class":"TPV","tag":"GBS","time":1249156159.000,"ept":0.005,"lat":52.699951833,"lon":5.292733167,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.002,"mode":2} +$GPRMC,194920.00,A,5241.99711,N,00517.56409,E,0.005,,010809,,,A*7A +!AIVDM,1,1,,B,13`g5:0P0`0E9MbN1FgDE?vV06K4,0*45 +{"class":"AIS","type":1,"repeat":0,"mmsi":244041000,"scaled":false,"status":0,"turn":-128,"speed":40,"accuracy":false,"lon":2771893,"lat":31479485,"course":1108,"heading":511,"second":19,"maneuver":0,"raim":false,"radio":52616} +!AIVDO,1,1,,,B3aC3LP00063ad7RNp<03wb5wP06,0*4C +!AIVDM,1,1,,A,13BE3l001n0DJHVN1fQJrHjb00SU,0*35 +{"class":"AIS","type":1,"repeat":0,"mmsi":220546000,"scaled":false,"status":0,"turn":0,"speed":118,"accuracy":false,"lon":2675475,"lat":31485573,"course":2793,"heading":281,"second":21,"maneuver":0,"raim":false,"radio":4554} +$GPGBS,194920.00,3.0,1.9,4.2,,,,*4B +{"class":"TPV","tag":"GBS","time":1249156160.000,"ept":0.005,"lat":52.699951833,"lon":5.292734833,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.003,"mode":2} +$GPRMC,194921.00,A,5241.99708,N,00517.56417,E,0.007,,010809,,,A*7E +!AIVDM,1,1,,A,13bf9v00010IaApN8IK3uSvd0Hf>428b0D1S,0*43 +{"class":"AIS","type":1,"repeat":0,"mmsi":247254200,"scaled":false,"status":1,"turn":0,"speed":1023,"accuracy":true,"lon":2582900,"lat":31510200,"course":3600,"heading":68,"second":21,"maneuver":0,"raim":false,"radio":164038} +$GPRMC,194923.00,A,5241.99704,N,00517.56423,E,0.007,,010809,,,A*77 +$GPGBS,194923.00,3.0,1.9,4.2,,,,*48 +{"class":"TPV","tag":"GBS","time":1249156163.000,"ept":0.005,"lat":52.699950667,"lon":5.292737167,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.004,"mode":2} +!AIVDO,1,1,,,B3aC3LP00063ae7RNp803wcUwP06,0*28 +$GPRMC,194924.00,A,5241.99705,N,00517.56425,E,0.006,,010809,,,A*76 +$GPGBS,194924.00,3.0,1.9,4.2,,,,*4F +{"class":"TPV","tag":"GBS","time":1249156164.000,"ept":0.005,"lat":52.699950833,"lon":5.292737500,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.003,"mode":2} +!AIVDO,1,1,,,B3aC3LP00063ae7RNp803wd5wP06,0*4F +!AIVDM,1,1,,B,100001?P?w4?wp0PS6,0*11 +{"class":"AIS","type":1,"repeat":0,"mmsi":4,"scaled":false,"status":15,"turn":-128,"speed":1023,"accuracy":false,"lon":108600000,"lat":54600000,"course":3600,"heading":511,"second":60,"maneuver":0,"raim":false,"radio":266636} +!AIVDM,1,1,,B,13aC225P130HqQ@N3tfQ5OvfP6K4,0*37 +{"class":"AIS","type":1,"repeat":0,"mmsi":244630024,"scaled":false,"status":5,"turn":-128,"speed":67,"accuracy":false,"lon":3263528,"lat":31521978,"course":277,"heading":511,"second":23,"maneuver":1,"raim":false,"radio":52616} +$GPRMC,194925.00,A,5241.99714,N,00517.56429,E,0.002,,010809,,,A*7F +$GPGBS,194925.00,3.0,1.9,4.2,,,,*4E +{"class":"TPV","tag":"GBS","time":1249156165.000,"ept":0.005,"lat":52.699952333,"lon":5.292738167,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.001,"mode":2} +!AIVDO,1,1,,,B3aC3LP00063ae7RNp<03wdUwP06,0*2B +!AIVDM,1,1,,B,D02E3:1FTg6D000000000000001,2*2A +{"class":"AIS","type":20,"repeat":0,"mmsi":2442024,"scaled":false,"offset1":1385,"number1":2,"timeout1":7,"increment1":1125,"offset2":0,"number2":0,"timeout2":0,"increment2":0,"offset3":0,"number3":0,"timeout3":0,"increment3":0,"offset4":0,"number4":0,"timeout4":0,"increment4":0} +$GPRMC,194926.00,A,5241.99718,N,00517.56440,E,0.010,,010809,,,A*7C +$GPGBS,194926.00,3.0,1.9,4.2,,,,*4D +{"class":"TPV","tag":"GBS","time":1249156166.000,"ept":0.005,"lat":52.699953000,"lon":5.292740000,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.005,"mode":2} +!AIVDO,1,1,,,B3aC3LP00063af7RNp<03we5wP06,0*49 +$GPRMC,194927.00,A,5241.99723,N,00517.56454,E,0.009,,010809,,,A*78 +$GPGBS,194927.00,3.0,1.9,4.2,,,,*4C +{"class":"TPV","tag":"GBS","time":1249156167.000,"ept":0.005,"lat":52.699953833,"lon":5.292742333,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.005,"mode":2} +!AIVDO,1,1,,,B3aC3LP00063afWRNp@03weUsP06,0*31 +!AIVDM,1,1,,A,13`p;<0P0`0E8p0N1GU4G?vl@@@G,0*32 +{"class":"AIS","type":1,"repeat":0,"mmsi":244190000,"scaled":false,"status":0,"turn":-128,"speed":40,"accuracy":false,"lon":2770688,"lat":31479700,"course":1116,"heading":511,"second":26,"maneuver":0,"raim":false,"radio":133166} +$GPRMC,194928.00,A,5241.99730,N,00517.56469,E,0.005,,010809,,,A*77 +$GPGBS,194928.00,3.0,1.9,4.2,,,,*43 +{"class":"TPV","tag":"GBS","time":1249156168.000,"ept":0.005,"lat":52.699955000,"lon":5.292744833,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.003,"mode":2} +!AIVDO,1,1,,,B3aC3LP00063ag7RNpD03wf5sP06,0*37 +!AIVDM,1,1,,B,100001?P?w4?wp0PS3,0*14 +{"class":"AIS","type":1,"repeat":0,"mmsi":4,"scaled":false,"status":15,"turn":-128,"speed":1023,"accuracy":false,"lon":108600000,"lat":54600000,"course":3600,"heading":511,"second":60,"maneuver":0,"raim":false,"radio":266630} +$GPRMC,194929.00,A,5241.99738,N,00517.56482,E,0.002,,010809,,,A*7C +$GPGBS,194929.00,3.0,1.9,4.2,,,,*42 +{"class":"TPV","tag":"GBS","time":1249156169.000,"ept":0.005,"lat":52.699956333,"lon":5.292747000,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.001,"mode":2} +!AIVDO,1,1,,,B3aC3LP00063ah7RNpD03wfUsP06,0*58 +!AIVDM,1,1,,A,139QcE7P?w4?wv0URP,0*32 +{"class":"AIS","type":1,"repeat":0,"mmsi":211315540,"scaled":false,"status":7,"turn":-128,"speed":1023,"accuracy":false,"lon":108600000,"lat":54600000,"course":3600,"heading":511,"second":63,"maneuver":0,"raim":false,"radio":307520} +$GPRMC,194930.00,A,5241.99745,N,00517.56492,E,0.006,,010809,,,A*7B +$GPGBS,194930.00,3.0,1.9,4.2,,,,*4A +{"class":"TPV","tag":"GBS","time":1249156170.000,"ept":0.005,"lat":52.699957500,"lon":5.292748667,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.003,"mode":2} +!AIVDO,1,1,,,B3aC3LP00063ahWRNpH03wg5sP06,0*55 +!AIVDM,1,1,,B,402E3:0000HttPGEahN7pi700pBB,0*6B +{"class":"AIS","type":4,"repeat":0,"mmsi":2442024,"scaled":false,"timestamp":"0000-00-00T24:60:60Z","accuracy":true,"lon":3059000,"lat":31586500,"epfd":7,"raim":false,"radio":230546} +$GPRMC,194931.00,A,5241.99750,N,00517.56500,E,0.002,,010809,,,A*70 +$GPGBS,194931.00,3.0,1.9,4.2,,,,*4B +{"class":"TPV","tag":"GBS","time":1249156171.000,"ept":0.005,"lat":52.699958333,"lon":5.292750000,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.001,"mode":2} +!AIVDM,1,1,,B,13bcuF0P000H@F2N:0tLH03wkUoP06,0*00 +{"class":"AIS","type":18,"repeat":0,"mmsi":244100276,"scaled":false,"reserved":0,"speed":0,"accuracy":false,"lon":3179598,"lat":31622374,"course":0,"heading":511,"second":39,"regional":0,"cs":true,"display":false,"dsc":true,"band":true,"msg22":true,"raim":true,"radio":917510} +$GPGBS,194939.00,3.0,1.9,4.2,,,,*43 +{"class":"TPV","tag":"GBS","time":1249156179.000,"ept":0.005,"lat":52.699968167,"lon":5.292756500,"epx":1.900,"epy":3.000,"track":0.0000,"speed":0.005,"mode":2} +!AIVDM,1,1,,B,B3`gaQ000062Pc7RIt403wkUoP06,0*4B +{"class":"AIS","type":18,"repeat":0,"mmsi":244050308,"scaled":false,"reserved":0,"speed":0,"accuracy":false,"lon":3166294,"lat":31614913,"course":0,"heading":511,"second":39,"regional":0,"cs":true,"display":false,"dsc":true,"band":true,"msg22":true,"raim":true,"radio":917510} +!AIVDM,1,1,,B,139QcE7P?w4?wv0l08,0*02 +{"class":"AIS","type":1,"repeat":0,"mmsi":211315540,"scaled":false,"status":7,"turn":-128,"speed":1023,"accuracy":false,"lon":108600000,"lat":54600000,"course":3600,"heading":511,"second":63,"maneuver":0,"raim":false,"radio":426000} +!AIVDO,1,1,,,B3aC3LP00063ajWRNph03wkUsP06,0*1B +$GPRMC,194940.00,A,5241.99812,N,00517.56549,E,0.005,,010809,,,A*75 diff --git a/test/daemon/blumax-gps009.log b/test/daemon/blumax-gps009.log new file mode 100644 index 0000000..b438139 --- /dev/null +++ b/test/daemon/blumax-gps009.log @@ -0,0 +1,83 @@ +# Name: Blumax GPS-009 +# Chipset: SiRF Star III (according to data sheet) +# Submitted-by: Hartmut Holzgraefe +# Date: 18 July 2008 +# Location: Bielefeld, DE, 52=B0 01' N, 08=B0 31' O +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# Following lines are +# `cat /dev/ttyACM0` at startup +$PSRFTXTVersion GSW3.2.2_3.1.00.12-SDK003P1.01a *78 +$PSRFTXTGreat-Well 20061201*33 +$PSRFTXTTOW: 484076*30 +$PSRFTXTWK: 1488*4C +$PSRFTXTPOS: 3889831 583832 5004208*35 +$PSRFTXTCLK: 95879*0B +$PSRFTXTCHNL: 12*5F +$PSRFTXTBaud rate: 57600 *51 +$GPGGA,142816.359,,,,,0,00,,,M,0.0,M,,0000*51 +$GPGLL,,,,,142816.359,V,N*7D +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,3,1,12,12,48,233,,17,39,066,,15,29,172,,22,19,291,*70 +$GPGSV,3,2,12,26,17,161,,09,81,300,,05,32,240,,29,31,171,*70 +$GPGSV,3,3,12,18,15,251,,14,14,319,,28,08,059,,30,08,239,*77 +$GPRMC,142816.359,V,,,,,,,180708,,,N*4C +$GPGGA,142817.299,,,,,0,00,,,M,0.0,M,,0000*5D +$GPGLL,,,,,142817.299,V,N*71 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,3,1,12,12,48,233,,17,39,066,,15,29,172,,22,19,291,*70 +$GPGSV,3,2,12,26,17,161,28,09,81,300,,05,32,240,,29,31,171,*7A +$GPGSV,3,3,12,18,15,251,,14,14,319,,28,08,059,,30,08,239,*77 +$GPRMC,142817.299,V,,,,,,,180708,,,N*40 +$GPGGA,142818.299,,,,,0,00,,,M,0.0,M,,0000*52 +$GPGLL,,,,,142818.299,V,N*7E +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,3,1,12,12,48,233,,17,39,066,,15,29,172,,22,19,291,*70 +$GPGSV,3,2,12,26,17,161,29,09,81,300,,05,32,240,21,29,31,171,*78 +$GPGSV,3,3,12,18,15,251,,14,14,319,,28,08,059,,30,08,239,*77 +$GPRMC,142818.299,V,,,,,,,180708,,,N*4F +$GPGGA,142818.899,5201.0687,N,00832.0645,E,0,04,,35.8,M,47.2,M,,0000*47 +$GPGLL,5201.0687,N,00832.0645,E,142818.899,V,N*4E +$GPGSA,A,1,26,22,12,15,,,,,,,,,,,*1D +$GPGSV,3,1,12,12,48,233,28,17,39,066,,15,29,172,33,22,19,290,23*7A +$GPGSV,3,2,12,26,17,161,31,09,81,300,,05,32,240,23,29,31,171,*73 +$GPGSV,3,3,12,18,15,251,,14,14,319,,28,08,059,,30,08,239,*77 +$GPRMC,142818.899,V,5201.0687,N,00832.0645,E,,,180708,,,N*7F +$GPGGA,142819.299,5201.0809,N,00832.0852,E,1,04,4.9,32.1,M,47.2,M,,0000*60 +$GPGLL,5201.0809,N,00832.0852,E,142819.299,A,A*5D +$GPGSA,A,3,26,22,12,15,,,,,,,,,5.0,4.9,1.0*38 +$GPGSV,3,1,12,12,48,233,29,17,39,066,,15,29,172,35,22,19,290,22*7C +$GPGSV,3,2,12,26,17,161,31,09,81,300,,05,32,240,24,29,31,171,*74 +$GPGSV,3,3,12,18,15,251,,14,14,319,,28,08,059,,30,08,239,*77 +$GPRMC,142819.299,A,5201.0809,N,00832.0852,E,0.87,249.59,180708,,,A*60 +# ... +# +# Following lines are +# `cat /dev/ttyACM0` stationary +$GPZDA,143054.000,18,07,2008,,*55 +$GPGGA,143054.000,5201.1302,N,00832.1652,E,1,05,1.2,72.2,M,47.2,M,,0000*64 +$GPGLL,5201.1302,N,00832.1652,E,143054.000,A,A*51 +$GPGSA,A,3,26,17,22,12,15,,,,,,,,2.9,1.2,2.6*3B +$GPGSV,3,1,12,09,82,301,19,12,49,234,27,17,39,065,33,05,33,241,22*72 +$GPGSV,3,2,12,29,30,171,,15,27,172,38,22,19,289,29,26,15,162,30*7C +$GPGSV,3,3,12,14,15,319,21,18,14,250,13,30,09,240,17,28,07,059,15*75 +$GPRMC,143054.000,A,5201.1302,N,00832.1652,E,0.06,48.00,180708,,,A*5A +$GPZDA,143055.000,18,07,2008,,*54 +$GPGGA,143055.000,5201.1302,N,00832.1652,E,1,05,1.2,72.2,M,47.2,M,,0000*65 +$GPGLL,5201.1302,N,00832.1652,E,143055.000,A,A*50 +$GPGSA,A,3,26,17,22,12,15,,,,,,,,2.9,1.2,2.6*3B +$GPGSV,3,1,12,09,82,301,20,12,49,234,27,17,39,065,33,05,33,241,22*78 +$GPGSV,3,2,12,29,30,171,,15,27,172,38,22,19,289,29,26,15,162,30*7C +$GPGSV,3,3,12,14,15,319,21,18,14,250,13,30,09,240,17,28,07,059,15*75 +$GPRMC,143055.000,A,5201.1302,N,00832.1652,E,0.08,64.91,180708,,,A*53 +$GPZDA,143056.000,18,07,2008,,*57 +$GPGGA,143056.000,5201.1302,N,00832.1652,E,1,05,1.2,72.3,M,47.2,M,,0000*67 +$GPGLL,5201.1302,N,00832.1652,E,143056.000,A,A*53 +$GPGSA,A,3,26,17,22,12,15,,,,,,,,2.9,1.2,2.6*3B +$GPGSV,3,1,12,09,82,301,20,12,49,234,27,17,39,065,33,05,33,241,22*78 +$GPGSV,3,2,12,29,30,171,,15,27,172,38,22,19,289,29,26,15,162,31*7D +$GPGSV,3,3,12,14,15,319,20,18,14,250,13,30,09,240,16,28,07,059,15*75 +$GPRMC,143056.000,A,5201.1302,N,00832.1652,E,0.07,45.54,180708,,,A*55 + diff --git a/test/daemon/blumax-gps009.log.chk b/test/daemon/blumax-gps009.log.chk new file mode 100644 index 0000000..a03c160 --- /dev/null +++ b/test/daemon/blumax-gps009.log.chk @@ -0,0 +1,83 @@ +$PSRFTXTVersion GSW3.2.2_3.1.00.12-SDK003P1.01a *78 +$PSRFTXTGreat-Well 20061201*33 +$PSRFTXTTOW: 484076*30 +$PSRFTXTWK: 1488*4C +$PSRFTXTPOS: 3889831 583832 5004208*35 +$PSRFTXTCLK: 95879*0B +$PSRFTXTCHNL: 12*5F +$PSRFTXTBaud rate: 57600 *51 +$GPGGA,142816.359,,,,,0,00,,,M,0.0,M,,0000*51 +$GPGLL,,,,,142816.359,V,N*7D +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,12,48,233,,17,39,066,,15,29,172,,22,19,291,*70 +$GPGSV,3,2,12,26,17,161,,09,81,300,,05,32,240,,29,31,171,*70 +$GPGSV,3,3,12,18,15,251,,14,14,319,,28,08,059,,30,08,239,*77 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":48,"az":233,"ss":0,"used":false},{"PRN":17,"el":39,"az":66,"ss":0,"used":false},{"PRN":15,"el":29,"az":172,"ss":0,"used":false},{"PRN":22,"el":19,"az":291,"ss":0,"used":false},{"PRN":26,"el":17,"az":161,"ss":0,"used":false},{"PRN":9,"el":81,"az":300,"ss":0,"used":false},{"PRN":5,"el":32,"az":240,"ss":0,"used":false},{"PRN":29,"el":31,"az":171,"ss":0,"used":false},{"PRN":18,"el":15,"az":251,"ss":0,"used":false},{"PRN":14,"el":14,"az":319,"ss":0,"used":false},{"PRN":28,"el":8,"az":59,"ss":0,"used":false},{"PRN":30,"el":8,"az":239,"ss":0,"used":false}]} +$GPRMC,142816.359,V,,,,,,,180708,,,N*4C +$GPGGA,142817.299,,,,,0,00,,,M,0.0,M,,0000*5D +$GPGLL,,,,,142817.299,V,N*71 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,3,1,12,12,48,233,,17,39,066,,15,29,172,,22,19,291,*70 +$GPGSV,3,2,12,26,17,161,28,09,81,300,,05,32,240,,29,31,171,*7A +$GPGSV,3,3,12,18,15,251,,14,14,319,,28,08,059,,30,08,239,*77 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":48,"az":233,"ss":0,"used":false},{"PRN":17,"el":39,"az":66,"ss":0,"used":false},{"PRN":15,"el":29,"az":172,"ss":0,"used":false},{"PRN":22,"el":19,"az":291,"ss":0,"used":false},{"PRN":26,"el":17,"az":161,"ss":28,"used":false},{"PRN":9,"el":81,"az":300,"ss":0,"used":false},{"PRN":5,"el":32,"az":240,"ss":0,"used":false},{"PRN":29,"el":31,"az":171,"ss":0,"used":false},{"PRN":18,"el":15,"az":251,"ss":0,"used":false},{"PRN":14,"el":14,"az":319,"ss":0,"used":false},{"PRN":28,"el":8,"az":59,"ss":0,"used":false},{"PRN":30,"el":8,"az":239,"ss":0,"used":false}]} +$GPRMC,142817.299,V,,,,,,,180708,,,N*40 +$GPGGA,142818.299,,,,,0,00,,,M,0.0,M,,0000*52 +$GPGLL,,,,,142818.299,V,N*7E +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,3,1,12,12,48,233,,17,39,066,,15,29,172,,22,19,291,*70 +$GPGSV,3,2,12,26,17,161,29,09,81,300,,05,32,240,21,29,31,171,*78 +$GPGSV,3,3,12,18,15,251,,14,14,319,,28,08,059,,30,08,239,*77 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":48,"az":233,"ss":0,"used":false},{"PRN":17,"el":39,"az":66,"ss":0,"used":false},{"PRN":15,"el":29,"az":172,"ss":0,"used":false},{"PRN":22,"el":19,"az":291,"ss":0,"used":false},{"PRN":26,"el":17,"az":161,"ss":29,"used":false},{"PRN":9,"el":81,"az":300,"ss":0,"used":false},{"PRN":5,"el":32,"az":240,"ss":21,"used":false},{"PRN":29,"el":31,"az":171,"ss":0,"used":false},{"PRN":18,"el":15,"az":251,"ss":0,"used":false},{"PRN":14,"el":14,"az":319,"ss":0,"used":false},{"PRN":28,"el":8,"az":59,"ss":0,"used":false},{"PRN":30,"el":8,"az":239,"ss":0,"used":false}]} +$GPRMC,142818.299,V,,,,,,,180708,,,N*4F +$GPGGA,142818.899,5201.0687,N,00832.0645,E,0,04,,35.8,M,47.2,M,,0000*47 +$GPGLL,5201.0687,N,00832.0645,E,142818.899,V,N*4E +$GPGSA,A,1,26,22,12,15,,,,,,,,,,,*1D +$GPGSV,3,1,12,12,48,233,28,17,39,066,,15,29,172,33,22,19,290,23*7A +$GPGSV,3,2,12,26,17,161,31,09,81,300,,05,32,240,23,29,31,171,*73 +$GPGSV,3,3,12,18,15,251,,14,14,319,,28,08,059,,30,08,239,*77 +{"class":"SKY","tag":"GSV","xdop":0.88,"ydop":1.02,"vdop":3.53,"tdop":2.01,"hdop":1.34,"gdop":4.28,"pdop":3.78,"satellites":[{"PRN":12,"el":48,"az":233,"ss":28,"used":true},{"PRN":17,"el":39,"az":66,"ss":0,"used":false},{"PRN":15,"el":29,"az":172,"ss":33,"used":true},{"PRN":22,"el":19,"az":290,"ss":23,"used":true},{"PRN":26,"el":17,"az":161,"ss":31,"used":true},{"PRN":9,"el":81,"az":300,"ss":0,"used":false},{"PRN":5,"el":32,"az":240,"ss":23,"used":false},{"PRN":29,"el":31,"az":171,"ss":0,"used":false},{"PRN":18,"el":15,"az":251,"ss":0,"used":false},{"PRN":14,"el":14,"az":319,"ss":0,"used":false},{"PRN":28,"el":8,"az":59,"ss":0,"used":false},{"PRN":30,"el":8,"az":239,"ss":0,"used":false}]} +$GPRMC,142818.899,V,5201.0687,N,00832.0645,E,,,180708,,,N*7F +$GPGGA,142819.299,5201.0809,N,00832.0852,E,1,04,4.9,32.1,M,47.2,M,,0000*60 +$GPGLL,5201.0809,N,00832.0852,E,142819.299,A,A*5D +{"class":"TPV","tag":"GLL","lat":52.018015000,"lon":8.534753333,"alt":32.100,"epx":13.168,"epy":15.284,"epv":81.159,"mode":3} +$GPGSA,A,3,26,22,12,15,,,,,,,,,5.0,4.9,1.0*38 +$GPGSV,3,1,12,12,48,233,29,17,39,066,,15,29,172,35,22,19,290,22*7C +$GPGSV,3,2,12,26,17,161,31,09,81,300,,05,32,240,24,29,31,171,*74 +$GPGSV,3,3,12,18,15,251,,14,14,319,,28,08,059,,30,08,239,*77 +{"class":"SKY","tag":"GSV","xdop":0.88,"ydop":1.02,"vdop":3.53,"tdop":2.01,"hdop":1.34,"gdop":4.28,"pdop":3.78,"satellites":[{"PRN":12,"el":48,"az":233,"ss":29,"used":true},{"PRN":17,"el":39,"az":66,"ss":0,"used":false},{"PRN":15,"el":29,"az":172,"ss":35,"used":true},{"PRN":22,"el":19,"az":290,"ss":22,"used":true},{"PRN":26,"el":17,"az":161,"ss":31,"used":true},{"PRN":9,"el":81,"az":300,"ss":0,"used":false},{"PRN":5,"el":32,"az":240,"ss":24,"used":false},{"PRN":29,"el":31,"az":171,"ss":0,"used":false},{"PRN":18,"el":15,"az":251,"ss":0,"used":false},{"PRN":14,"el":14,"az":319,"ss":0,"used":false},{"PRN":28,"el":8,"az":59,"ss":0,"used":false},{"PRN":30,"el":8,"az":239,"ss":0,"used":false}]} +$GPRMC,142819.299,A,5201.0809,N,00832.0852,E,0.87,249.59,180708,,,A*60 +$GPZDA,143054.000,18,07,2008,,*55 +$GPGGA,143054.000,5201.1302,N,00832.1652,E,1,05,1.2,72.2,M,47.2,M,,0000*64 +$GPGLL,5201.1302,N,00832.1652,E,143054.000,A,A*51 +{"class":"TPV","tag":"GLL","time":1216391454.000,"ept":0.005,"lat":52.018836667,"lon":8.536086667,"alt":72.200,"epx":13.168,"epy":15.284,"epv":81.159,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,17,22,12,15,,,,,,,,2.9,1.2,2.6*3B +$GPGSV,3,1,12,09,82,301,19,12,49,234,27,17,39,065,33,05,33,241,22*72 +$GPGSV,3,2,12,29,30,171,,15,27,172,38,22,19,289,29,26,15,162,30*7C +$GPGSV,3,3,12,14,15,319,21,18,14,250,13,30,09,240,17,28,07,059,15*75 +{"class":"SKY","tag":"GSV","xdop":1.09,"ydop":1.57,"vdop":3.29,"tdop":2.50,"hdop":1.91,"gdop":4.55,"pdop":3.80,"satellites":[{"PRN":9,"el":82,"az":301,"ss":19,"used":false},{"PRN":12,"el":49,"az":234,"ss":27,"used":true},{"PRN":17,"el":39,"az":65,"ss":33,"used":true},{"PRN":5,"el":33,"az":241,"ss":22,"used":false},{"PRN":29,"el":30,"az":171,"ss":0,"used":false},{"PRN":15,"el":27,"az":172,"ss":38,"used":true},{"PRN":22,"el":19,"az":289,"ss":29,"used":true},{"PRN":26,"el":15,"az":162,"ss":30,"used":true},{"PRN":14,"el":15,"az":319,"ss":21,"used":false},{"PRN":18,"el":14,"az":250,"ss":13,"used":false},{"PRN":30,"el":9,"az":240,"ss":17,"used":false},{"PRN":28,"el":7,"az":59,"ss":15,"used":false}]} +$GPRMC,143054.000,A,5201.1302,N,00832.1652,E,0.06,48.00,180708,,,A*5A +{"class":"TPV","tag":"RMC","time":1216391454.000,"ept":0.005,"lat":52.018836667,"lon":8.536086667,"alt":72.200,"epx":13.168,"epy":15.284,"epv":81.159,"track":48.0000,"speed":0.031,"climb":0.000,"mode":3} +$GPZDA,143055.000,18,07,2008,,*54 +$GPGGA,143055.000,5201.1302,N,00832.1652,E,1,05,1.2,72.2,M,47.2,M,,0000*65 +$GPGLL,5201.1302,N,00832.1652,E,143055.000,A,A*50 +{"class":"TPV","tag":"GLL","time":1216391455.000,"ept":0.005,"lat":52.018836667,"lon":8.536086667,"alt":72.200,"epx":16.324,"epy":23.592,"epv":75.603,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,17,22,12,15,,,,,,,,2.9,1.2,2.6*3B +$GPGSV,3,1,12,09,82,301,20,12,49,234,27,17,39,065,33,05,33,241,22*78 +$GPGSV,3,2,12,29,30,171,,15,27,172,38,22,19,289,29,26,15,162,30*7C +$GPGSV,3,3,12,14,15,319,21,18,14,250,13,30,09,240,17,28,07,059,15*75 +{"class":"SKY","tag":"GSV","xdop":1.09,"ydop":1.57,"vdop":3.29,"tdop":2.50,"hdop":1.91,"gdop":4.55,"pdop":3.80,"satellites":[{"PRN":9,"el":82,"az":301,"ss":20,"used":false},{"PRN":12,"el":49,"az":234,"ss":27,"used":true},{"PRN":17,"el":39,"az":65,"ss":33,"used":true},{"PRN":5,"el":33,"az":241,"ss":22,"used":false},{"PRN":29,"el":30,"az":171,"ss":0,"used":false},{"PRN":15,"el":27,"az":172,"ss":38,"used":true},{"PRN":22,"el":19,"az":289,"ss":29,"used":true},{"PRN":26,"el":15,"az":162,"ss":30,"used":true},{"PRN":14,"el":15,"az":319,"ss":21,"used":false},{"PRN":18,"el":14,"az":250,"ss":13,"used":false},{"PRN":30,"el":9,"az":240,"ss":17,"used":false},{"PRN":28,"el":7,"az":59,"ss":15,"used":false}]} +$GPRMC,143055.000,A,5201.1302,N,00832.1652,E,0.08,64.91,180708,,,A*53 +{"class":"TPV","tag":"RMC","time":1216391455.000,"ept":0.005,"lat":52.018836667,"lon":8.536086667,"alt":72.200,"epx":16.324,"epy":23.592,"epv":75.603,"track":64.9100,"speed":0.041,"climb":0.000,"mode":3} +$GPZDA,143056.000,18,07,2008,,*57 +$GPGGA,143056.000,5201.1302,N,00832.1652,E,1,05,1.2,72.3,M,47.2,M,,0000*67 +$GPGLL,5201.1302,N,00832.1652,E,143056.000,A,A*53 +{"class":"TPV","tag":"GLL","time":1216391456.000,"ept":0.005,"lat":52.018836667,"lon":8.536086667,"alt":72.300,"epx":16.324,"epy":23.592,"epv":75.603,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,17,22,12,15,,,,,,,,2.9,1.2,2.6*3B +$GPGSV,3,1,12,09,82,301,20,12,49,234,27,17,39,065,33,05,33,241,22*78 +$GPGSV,3,2,12,29,30,171,,15,27,172,38,22,19,289,29,26,15,162,31*7D +$GPGSV,3,3,12,14,15,319,20,18,14,250,13,30,09,240,16,28,07,059,15*75 +{"class":"SKY","tag":"GSV","xdop":1.09,"ydop":1.57,"vdop":3.29,"tdop":2.50,"hdop":1.91,"gdop":4.55,"pdop":3.80,"satellites":[{"PRN":9,"el":82,"az":301,"ss":20,"used":false},{"PRN":12,"el":49,"az":234,"ss":27,"used":true},{"PRN":17,"el":39,"az":65,"ss":33,"used":true},{"PRN":5,"el":33,"az":241,"ss":22,"used":false},{"PRN":29,"el":30,"az":171,"ss":0,"used":false},{"PRN":15,"el":27,"az":172,"ss":38,"used":true},{"PRN":22,"el":19,"az":289,"ss":29,"used":true},{"PRN":26,"el":15,"az":162,"ss":31,"used":true},{"PRN":14,"el":15,"az":319,"ss":20,"used":false},{"PRN":18,"el":14,"az":250,"ss":13,"used":false},{"PRN":30,"el":9,"az":240,"ss":16,"used":false},{"PRN":28,"el":7,"az":59,"ss":15,"used":false}]} +$GPRMC,143056.000,A,5201.1302,N,00832.1652,E,0.07,45.54,180708,,,A*55 +{"class":"TPV","tag":"RMC","time":1216391456.000,"ept":0.005,"lat":52.018836667,"lon":8.536086667,"alt":72.300,"epx":16.324,"epy":23.592,"epv":75.603,"track":45.5400,"speed":0.036,"climb":0.000,"mode":3} diff --git a/test/daemon/bn-9015.log b/test/daemon/bn-9015.log new file mode 100644 index 0000000..ef8b735 --- /dev/null +++ b/test/daemon/bn-9015.log @@ -0,0 +1,534 @@ +# Name: Bluenext BN-9015 +# Chipset: Skytraq Venus 6 +# Submitted-by: Andrew Gray +# Date: 12 June 2010 +# Location: Delft, NL, 52.01N 4.36E +# +# The sample was taken with the unit stationary on windowsill. +# The log starts before the unit was powered on. The log ends +# when I walked it about 3 meters from the bluetooth hub is was paired +# with. +$GPGGA,170909.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*53 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170909.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*78 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170910.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5B +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170910.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*70 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170911.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5A +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170911.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*71 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170912.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*59 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170912.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*72 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170913.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*58 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170913.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*73 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170914.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170914.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170915.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170915.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170916.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5D +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170916.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*76 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170917.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5C +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170917.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*77 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170918.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*53 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170918.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*78 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170919.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*52 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170919.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*79 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170920.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*58 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170920.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*73 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170921.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*59 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170921.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*72 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170922.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5A +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170922.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*71 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170923.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5B +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170923.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*70 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170924.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5C +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170924.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*77 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170925.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5D +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170925.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*76 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170926.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170926.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170927.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170927.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170928.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*50 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170928.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7B +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170929.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*51 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170929.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7A +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170930.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*59 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170930.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*72 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170931.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*58 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170931.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*73 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170932.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5B +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170932.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*70 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170933.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5A +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170933.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*71 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170934.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5D +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170934.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*76 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170935.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5C +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170935.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*77 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170936.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170936.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170937.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170937.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170938.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*51 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170938.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7A +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170939.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*50 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +$GPRMC,170939.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7B +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170940.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170940.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170941.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170941.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170942.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5C +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170942.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*77 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170943.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5D +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170943.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*76 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170944.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5A +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170944.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*71 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170945.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5B +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170945.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*70 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170946.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*58 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170946.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*73 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170947.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*59 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170947.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*72 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170948.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*56 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170948.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7D +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170949.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*57 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,28,136,*73 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170949.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7C +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170950.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,40,14,44,268,,09,28,136,*77 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170950.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170951.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,74,066,,30,67,271,40,14,44,268,,09,28,136,*77 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170951.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170952.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*58 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,73,067,,30,67,271,40,14,44,268,,09,28,136,*71 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170952.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*73 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170953.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*59 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,268,,09,28,136,*7F +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170953.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*72 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170954.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,73,067,32,30,67,271,38,14,44,267,,09,28,136,*70 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170954.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170955.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,,09,28,136,*70 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170955.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170956.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5C +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,,09,28,136,*70 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170956.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*77 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170957.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5D +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,,09,28,136,*70 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170957.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*76 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170958.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*52 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,,09,28,136,*70 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170958.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*79 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170959.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*53 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,73,067,,30,67,271,38,14,44,267,,09,28,136,*71 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,170959.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*78 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,171000.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*57 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,34,09,28,136,*77 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,171000.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7C +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,171001.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*56 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,34,09,28,136,*77 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +$GPRMC,171001.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7D +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,171002.972,5200.8519,N,00421.7812,E,1,08,1.0,8.8,M,44.8,M,,0000*5D +$GPGSA,A,3,14,30,09,29,02,27,04,31,,,,,2.3,1.0,2.0*35 +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,33,09,28,136,26*74 +$GPGSV,3,2,11,29,27,200,25,02,25,101,28,27,23,137,28,04,21,055,38*7B +$GPGSV,3,3,11,31,18,305,31,32,06,331,,20,02,354,*42 +$GPRMC,171002.972,A,5200.8519,N,00421.7812,E,000.0,000.0,120610,,,A*6A +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171003.972,5200.8519,N,00421.7819,E,1,08,1.0,8.8,M,44.8,M,,0000*57 +$GPGSA,A,3,14,30,09,29,02,27,04,31,,,,,2.3,1.0,2.0*35 +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,34,09,28,136,27*72 +$GPGSV,3,2,11,29,27,200,27,02,25,101,28,27,23,137,26,04,21,055,38*77 +$GPGSV,3,3,11,31,18,305,30,32,06,331,,20,02,354,*43 +$GPRMC,171003.972,A,5200.8519,N,00421.7819,E,000.9,022.1,120610,,,A*68 +$GPVTG,022.1,T,,M,000.9,N,001.8,K,A*0C +$GPGGA,171004.972,5200.8519,N,00421.7830,E,1,09,0.9,8.8,M,44.8,M,,0000*52 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,32,30,67,271,39,14,44,267,34,09,28,136,26*72 +$GPGSV,3,2,11,29,27,200,26,02,25,101,27,27,23,137,27,04,21,055,38*78 +$GPGSV,3,3,11,31,18,305,31,32,06,331,,20,02,354,*42 +$GPRMC,171004.972,A,5200.8519,N,00421.7830,E,000.0,000.0,120610,,,A*6C +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171005.972,5200.8520,N,00421.7842,E,1,09,0.9,8.3,M,44.8,M,,0000*57 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,32,30,67,271,39,14,44,267,34,09,28,136,26*72 +$GPGSV,3,2,11,29,27,200,27,02,25,101,28,27,23,137,27,04,21,055,38*76 +$GPGSV,3,3,11,31,18,305,30,32,06,331,,20,02,354,*43 +$GPRMC,171005.972,A,5200.8520,N,00421.7842,E,000.0,000.0,120610,,,A*62 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171006.972,5200.8513,N,00421.7856,E,1,09,0.9,7.6,M,44.8,M,,0000*5B +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,33,30,67,271,38,14,44,267,33,09,28,136,26*75 +$GPGSV,3,2,11,29,27,200,26,02,25,101,27,27,23,137,28,04,21,055,37*78 +$GPGSV,3,3,11,31,18,305,30,32,06,331,,20,02,354,*43 +$GPRMC,171006.972,A,5200.8513,N,00421.7856,E,000.0,000.0,120610,,,A*64 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171007.972,5200.8514,N,00421.7851,E,1,09,0.9,7.7,M,44.8,M,,0000*5B +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,33,30,67,271,38,14,44,267,33,09,28,136,26*75 +$GPGSV,3,2,11,29,27,200,26,02,25,101,27,27,23,137,28,04,21,055,37*78 +$GPGSV,3,3,11,31,18,305,30,32,06,331,,20,02,354,*43 +$GPRMC,171007.972,A,5200.8514,N,00421.7851,E,000.0,000.0,120610,,,A*65 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171008.972,5200.8516,N,00421.7844,E,1,09,0.9,6.4,M,44.8,M,,0000*50 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,33,30,67,271,38,14,44,267,33,09,28,136,26*75 +$GPGSV,3,2,11,29,27,200,26,02,25,101,28,27,23,137,28,04,21,055,38*78 +$GPGSV,3,3,11,31,18,305,29,32,06,331,,20,02,354,*4B +$GPRMC,171008.972,A,5200.8516,N,00421.7844,E,000.0,000.0,120610,,,A*6C +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171009.972,5200.8518,N,00421.7840,E,1,09,0.9,5.4,M,44.8,M,,0000*58 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,33,30,67,271,38,14,44,267,33,09,28,136,27*74 +$GPGSV,3,2,11,29,28,200,26,02,25,101,28,27,23,137,28,04,21,055,37*78 +$GPGSV,3,3,11,31,18,305,29,32,06,331,,20,02,354,*4B +$GPRMC,171009.972,A,5200.8518,N,00421.7840,E,000.0,000.0,120610,,,A*67 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171010.972,5200.8515,N,00421.7842,E,1,09,0.9,4.1,M,44.8,M,,0000*5B +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,32,30,67,271,39,14,44,267,33,09,28,136,27*74 +$GPGSV,3,2,11,29,28,200,26,02,25,101,28,27,23,137,27,04,21,055,38*78 +$GPGSV,3,3,11,31,18,305,30,32,06,331,,20,02,354,*43 +$GPRMC,171010.972,A,5200.8515,N,00421.7842,E,000.0,000.0,120610,,,A*60 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171011.972,5200.8513,N,00421.7841,E,1,09,0.9,4.7,M,44.8,M,,0000*59 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,31,30,67,271,39,14,44,267,34,09,28,136,28*7F +$GPGSV,3,2,11,29,28,200,27,02,25,101,29,27,23,137,26,04,21,055,39*78 +$GPGSV,3,3,11,31,18,305,31,32,06,331,,20,02,354,*42 +$GPRMC,171011.972,A,5200.8513,N,00421.7841,E,000.0,000.0,120610,,,A*64 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171012.972,5200.8515,N,00421.7846,E,1,09,0.9,4.3,M,44.8,M,,0000*5F +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,27,30,67,271,40,14,44,267,35,09,28,136,29*76 +$GPGSV,3,2,11,29,28,200,28,02,25,101,31,27,23,137,25,04,21,055,39*7D +$GPGSV,3,3,11,31,18,305,32,32,06,331,,20,02,354,*41 +$GPRMC,171012.972,A,5200.8515,N,00421.7846,E,000.0,000.0,120610,,,A*66 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171013.972,5200.8513,N,00421.7842,E,1,09,0.9,3.8,M,44.8,M,,0000*50 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,29,30,67,271,40,14,44,267,35,09,28,136,28*79 +$GPGSV,3,2,11,29,28,200,27,02,25,101,29,27,23,137,25,04,21,055,39*7B +$GPGSV,3,3,11,31,18,305,32,32,06,331,,20,02,354,*41 +$GPRMC,171013.972,A,5200.8513,N,00421.7842,E,000.0,000.0,120610,,,A*65 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171014.972,5200.8514,N,00421.7845,E,1,09,0.9,3.6,M,44.8,M,,0000*59 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,28,30,67,271,40,14,44,267,34,09,28,136,28*79 +$GPGSV,3,2,11,29,28,200,29,02,25,101,26,27,23,137,25,04,21,055,39*7A +$GPGSV,3,3,11,31,18,305,31,32,06,331,,20,02,354,*42 +$GPRMC,171014.972,A,5200.8514,N,00421.7845,E,000.0,000.0,120610,,,A*62 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171015.972,5200.8510,N,00421.7850,E,1,09,0.9,4.0,M,44.8,M,,0000*59 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,35,30,67,271,28,14,44,267,24,09,28,136,25*77 +$GPGSV,3,2,11,29,28,200,24,02,25,101,25,27,23,137,26,04,21,055,30*7E +$GPGSV,3,3,11,31,18,305,32,32,06,331,,20,02,354,*41 +$GPRMC,171015.972,A,5200.8510,N,00421.7850,E,000.0,000.0,120610,,,A*63 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171016.972,5200.8492,N,00421.7842,E,1,09,0.9,3.5,M,44.8,M,,0000*50 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,33,30,67,271,26,14,44,267,28,09,28,136,24*72 +$GPGSV,3,2,11,29,28,200,29,02,25,101,24,27,23,137,27,04,21,055,25*77 +$GPGSV,3,3,11,31,18,305,25,32,06,331,,20,02,354,*47 +$GPRMC,171016.972,A,5200.8492,N,00421.7842,E,000.0,000.0,120610,,,A*68 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171017.972,5200.8498,N,00421.7845,E,1,09,0.9,4.8,M,44.8,M,,0000*56 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,36,30,67,271,27,14,44,267,25,09,28,136,25*7A +$GPGSV,3,2,11,29,28,200,25,02,25,101,26,27,23,137,28,04,21,055,24*77 +$GPGSV,3,3,11,31,18,305,25,32,06,331,,20,02,354,*47 +$GPRMC,171017.972,A,5200.8498,N,00421.7845,E,001.0,000.6,120610,,,A*63 +$GPVTG,000.6,T,,M,001.0,N,001.8,K,A*03 +$GPGGA,171018.972,5200.8501,N,00421.7847,E,1,08,1.1,4.7,M,44.8,M,,0000*5D +$GPGSA,A,3,14,30,12,09,29,02,27,31,,,,,1.9,1.1,1.6*3F +$GPGSV,3,1,11,12,73,067,33,30,67,271,25,14,44,267,25,09,28,136,25*7D +$GPGSV,3,2,11,29,28,200,26,02,25,101,26,27,23,137,26,04,21,055,22*7C +$GPGSV,3,3,11,31,18,305,24,32,06,331,,20,02,354,*46 +$GPRMC,171018.972,A,5200.8501,N,00421.7847,E,000.0,000.6,120610,,,A*6E +$GPVTG,000.6,T,,M,000.0,N,000.0,K,A*0B +$GPGGA,171019.972,5200.8503,N,00421.7844,E,1,09,0.9,4.6,M,44.8,M,,0000*54 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,34,30,67,271,25,14,44,267,24,09,28,136,24*7A +$GPGSV,3,2,11,29,28,200,25,02,25,101,25,27,23,137,29,04,21,055,22*73 +$GPGSV,3,3,11,31,18,305,24,32,06,331,,20,02,354,*46 +$GPRMC,171019.972,A,5200.8503,N,00421.7844,E,000.9,290.7,120610,,,A*6D +$GPVTG,290.7,T,,M,000.9,N,001.6,K,A*0F +$GPGGA,171020.972,5200.8499,N,00421.7837,E,1,09,0.9,4.9,M,44.8,M,,0000*57 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,31,30,67,271,26,14,44,267,23,09,28,136,23*7C +$GPGSV,3,2,11,29,28,200,32,02,25,101,28,27,23,137,27,04,21,055,22*76 +$GPGSV,3,3,11,31,18,305,23,32,06,331,,20,02,354,*41 +$GPRMC,171020.972,A,5200.8499,N,00421.7837,E,000.0,290.7,120610,,,A*68 +$GPVTG,290.7,T,,M,000.0,N,000.0,K,A*01 +$GPGGA,171021.972,5200.8502,N,00421.7865,E,1,09,0.9,5.5,M,44.8,M,,0000*5F +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,31,30,67,271,24,14,44,267,23,09,28,136,24*79 +$GPGSV,3,2,11,29,28,200,26,02,25,101,26,27,23,137,25,04,21,055,23*7E +$GPVTG,290.7,T,,M,000.0,N,000.0,K,A*01 +$GPGGA,171022.972,5200.8502,N,00421.7872,E,1,09,0.9,6.6,M,44.8,M,,0000*5A +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,2,11,29,28,200,27,02,25,101,25,27,23,137,24,04,21,055,25*7B +$GPGSV,3,3,11,31,18,305,23,32,06,331,,20,02,354,*41 +$GPRMC,171023.972,A,5200.8507,N,00421.7871,E,000.9,008.0,120610,,,A*62 +$GPVTG,008.0,T,,M,000.9,N,001.7,K,A*0A +$GPGGA,171024.972,5200.8518,N,00421.7884,E,1,08,1.0,4.8,M,44.8,M,,0000*5B +$GPGSA,A,3,14,30,12,09,29,02,04,31,,,,,1.8,1.0,1.5*3D +$GPGSV,3,1,11,12,73,067,25,30,67,271,25,14,44,267,22,09,28,136,27*7F +$GPGSV,3,2,11,29,28,200,25,02,25,101,24,27,23,137,23,04,21,055,30*7B +$GPGSV,3,3,11,31,18,305,27,32,06,331,,20,02,354,*45 +$GPRMC,171024.972,A,5200.8518,N,00421.7884,E,000.0,008.0,120610,,,A*68 +$GPVTG,008.0,T,,M,000.0,N,000.0,K,A*05 +$GPGSA,A,3,14,30,12,09,29,02,04,31,,,,,1.8,1.0,1.5*3D +$GPGSV,3,1,11,12,73,067,34,30,67,271,33,14,44,267,23,09,28,136,28*76 diff --git a/test/daemon/bn-9015.log.chk b/test/daemon/bn-9015.log.chk new file mode 100644 index 0000000..6761522 --- /dev/null +++ b/test/daemon/bn-9015.log.chk @@ -0,0 +1,676 @@ +$GPGGA,170909.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*53 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170909.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*78 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170910.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5B +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170910.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*70 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170911.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5A +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170911.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*71 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170912.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*59 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170912.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*72 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170913.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*58 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170913.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*73 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170914.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170914.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170915.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170915.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170916.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5D +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170916.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*76 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170917.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5C +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170917.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*77 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170918.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*53 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170918.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*78 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170919.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*52 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170919.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*79 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170920.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*58 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170920.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*73 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170921.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*59 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170921.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*72 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170922.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5A +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170922.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*71 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170923.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5B +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170923.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*70 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170924.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5C +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170924.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*77 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170925.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5D +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170925.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*76 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170926.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170926.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170927.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170927.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170928.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*50 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170928.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7B +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170929.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*51 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170929.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7A +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170930.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*59 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170930.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*72 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170931.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*58 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170931.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*73 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170932.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5B +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170932.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*70 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170933.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5A +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170933.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*71 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170934.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5D +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,136,,04,21,055,*76 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":136,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170934.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*76 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170935.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5C +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170935.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*77 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170936.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170936.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170937.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170937.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170938.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*51 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170938.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7A +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170939.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*50 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,332,,20,02,354,*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":332,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170939.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7B +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170940.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170940.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170941.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170941.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170942.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5C +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170942.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*77 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170943.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5D +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170943.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*76 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170944.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5A +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170944.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*71 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170945.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5B +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170945.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*70 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170946.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*58 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170946.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*73 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170947.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*59 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170947.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*72 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170948.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*56 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,29,136,*72 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":29,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170948.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7D +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170949.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*57 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,,14,44,268,,09,28,136,*73 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":0,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170949.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7C +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170950.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,40,14,44,268,,09,28,136,*77 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":40,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170950.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170951.999,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,74,066,,30,67,271,40,14,44,268,,09,28,136,*77 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":74,"az":66,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":40,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170951.999,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170952.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*58 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,73,067,,30,67,271,40,14,44,268,,09,28,136,*71 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":40,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170952.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*73 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170953.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*59 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,268,,09,28,136,*7F +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":39,"used":false},{"PRN":14,"el":44,"az":268,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170953.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*72 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170954.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5E +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,73,067,32,30,67,271,38,14,44,267,,09,28,136,*70 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":73,"az":67,"ss":32,"used":false},{"PRN":30,"el":67,"az":271,"ss":38,"used":false},{"PRN":14,"el":44,"az":267,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170954.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*75 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170955.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5F +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,,09,28,136,*70 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":39,"used":false},{"PRN":14,"el":44,"az":267,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170955.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*74 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170956.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5C +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,,09,28,136,*70 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":39,"used":false},{"PRN":14,"el":44,"az":267,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170956.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*77 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170957.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*5D +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,,09,28,136,*70 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":39,"used":false},{"PRN":14,"el":44,"az":267,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170957.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*76 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170958.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*52 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,,09,28,136,*70 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":39,"used":false},{"PRN":14,"el":44,"az":267,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170958.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*79 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,170959.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*53 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,73,067,,30,67,271,38,14,44,267,,09,28,136,*71 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":38,"used":false},{"PRN":14,"el":44,"az":267,"ss":0,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,170959.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*78 +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,171000.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*57 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,34,09,28,136,*77 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":39,"used":false},{"PRN":14,"el":44,"az":267,"ss":34,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171000.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7C +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,171001.972,5200.8499,N,00421.7860,E,0,00,0.0,48.8,M,0.0,M,,0000*56 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,34,09,28,136,*77 +$GPGSV,3,2,11,29,27,200,,02,25,101,,27,23,137,,04,21,055,*77 +$GPGSV,3,3,11,31,18,305,,32,06,331,,20,02,354,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":39,"used":false},{"PRN":14,"el":44,"az":267,"ss":34,"used":false},{"PRN":9,"el":28,"az":136,"ss":0,"used":false},{"PRN":29,"el":27,"az":200,"ss":0,"used":false},{"PRN":2,"el":25,"az":101,"ss":0,"used":false},{"PRN":27,"el":23,"az":137,"ss":0,"used":false},{"PRN":4,"el":21,"az":55,"ss":0,"used":false},{"PRN":31,"el":18,"az":305,"ss":0,"used":false},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171001.972,V,5200.8499,N,00421.7860,E,000.0,000.0,120610,,,N*7D +$GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02 +$GPGGA,171002.972,5200.8519,N,00421.7812,E,1,08,1.0,8.8,M,44.8,M,,0000*5D +{"class":"TPV","tag":"GGA","lat":52.014198333,"lon":4.363020000,"alt":8.800,"mode":3} +$GPGSA,A,3,14,30,09,29,02,27,04,31,,,,,2.3,1.0,2.0*35 +{"class":"TPV","tag":"GSA","lat":52.014198333,"lon":4.363020000,"alt":8.800,"epv":46.000,"mode":3} +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,33,09,28,136,26*74 +$GPGSV,3,2,11,29,27,200,25,02,25,101,28,27,23,137,28,04,21,055,38*7B +$GPGSV,3,3,11,31,18,305,31,32,06,331,,20,02,354,*42 +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":0.90,"vdop":2.10,"tdop":1.48,"hdop":1.20,"gdop":2.84,"pdop":2.42,"satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":39,"used":true},{"PRN":14,"el":44,"az":267,"ss":33,"used":true},{"PRN":9,"el":28,"az":136,"ss":26,"used":true},{"PRN":29,"el":27,"az":200,"ss":25,"used":true},{"PRN":2,"el":25,"az":101,"ss":28,"used":true},{"PRN":27,"el":23,"az":137,"ss":28,"used":true},{"PRN":4,"el":21,"az":55,"ss":38,"used":true},{"PRN":31,"el":18,"az":305,"ss":31,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171002.972,A,5200.8519,N,00421.7812,E,000.0,000.0,120610,,,A*6A +{"class":"TPV","tag":"RMC","time":1276362602.972,"ept":0.005,"lat":52.014198333,"lon":4.363020000,"alt":8.800,"epx":11.845,"epy":13.531,"epv":46.000,"track":0.0000,"speed":0.000,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171003.972,5200.8519,N,00421.7819,E,1,08,1.0,8.8,M,44.8,M,,0000*57 +$GPGSA,A,3,14,30,09,29,02,27,04,31,,,,,2.3,1.0,2.0*35 +$GPGSV,3,1,11,12,73,067,,30,67,271,39,14,44,267,34,09,28,136,27*72 +$GPGSV,3,2,11,29,27,200,27,02,25,101,28,27,23,137,26,04,21,055,38*77 +$GPGSV,3,3,11,31,18,305,30,32,06,331,,20,02,354,*43 +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":0.90,"vdop":2.10,"tdop":1.48,"hdop":1.20,"gdop":2.84,"pdop":2.42,"satellites":[{"PRN":12,"el":73,"az":67,"ss":0,"used":false},{"PRN":30,"el":67,"az":271,"ss":39,"used":true},{"PRN":14,"el":44,"az":267,"ss":34,"used":true},{"PRN":9,"el":28,"az":136,"ss":27,"used":true},{"PRN":29,"el":27,"az":200,"ss":27,"used":true},{"PRN":2,"el":25,"az":101,"ss":28,"used":true},{"PRN":27,"el":23,"az":137,"ss":26,"used":true},{"PRN":4,"el":21,"az":55,"ss":38,"used":true},{"PRN":31,"el":18,"az":305,"ss":30,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171003.972,A,5200.8519,N,00421.7819,E,000.9,022.1,120610,,,A*68 +{"class":"TPV","tag":"RMC","time":1276362603.972,"ept":0.005,"lat":52.014198333,"lon":4.363031667,"alt":8.800,"epx":11.845,"epy":13.531,"epv":48.373,"track":22.1000,"speed":0.463,"climb":0.000,"eps":27.06,"mode":3} +$GPVTG,022.1,T,,M,000.9,N,001.8,K,A*0C +$GPGGA,171004.972,5200.8519,N,00421.7830,E,1,09,0.9,8.8,M,44.8,M,,0000*52 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,32,30,67,271,39,14,44,267,34,09,28,136,26*72 +$GPGSV,3,2,11,29,27,200,26,02,25,101,27,27,23,137,27,04,21,055,38*78 +$GPGSV,3,3,11,31,18,305,31,32,06,331,,20,02,354,*42 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.50,"tdop":0.92,"hdop":0.91,"gdop":1.98,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":32,"used":true},{"PRN":30,"el":67,"az":271,"ss":39,"used":true},{"PRN":14,"el":44,"az":267,"ss":34,"used":true},{"PRN":9,"el":28,"az":136,"ss":26,"used":true},{"PRN":29,"el":27,"az":200,"ss":26,"used":true},{"PRN":2,"el":25,"az":101,"ss":27,"used":true},{"PRN":27,"el":23,"az":137,"ss":27,"used":true},{"PRN":4,"el":21,"az":55,"ss":38,"used":true},{"PRN":31,"el":18,"az":305,"ss":31,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171004.972,A,5200.8519,N,00421.7830,E,000.0,000.0,120610,,,A*6C +{"class":"TPV","tag":"RMC","time":1276362604.972,"ept":0.005,"lat":52.014198333,"lon":4.363050000,"alt":8.800,"epx":11.845,"epy":13.531,"epv":48.373,"track":0.0000,"speed":0.000,"climb":0.000,"eps":27.06,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171005.972,5200.8520,N,00421.7842,E,1,09,0.9,8.3,M,44.8,M,,0000*57 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,32,30,67,271,39,14,44,267,34,09,28,136,26*72 +$GPGSV,3,2,11,29,27,200,27,02,25,101,28,27,23,137,27,04,21,055,38*76 +$GPGSV,3,3,11,31,18,305,30,32,06,331,,20,02,354,*43 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.50,"tdop":0.92,"hdop":0.91,"gdop":1.98,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":32,"used":true},{"PRN":30,"el":67,"az":271,"ss":39,"used":true},{"PRN":14,"el":44,"az":267,"ss":34,"used":true},{"PRN":9,"el":28,"az":136,"ss":26,"used":true},{"PRN":29,"el":27,"az":200,"ss":27,"used":true},{"PRN":2,"el":25,"az":101,"ss":28,"used":true},{"PRN":27,"el":23,"az":137,"ss":27,"used":true},{"PRN":4,"el":21,"az":55,"ss":38,"used":true},{"PRN":31,"el":18,"az":305,"ss":30,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171005.972,A,5200.8520,N,00421.7842,E,000.0,000.0,120610,,,A*62 +{"class":"TPV","tag":"RMC","time":1276362605.972,"ept":0.005,"lat":52.014200000,"lon":4.363070000,"alt":8.300,"epx":8.483,"epy":10.737,"epv":34.557,"track":0.0000,"speed":0.000,"climb":-0.500,"eps":24.27,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171006.972,5200.8513,N,00421.7856,E,1,09,0.9,7.6,M,44.8,M,,0000*5B +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,33,30,67,271,38,14,44,267,33,09,28,136,26*75 +$GPGSV,3,2,11,29,27,200,26,02,25,101,27,27,23,137,28,04,21,055,37*78 +$GPGSV,3,3,11,31,18,305,30,32,06,331,,20,02,354,*43 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.50,"tdop":0.92,"hdop":0.91,"gdop":1.98,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":33,"used":true},{"PRN":30,"el":67,"az":271,"ss":38,"used":true},{"PRN":14,"el":44,"az":267,"ss":33,"used":true},{"PRN":9,"el":28,"az":136,"ss":26,"used":true},{"PRN":29,"el":27,"az":200,"ss":26,"used":true},{"PRN":2,"el":25,"az":101,"ss":27,"used":true},{"PRN":27,"el":23,"az":137,"ss":28,"used":true},{"PRN":4,"el":21,"az":55,"ss":37,"used":true},{"PRN":31,"el":18,"az":305,"ss":30,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171006.972,A,5200.8513,N,00421.7856,E,000.0,000.0,120610,,,A*64 +{"class":"TPV","tag":"RMC","time":1276362606.972,"ept":0.005,"lat":52.014188333,"lon":4.363093333,"alt":7.600,"epx":8.483,"epy":10.737,"epv":34.557,"track":0.0000,"speed":0.000,"climb":-0.700,"eps":21.47,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171007.972,5200.8514,N,00421.7851,E,1,09,0.9,7.7,M,44.8,M,,0000*5B +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,33,30,67,271,38,14,44,267,33,09,28,136,26*75 +$GPGSV,3,2,11,29,27,200,26,02,25,101,27,27,23,137,28,04,21,055,37*78 +$GPGSV,3,3,11,31,18,305,30,32,06,331,,20,02,354,*43 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.50,"tdop":0.92,"hdop":0.91,"gdop":1.98,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":33,"used":true},{"PRN":30,"el":67,"az":271,"ss":38,"used":true},{"PRN":14,"el":44,"az":267,"ss":33,"used":true},{"PRN":9,"el":28,"az":136,"ss":26,"used":true},{"PRN":29,"el":27,"az":200,"ss":26,"used":true},{"PRN":2,"el":25,"az":101,"ss":27,"used":true},{"PRN":27,"el":23,"az":137,"ss":28,"used":true},{"PRN":4,"el":21,"az":55,"ss":37,"used":true},{"PRN":31,"el":18,"az":305,"ss":30,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171007.972,A,5200.8514,N,00421.7851,E,000.0,000.0,120610,,,A*65 +{"class":"TPV","tag":"RMC","time":1276362607.972,"ept":0.005,"lat":52.014190000,"lon":4.363085000,"alt":7.700,"epx":8.483,"epy":10.737,"epv":34.557,"track":0.0000,"speed":0.000,"climb":0.100,"eps":21.47,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171008.972,5200.8516,N,00421.7844,E,1,09,0.9,6.4,M,44.8,M,,0000*50 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,33,30,67,271,38,14,44,267,33,09,28,136,26*75 +$GPGSV,3,2,11,29,27,200,26,02,25,101,28,27,23,137,28,04,21,055,38*78 +$GPGSV,3,3,11,31,18,305,29,32,06,331,,20,02,354,*4B +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.50,"tdop":0.92,"hdop":0.91,"gdop":1.98,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":33,"used":true},{"PRN":30,"el":67,"az":271,"ss":38,"used":true},{"PRN":14,"el":44,"az":267,"ss":33,"used":true},{"PRN":9,"el":28,"az":136,"ss":26,"used":true},{"PRN":29,"el":27,"az":200,"ss":26,"used":true},{"PRN":2,"el":25,"az":101,"ss":28,"used":true},{"PRN":27,"el":23,"az":137,"ss":28,"used":true},{"PRN":4,"el":21,"az":55,"ss":38,"used":true},{"PRN":31,"el":18,"az":305,"ss":29,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171008.972,A,5200.8516,N,00421.7844,E,000.0,000.0,120610,,,A*6C +{"class":"TPV","tag":"RMC","time":1276362608.972,"ept":0.005,"lat":52.014193333,"lon":4.363073333,"alt":6.400,"epx":8.483,"epy":10.737,"epv":34.557,"track":0.0000,"speed":0.000,"climb":-1.300,"eps":21.47,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171009.972,5200.8518,N,00421.7840,E,1,09,0.9,5.4,M,44.8,M,,0000*58 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,33,30,67,271,38,14,44,267,33,09,28,136,27*74 +$GPGSV,3,2,11,29,28,200,26,02,25,101,28,27,23,137,28,04,21,055,37*78 +$GPGSV,3,3,11,31,18,305,29,32,06,331,,20,02,354,*4B +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":33,"used":true},{"PRN":30,"el":67,"az":271,"ss":38,"used":true},{"PRN":14,"el":44,"az":267,"ss":33,"used":true},{"PRN":9,"el":28,"az":136,"ss":27,"used":true},{"PRN":29,"el":28,"az":200,"ss":26,"used":true},{"PRN":2,"el":25,"az":101,"ss":28,"used":true},{"PRN":27,"el":23,"az":137,"ss":28,"used":true},{"PRN":4,"el":21,"az":55,"ss":37,"used":true},{"PRN":31,"el":18,"az":305,"ss":29,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171009.972,A,5200.8518,N,00421.7840,E,000.0,000.0,120610,,,A*67 +{"class":"TPV","tag":"RMC","time":1276362609.972,"ept":0.005,"lat":52.014196667,"lon":4.363066667,"alt":5.400,"epx":8.483,"epy":10.737,"epv":34.557,"track":0.0000,"speed":0.000,"climb":-1.000,"eps":21.47,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171010.972,5200.8515,N,00421.7842,E,1,09,0.9,4.1,M,44.8,M,,0000*5B +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,32,30,67,271,39,14,44,267,33,09,28,136,27*74 +$GPGSV,3,2,11,29,28,200,26,02,25,101,28,27,23,137,27,04,21,055,38*78 +$GPGSV,3,3,11,31,18,305,30,32,06,331,,20,02,354,*43 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":32,"used":true},{"PRN":30,"el":67,"az":271,"ss":39,"used":true},{"PRN":14,"el":44,"az":267,"ss":33,"used":true},{"PRN":9,"el":28,"az":136,"ss":27,"used":true},{"PRN":29,"el":28,"az":200,"ss":26,"used":true},{"PRN":2,"el":25,"az":101,"ss":28,"used":true},{"PRN":27,"el":23,"az":137,"ss":27,"used":true},{"PRN":4,"el":21,"az":55,"ss":38,"used":true},{"PRN":31,"el":18,"az":305,"ss":30,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171010.972,A,5200.8515,N,00421.7842,E,000.0,000.0,120610,,,A*60 +{"class":"TPV","tag":"RMC","time":1276362610.972,"ept":0.005,"lat":52.014191667,"lon":4.363070000,"alt":4.100,"epx":8.510,"epy":10.769,"epv":34.713,"track":0.0000,"speed":0.000,"climb":-1.300,"eps":21.51,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171011.972,5200.8513,N,00421.7841,E,1,09,0.9,4.7,M,44.8,M,,0000*59 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,31,30,67,271,39,14,44,267,34,09,28,136,28*7F +$GPGSV,3,2,11,29,28,200,27,02,25,101,29,27,23,137,26,04,21,055,39*78 +$GPGSV,3,3,11,31,18,305,31,32,06,331,,20,02,354,*42 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":31,"used":true},{"PRN":30,"el":67,"az":271,"ss":39,"used":true},{"PRN":14,"el":44,"az":267,"ss":34,"used":true},{"PRN":9,"el":28,"az":136,"ss":28,"used":true},{"PRN":29,"el":28,"az":200,"ss":27,"used":true},{"PRN":2,"el":25,"az":101,"ss":29,"used":true},{"PRN":27,"el":23,"az":137,"ss":26,"used":true},{"PRN":4,"el":21,"az":55,"ss":39,"used":true},{"PRN":31,"el":18,"az":305,"ss":31,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171011.972,A,5200.8513,N,00421.7841,E,000.0,000.0,120610,,,A*64 +{"class":"TPV","tag":"RMC","time":1276362611.972,"ept":0.005,"lat":52.014188333,"lon":4.363068333,"alt":4.700,"epx":8.510,"epy":10.769,"epv":34.713,"track":0.0000,"speed":0.000,"climb":0.600,"eps":21.54,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171012.972,5200.8515,N,00421.7846,E,1,09,0.9,4.3,M,44.8,M,,0000*5F +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,27,30,67,271,40,14,44,267,35,09,28,136,29*76 +$GPGSV,3,2,11,29,28,200,28,02,25,101,31,27,23,137,25,04,21,055,39*7D +$GPGSV,3,3,11,31,18,305,32,32,06,331,,20,02,354,*41 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":27,"used":true},{"PRN":30,"el":67,"az":271,"ss":40,"used":true},{"PRN":14,"el":44,"az":267,"ss":35,"used":true},{"PRN":9,"el":28,"az":136,"ss":29,"used":true},{"PRN":29,"el":28,"az":200,"ss":28,"used":true},{"PRN":2,"el":25,"az":101,"ss":31,"used":true},{"PRN":27,"el":23,"az":137,"ss":25,"used":true},{"PRN":4,"el":21,"az":55,"ss":39,"used":true},{"PRN":31,"el":18,"az":305,"ss":32,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171012.972,A,5200.8515,N,00421.7846,E,000.0,000.0,120610,,,A*66 +{"class":"TPV","tag":"RMC","time":1276362612.972,"ept":0.005,"lat":52.014191667,"lon":4.363076667,"alt":4.300,"epx":8.510,"epy":10.769,"epv":34.713,"track":0.0000,"speed":0.000,"climb":-0.400,"eps":21.54,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171013.972,5200.8513,N,00421.7842,E,1,09,0.9,3.8,M,44.8,M,,0000*50 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,29,30,67,271,40,14,44,267,35,09,28,136,28*79 +$GPGSV,3,2,11,29,28,200,27,02,25,101,29,27,23,137,25,04,21,055,39*7B +$GPGSV,3,3,11,31,18,305,32,32,06,331,,20,02,354,*41 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":29,"used":true},{"PRN":30,"el":67,"az":271,"ss":40,"used":true},{"PRN":14,"el":44,"az":267,"ss":35,"used":true},{"PRN":9,"el":28,"az":136,"ss":28,"used":true},{"PRN":29,"el":28,"az":200,"ss":27,"used":true},{"PRN":2,"el":25,"az":101,"ss":29,"used":true},{"PRN":27,"el":23,"az":137,"ss":25,"used":true},{"PRN":4,"el":21,"az":55,"ss":39,"used":true},{"PRN":31,"el":18,"az":305,"ss":32,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171013.972,A,5200.8513,N,00421.7842,E,000.0,000.0,120610,,,A*65 +{"class":"TPV","tag":"RMC","time":1276362613.972,"ept":0.005,"lat":52.014188333,"lon":4.363070000,"alt":3.800,"epx":8.510,"epy":10.769,"epv":34.713,"track":0.0000,"speed":0.000,"climb":-0.500,"eps":21.54,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171014.972,5200.8514,N,00421.7845,E,1,09,0.9,3.6,M,44.8,M,,0000*59 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,28,30,67,271,40,14,44,267,34,09,28,136,28*79 +$GPGSV,3,2,11,29,28,200,29,02,25,101,26,27,23,137,25,04,21,055,39*7A +$GPGSV,3,3,11,31,18,305,31,32,06,331,,20,02,354,*42 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":28,"used":true},{"PRN":30,"el":67,"az":271,"ss":40,"used":true},{"PRN":14,"el":44,"az":267,"ss":34,"used":true},{"PRN":9,"el":28,"az":136,"ss":28,"used":true},{"PRN":29,"el":28,"az":200,"ss":29,"used":true},{"PRN":2,"el":25,"az":101,"ss":26,"used":true},{"PRN":27,"el":23,"az":137,"ss":25,"used":true},{"PRN":4,"el":21,"az":55,"ss":39,"used":true},{"PRN":31,"el":18,"az":305,"ss":31,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171014.972,A,5200.8514,N,00421.7845,E,000.0,000.0,120610,,,A*62 +{"class":"TPV","tag":"RMC","time":1276362614.972,"ept":0.005,"lat":52.014190000,"lon":4.363075000,"alt":3.600,"epx":8.510,"epy":10.769,"epv":34.713,"track":0.0000,"speed":0.000,"climb":-0.200,"eps":21.54,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171015.972,5200.8510,N,00421.7850,E,1,09,0.9,4.0,M,44.8,M,,0000*59 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,35,30,67,271,28,14,44,267,24,09,28,136,25*77 +$GPGSV,3,2,11,29,28,200,24,02,25,101,25,27,23,137,26,04,21,055,30*7E +$GPGSV,3,3,11,31,18,305,32,32,06,331,,20,02,354,*41 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":35,"used":true},{"PRN":30,"el":67,"az":271,"ss":28,"used":true},{"PRN":14,"el":44,"az":267,"ss":24,"used":true},{"PRN":9,"el":28,"az":136,"ss":25,"used":true},{"PRN":29,"el":28,"az":200,"ss":24,"used":true},{"PRN":2,"el":25,"az":101,"ss":25,"used":true},{"PRN":27,"el":23,"az":137,"ss":26,"used":true},{"PRN":4,"el":21,"az":55,"ss":30,"used":true},{"PRN":31,"el":18,"az":305,"ss":32,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171015.972,A,5200.8510,N,00421.7850,E,000.0,000.0,120610,,,A*63 +{"class":"TPV","tag":"RMC","time":1276362615.972,"ept":0.005,"lat":52.014183333,"lon":4.363083333,"alt":4.000,"epx":8.510,"epy":10.769,"epv":34.713,"track":0.0000,"speed":0.000,"climb":0.400,"eps":21.54,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171016.972,5200.8492,N,00421.7842,E,1,09,0.9,3.5,M,44.8,M,,0000*50 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,33,30,67,271,26,14,44,267,28,09,28,136,24*72 +$GPGSV,3,2,11,29,28,200,29,02,25,101,24,27,23,137,27,04,21,055,25*77 +$GPGSV,3,3,11,31,18,305,25,32,06,331,,20,02,354,*47 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":33,"used":true},{"PRN":30,"el":67,"az":271,"ss":26,"used":true},{"PRN":14,"el":44,"az":267,"ss":28,"used":true},{"PRN":9,"el":28,"az":136,"ss":24,"used":true},{"PRN":29,"el":28,"az":200,"ss":29,"used":true},{"PRN":2,"el":25,"az":101,"ss":24,"used":true},{"PRN":27,"el":23,"az":137,"ss":27,"used":true},{"PRN":4,"el":21,"az":55,"ss":25,"used":true},{"PRN":31,"el":18,"az":305,"ss":25,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171016.972,A,5200.8492,N,00421.7842,E,000.0,000.0,120610,,,A*68 +{"class":"TPV","tag":"RMC","time":1276362616.972,"ept":0.005,"lat":52.014153333,"lon":4.363070000,"alt":3.500,"epx":8.510,"epy":10.769,"epv":34.713,"track":0.0000,"speed":0.000,"climb":-0.500,"eps":21.54,"mode":3} +$GPVTG,000.0,T,,M,000.0,N,000.0,K,A*0D +$GPGGA,171017.972,5200.8498,N,00421.7845,E,1,09,0.9,4.8,M,44.8,M,,0000*56 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,36,30,67,271,27,14,44,267,25,09,28,136,25*7A +$GPGSV,3,2,11,29,28,200,25,02,25,101,26,27,23,137,28,04,21,055,24*77 +$GPGSV,3,3,11,31,18,305,25,32,06,331,,20,02,354,*47 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":36,"used":true},{"PRN":30,"el":67,"az":271,"ss":27,"used":true},{"PRN":14,"el":44,"az":267,"ss":25,"used":true},{"PRN":9,"el":28,"az":136,"ss":25,"used":true},{"PRN":29,"el":28,"az":200,"ss":25,"used":true},{"PRN":2,"el":25,"az":101,"ss":26,"used":true},{"PRN":27,"el":23,"az":137,"ss":28,"used":true},{"PRN":4,"el":21,"az":55,"ss":24,"used":true},{"PRN":31,"el":18,"az":305,"ss":25,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171017.972,A,5200.8498,N,00421.7845,E,001.0,000.6,120610,,,A*63 +{"class":"TPV","tag":"RMC","time":1276362617.972,"ept":0.005,"lat":52.014163333,"lon":4.363075000,"alt":4.800,"epx":8.510,"epy":10.769,"epv":34.713,"track":0.6000,"speed":0.514,"climb":1.300,"eps":21.54,"mode":3} +$GPVTG,000.6,T,,M,001.0,N,001.8,K,A*03 +$GPGGA,171018.972,5200.8501,N,00421.7847,E,1,08,1.1,4.7,M,44.8,M,,0000*5D +$GPGSA,A,3,14,30,12,09,29,02,27,31,,,,,1.9,1.1,1.6*3F +$GPGSV,3,1,11,12,73,067,33,30,67,271,25,14,44,267,25,09,28,136,25*7D +$GPGSV,3,2,11,29,28,200,26,02,25,101,26,27,23,137,26,04,21,055,22*7C +$GPGSV,3,3,11,31,18,305,24,32,06,331,,20,02,354,*46 +{"class":"SKY","tag":"GSV","xdop":0.80,"ydop":0.90,"vdop":2.12,"tdop":1.49,"hdop":1.20,"gdop":2.86,"pdop":2.44,"satellites":[{"PRN":12,"el":73,"az":67,"ss":33,"used":true},{"PRN":30,"el":67,"az":271,"ss":25,"used":true},{"PRN":14,"el":44,"az":267,"ss":25,"used":true},{"PRN":9,"el":28,"az":136,"ss":25,"used":true},{"PRN":29,"el":28,"az":200,"ss":26,"used":true},{"PRN":2,"el":25,"az":101,"ss":26,"used":true},{"PRN":27,"el":23,"az":137,"ss":26,"used":true},{"PRN":4,"el":21,"az":55,"ss":22,"used":false},{"PRN":31,"el":18,"az":305,"ss":24,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171018.972,A,5200.8501,N,00421.7847,E,000.0,000.6,120610,,,A*6E +{"class":"TPV","tag":"RMC","time":1276362618.972,"ept":0.005,"lat":52.014168333,"lon":4.363078333,"alt":4.700,"epx":8.510,"epy":10.769,"epv":34.713,"track":0.6000,"speed":0.000,"climb":-0.100,"eps":21.54,"mode":3} +$GPVTG,000.6,T,,M,000.0,N,000.0,K,A*0B +$GPGGA,171019.972,5200.8503,N,00421.7844,E,1,09,0.9,4.6,M,44.8,M,,0000*54 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,34,30,67,271,25,14,44,267,24,09,28,136,24*7A +$GPGSV,3,2,11,29,28,200,25,02,25,101,25,27,23,137,29,04,21,055,22*73 +$GPGSV,3,3,11,31,18,305,24,32,06,331,,20,02,354,*46 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":34,"used":true},{"PRN":30,"el":67,"az":271,"ss":25,"used":true},{"PRN":14,"el":44,"az":267,"ss":24,"used":true},{"PRN":9,"el":28,"az":136,"ss":24,"used":true},{"PRN":29,"el":28,"az":200,"ss":25,"used":true},{"PRN":2,"el":25,"az":101,"ss":25,"used":true},{"PRN":27,"el":23,"az":137,"ss":29,"used":true},{"PRN":4,"el":21,"az":55,"ss":22,"used":true},{"PRN":31,"el":18,"az":305,"ss":24,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171019.972,A,5200.8503,N,00421.7844,E,000.9,290.7,120610,,,A*6D +{"class":"TPV","tag":"RMC","time":1276362619.972,"ept":0.005,"lat":52.014171667,"lon":4.363073333,"alt":4.600,"epx":11.942,"epy":13.497,"epv":48.785,"track":290.7000,"speed":0.463,"climb":-0.100,"eps":24.27,"mode":3} +$GPVTG,290.7,T,,M,000.9,N,001.6,K,A*0F +$GPGGA,171020.972,5200.8499,N,00421.7837,E,1,09,0.9,4.9,M,44.8,M,,0000*57 +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,31,30,67,271,26,14,44,267,23,09,28,136,23*7C +$GPGSV,3,2,11,29,28,200,32,02,25,101,28,27,23,137,27,04,21,055,22*76 +$GPGSV,3,3,11,31,18,305,23,32,06,331,,20,02,354,*41 +{"class":"SKY","tag":"GSV","xdop":0.57,"ydop":0.72,"vdop":1.51,"tdop":0.92,"hdop":0.92,"gdop":1.99,"pdop":1.76,"satellites":[{"PRN":12,"el":73,"az":67,"ss":31,"used":true},{"PRN":30,"el":67,"az":271,"ss":26,"used":true},{"PRN":14,"el":44,"az":267,"ss":23,"used":true},{"PRN":9,"el":28,"az":136,"ss":23,"used":true},{"PRN":29,"el":28,"az":200,"ss":32,"used":true},{"PRN":2,"el":25,"az":101,"ss":28,"used":true},{"PRN":27,"el":23,"az":137,"ss":27,"used":true},{"PRN":4,"el":21,"az":55,"ss":22,"used":true},{"PRN":31,"el":18,"az":305,"ss":23,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171020.972,A,5200.8499,N,00421.7837,E,000.0,290.7,120610,,,A*68 +{"class":"TPV","tag":"RMC","time":1276362620.972,"ept":0.005,"lat":52.014165000,"lon":4.363061667,"alt":4.900,"epx":8.510,"epy":10.769,"epv":34.713,"track":290.7000,"speed":0.000,"climb":0.300,"eps":24.27,"mode":3} +$GPVTG,290.7,T,,M,000.0,N,000.0,K,A*01 +$GPGGA,171021.972,5200.8502,N,00421.7865,E,1,09,0.9,5.5,M,44.8,M,,0000*5F +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,1,11,12,73,067,31,30,67,271,24,14,44,267,23,09,28,136,24*79 +$GPGSV,3,2,11,29,28,200,26,02,25,101,26,27,23,137,25,04,21,055,23*7E +$GPVTG,290.7,T,,M,000.0,N,000.0,K,A*01 +$GPGGA,171022.972,5200.8502,N,00421.7872,E,1,09,0.9,6.6,M,44.8,M,,0000*5A +{"class":"TPV","tag":"GGA","time":1276362622.972,"ept":0.005,"lat":52.014170000,"lon":4.363120000,"alt":6.600,"speed":0.801,"climb":1.100,"mode":3} +$GPGSA,A,3,14,30,12,09,29,02,27,04,31,,,,1.8,0.9,1.5*30 +$GPGSV,3,2,11,29,28,200,27,02,25,101,25,27,23,137,24,04,21,055,25*7B +$GPGSV,3,3,11,31,18,305,23,32,06,331,,20,02,354,*41 +{"class":"SKY","tag":"GSV","xdop":0.75,"ydop":0.87,"vdop":1.50,"tdop":1.44,"hdop":0.90,"gdop":2.78,"pdop":1.80,"satellites":[{"PRN":12,"el":73,"az":67,"ss":31,"used":true},{"PRN":30,"el":67,"az":271,"ss":24,"used":true},{"PRN":14,"el":44,"az":267,"ss":23,"used":true},{"PRN":9,"el":28,"az":136,"ss":24,"used":true},{"PRN":29,"el":28,"az":200,"ss":26,"used":true},{"PRN":2,"el":25,"az":101,"ss":26,"used":true},{"PRN":27,"el":23,"az":137,"ss":25,"used":true},{"PRN":4,"el":21,"az":55,"ss":23,"used":true},{"PRN":29,"el":28,"az":200,"ss":27,"used":true},{"PRN":2,"el":25,"az":101,"ss":25,"used":true},{"PRN":27,"el":23,"az":137,"ss":24,"used":true},{"PRN":4,"el":21,"az":55,"ss":25,"used":true},{"PRN":31,"el":18,"az":305,"ss":23,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171023.972,A,5200.8507,N,00421.7871,E,000.9,008.0,120610,,,A*62 +{"class":"TPV","tag":"RMC","time":1276362623.972,"ept":0.005,"lat":52.014178333,"lon":4.363118333,"epx":11.316,"epy":13.032,"track":8.0000,"speed":0.463,"eps":26.06,"mode":2} +$GPVTG,008.0,T,,M,000.9,N,001.7,K,A*0A +$GPGGA,171024.972,5200.8518,N,00421.7884,E,1,08,1.0,4.8,M,44.8,M,,0000*5B +{"class":"TPV","tag":"GGA","time":1276362624.972,"ept":0.005,"lat":52.014196667,"lon":4.363140000,"alt":4.800,"epx":11.316,"epy":13.032,"epv":34.500,"speed":2.525,"eps":26.06,"mode":3} +$GPGSA,A,3,14,30,12,09,29,02,04,31,,,,,1.8,1.0,1.5*3D +$GPGSV,3,1,11,12,73,067,25,30,67,271,25,14,44,267,22,09,28,136,27*7F +$GPGSV,3,2,11,29,28,200,25,02,25,101,24,27,23,137,23,04,21,055,30*7B +$GPGSV,3,3,11,31,18,305,27,32,06,331,,20,02,354,*45 +{"class":"SKY","tag":"GSV","xdop":0.80,"ydop":0.90,"vdop":2.12,"tdop":1.49,"hdop":1.20,"gdop":2.86,"pdop":2.44,"satellites":[{"PRN":12,"el":73,"az":67,"ss":25,"used":true},{"PRN":30,"el":67,"az":271,"ss":25,"used":true},{"PRN":14,"el":44,"az":267,"ss":22,"used":true},{"PRN":9,"el":28,"az":136,"ss":27,"used":true},{"PRN":29,"el":28,"az":200,"ss":25,"used":true},{"PRN":2,"el":25,"az":101,"ss":24,"used":true},{"PRN":27,"el":23,"az":137,"ss":23,"used":false},{"PRN":4,"el":21,"az":55,"ss":30,"used":true},{"PRN":31,"el":18,"az":305,"ss":27,"used":true},{"PRN":32,"el":6,"az":331,"ss":0,"used":false},{"PRN":20,"el":2,"az":354,"ss":0,"used":false}]} +$GPRMC,171024.972,A,5200.8518,N,00421.7884,E,000.0,008.0,120610,,,A*68 +{"class":"TPV","tag":"RMC","time":1276362624.972,"ept":0.005,"lat":52.014196667,"lon":4.363140000,"alt":4.800,"epx":11.316,"epy":13.032,"epv":34.500,"track":8.0000,"speed":0.000,"climb":0.000,"eps":26.06,"mode":3} +$GPVTG,008.0,T,,M,000.0,N,000.0,K,A*05 +$GPGSA,A,3,14,30,12,09,29,02,04,31,,,,,1.8,1.0,1.5*3D +$GPGSV,3,1,11,12,73,067,34,30,67,271,33,14,44,267,23,09,28,136,28*76 diff --git a/test/daemon/bt-q818.log b/test/daemon/bt-q818.log new file mode 100644 index 0000000..cdf31ee --- /dev/null +++ b/test/daemon/bt-q818.log @@ -0,0 +1,178 @@ +# Name: BT-Q818 +# Chipset: MTK +# Submitted-by: Jason Komut +# Date: June 3rd 2010 7:53 PST +# Location: +34? 1' 58.80", -117? 44' 49.56" +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGGA,145243.000,3401.9764,N,11744.8274,W,2,10,0.87,234.7,M,-33.2,M,0000,0000*5F +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,049,36,24,54,134,38,51,48,161,31*7F +$GPGSV,3,2,11,19,36,273,30,06,28,224,27,03,27,237,25,18,25,076,36*70 +$GPGSV,3,3,11,31,19,169,29,21,16,136,28,09,11,039,34*48 +$GPRMC,145243.000,A,3401.9764,N,11744.8274,W,0.00,119.27,030610,,,D*70 +$GPGGA,145244.000,3401.9764,N,11744.8274,W,2,10,0.87,234.7,M,-33.2,M,0000,0000*58 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,050,36,24,54,134,38,51,48,161,31*77 +$GPGSV,3,2,11,19,36,273,30,06,28,224,27,03,27,237,25,18,25,076,36*70 +$GPGSV,3,3,11,31,19,169,28,21,16,136,28,09,11,039,34*49 +$GPRMC,145244.000,A,3401.9764,N,11744.8274,W,0.00,119.27,030610,,,D*77 +$GPGGA,145245.000,3401.9764,N,11744.8274,W,2,10,0.87,234.7,M,-33.2,M,0000,0000*59 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,050,36,24,54,134,38,51,48,161,31*77 +$GPGSV,3,2,11,19,36,273,30,06,28,224,27,03,27,237,25,18,25,076,35*73 +$GPGSV,3,3,11,31,19,169,28,21,16,136,27,09,11,039,34*46 +$GPRMC,145245.000,A,3401.9764,N,11744.8274,W,0.00,119.27,030610,,,D*76 +$GPGGA,145246.000,3401.9765,N,11744.8274,W,2,10,0.87,234.7,M,-33.2,M,0000,0000*5B +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,050,36,24,53,134,38,51,48,161,31*70 +$GPGSV,3,2,11,19,36,273,30,06,28,224,27,03,27,237,25,18,25,076,35*73 +$GPGSV,3,3,11,31,19,169,28,21,16,136,27,09,11,039,34*46 +$GPRMC,145246.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*75 +$GPGGA,145247.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*55 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,40,22,54,050,35,24,53,134,38,51,48,161,30*73 +$GPGSV,3,2,11,19,36,273,29,06,28,224,25,03,27,237,25,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,27,21,16,136,26,09,11,039,33*4F +$GPRMC,145247.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*75 +$GPGGA,145248.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*5A +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,050,36,24,53,134,38,51,48,161,30*71 +$GPGSV,3,2,11,19,36,273,29,06,28,224,26,03,27,237,26,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,27,21,16,136,27,09,11,039,34*49 +$GPRMC,145248.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*7A +$GPGGA,145249.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*5B +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,42,22,54,050,36,24,53,134,38,51,48,161,30*72 +$GPGSV,3,2,11,19,36,273,29,06,28,224,27,03,27,237,27,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,27,21,16,136,28,09,11,039,34*46 +$GPRMC,145249.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*7B +$GPGGA,145250.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*53 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,42,22,54,050,36,24,53,134,38,51,48,161,30*72 +$GPGSV,3,2,11,19,36,273,29,06,28,224,27,03,27,237,27,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,27,21,16,136,28,09,11,039,34*46 +$GPRMC,145250.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*73 +$GPGGA,145251.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*52 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,42,22,54,050,36,24,53,134,38,51,48,161,30*72 +$GPGSV,3,2,11,19,36,273,29,06,28,224,27,03,27,237,27,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,26,21,16,136,28,09,11,039,34*47 +$GPRMC,145251.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*72 +$GPGGA,145252.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*51 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,050,35,24,53,134,39,51,48,161,29*7B +$GPGSV,3,2,11,19,36,273,28,06,28,224,27,03,27,237,26,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,25,21,16,136,28,09,11,039,33*43 +$GPRMC,145252.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*70 +$GPGGA,145253.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*50 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,40,22,54,050,34,24,53,134,38,51,48,161,28*7B +$GPGSV,3,2,11,19,36,273,27,06,28,224,27,03,27,237,25,18,25,076,33*73 +$GPGSV,3,3,11,31,19,169,25,21,16,136,28,09,11,039,32*42 +$GPRMC,145253.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*70 +$GPGGA,145254.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*57 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,40,22,54,050,34,24,53,134,39,51,48,161,28*7A +$GPGSV,3,2,11,19,36,273,27,06,28,224,28,03,27,237,24,18,25,076,34*7A +$GPGSV,3,3,11,31,19,169,25,21,16,136,28,09,11,039,33*43 +$GPRMC,145254.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*76 +$GPGGA,145255.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*56 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,39,22,54,050,34,24,53,134,40,51,48,161,28*7A +$GPGSV,3,2,11,19,36,273,28,06,28,224,27,03,27,237,26,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,26,21,16,136,28,09,11,039,32*41 +$GPRMC,145255.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*77 +$GPGGA,145256.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*55 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,39,22,54,050,33,24,53,134,41,51,48,161,*76 +$GPGSV,3,2,11,19,36,273,29,06,28,224,27,03,27,237,27,18,25,076,33*7F +$GPGSV,3,3,11,31,19,169,27,21,16,136,28,09,11,039,32*40 +$GPRMC,145256.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*75 +$GPGGA,145257.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*54 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,31,22,54,050,33,24,53,134,26,51,48,161,27*7A +$GPGSV,3,2,11,19,36,273,29,06,28,224,28,03,27,237,26,18,25,076,19*79 +$GPGSV,3,3,11,31,19,169,29,21,16,136,29,09,11,039,30*4D +$GPRMC,145257.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*74 +$GPGGA,145258.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*64 +$GPGSA,A,3,14,09,22,19,24,06,21,03,31,,,,1.60,0.91,1.32*0B +$GPGSV,3,1,11,14,86,335,24,22,54,050,33,24,53,134,35,51,48,161,39*73 +$GPGSV,3,2,11,19,36,273,30,06,28,224,28,03,27,237,25,18,25,076,19*72 +$GPGSV,3,3,11,31,19,169,28,21,16,136,37,09,11,039,29*4B +$GPRMC,145258.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*7B +$GPGGA,145259.000,3401.9765,N,11744.8274,W,2,9,0.93,234.8,M,-33.2,M,0000,0000*67 +$GPGSA,A,3,14,09,22,18,19,24,06,21,31,,,,1.63,0.93,1.34*06 +$GPGSV,3,1,11,14,86,335,24,22,54,050,25,24,53,134,36,51,48,161,34*7A +$GPGSV,3,2,11,19,36,273,30,06,28,224,27,03,27,237,16,18,25,076,21*76 +$GPGSV,3,3,11,31,19,169,29,21,16,136,37,09,11,039,30*42 +$GPRMC,145259.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*7B +$GPGGA,145300.000,3401.9765,N,11744.8274,W,2,9,0.88,234.8,M,-33.2,M,0000,0000*60 +$GPGSA,A,3,09,22,18,19,24,06,21,03,31,,,,1.87,0.88,1.65*04 +$GPGSV,3,1,11,14,86,335,17,22,54,050,27,24,53,134,37,51,48,161,38*75 +$GPGSV,3,2,11,19,36,273,29,06,28,224,17,03,27,237,17,18,25,076,29*74 +$GPGSV,3,3,11,31,19,169,28,21,16,136,27,09,11,039,29*4A +$GPRMC,145300.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*77 +$GPGGA,145301.000,3401.9765,N,11744.8274,W,2,9,0.87,234.8,M,-33.2,M,0000,0000*6E +$GPGSA,A,3,09,22,18,19,24,06,21,03,31,,,,1.87,0.87,1.65*0B +$GPGSV,3,1,11,14,86,335,17,22,54,050,29,24,53,134,37,51,48,161,38*7B +$GPGSV,3,2,11,19,36,273,27,06,28,224,17,03,27,237,18,18,25,076,28*74 +$GPGSV,3,3,11,31,19,169,27,21,16,136,26,09,11,039,29*44 +$GPRMC,145301.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*76 +$GPGGA,145302.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6A +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,335,17,22,54,050,30,24,53,134,37,51,48,161,37*7C +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,25,09,11,039,29*47 +$GPRMC,145302.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*74 +$GPGGA,145303.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6B +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,335,16,22,54,050,31,24,53,134,37,51,48,161,37*7C +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,25,09,10,039,29*46 +$GPRMC,145303.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*75 +$GPGGA,145304.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6C +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,335,16,22,54,050,32,24,53,134,37,51,48,161,37*7F +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,26,09,10,039,28*44 +$GPRMC,145304.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*73 +$GPGGA,145305.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6D +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,335,16,22,54,050,32,24,53,134,37,51,48,161,37*7F +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,27,09,10,039,28*45 +$GPRMC,145305.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*72 +$GPGGA,145306.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6E +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,335,16,22,54,050,32,24,53,134,37,51,48,161,38*70 +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,27,09,10,039,28*45 +$GPRMC,145306.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*70 +$GPGGA,145307.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6F +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.60,0.91,1.32*04 +$GPGSV,3,1,11,14,86,335,16,22,54,050,32,24,53,134,37,51,48,161,38*70 +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,27,09,10,039,28*45 +$GPRMC,145307.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*71 +$GPGGA,145308.000,3401.9765,N,11744.8275,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*61 +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,338,16,22,54,050,32,24,53,134,37,51,48,161,38*7D +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,26,21,16,136,28,09,10,039,27*44 +$GPRMC,145308.000,A,3401.9765,N,11744.8275,W,0.00,119.27,030610,,,D*7E +$GPGGA,145309.000,3401.9765,N,11744.8275,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*60 +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,338,17,22,54,050,32,24,53,134,37,51,48,161,38*7C +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,26,21,16,136,28,09,10,039,27*44 +$GPRMC,145309.000,A,3401.9765,N,11744.8275,W,0.01,119.27,030610,,,D*7E +$GPGGA,145310.000,3401.9765,N,11744.8275,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*68 +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,338,17,22,54,050,32,24,53,134,37,51,48,161,38*7C +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,26,21,16,136,28,09,10,039,27*44 +$GPRMC,145310.000,A,3401.9765,N,11744.8275,W,0.01,119.27,030610,,,D*76 + diff --git a/test/daemon/bt-q818.log.chk b/test/daemon/bt-q818.log.chk new file mode 100644 index 0000000..d96d856 --- /dev/null +++ b/test/daemon/bt-q818.log.chk @@ -0,0 +1,226 @@ +$GPGGA,145243.000,3401.9764,N,11744.8274,W,2,10,0.87,234.7,M,-33.2,M,0000,0000*5F +{"class":"TPV","tag":"GGA","lat":34.032940000,"lon":-117.747123333,"alt":234.700,"mode":3} +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +{"class":"TPV","tag":"GSA","lat":34.032940000,"lon":-117.747123333,"alt":234.700,"epv":7.533,"mode":3} +$GPGSV,3,1,11,14,86,335,41,22,54,049,36,24,54,134,38,51,48,161,31*7F +$GPGSV,3,2,11,19,36,273,30,06,28,224,27,03,27,237,25,18,25,076,36*70 +$GPGSV,3,3,11,31,19,169,29,21,16,136,28,09,11,039,34*48 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.26,"pdop":1.93,"satellites":[{"PRN":14,"el":86,"az":335,"ss":41,"used":true},{"PRN":22,"el":54,"az":49,"ss":36,"used":true},{"PRN":24,"el":54,"az":134,"ss":38,"used":true},{"PRN":51,"el":48,"az":161,"ss":31,"used":false},{"PRN":19,"el":36,"az":273,"ss":30,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":25,"used":true},{"PRN":18,"el":25,"az":76,"ss":36,"used":true},{"PRN":31,"el":19,"az":169,"ss":29,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":11,"az":39,"ss":34,"used":true}]} +$GPRMC,145243.000,A,3401.9764,N,11744.8274,W,0.00,119.27,030610,,,D*70 +{"class":"TPV","tag":"RMC","time":1275576763.000,"ept":0.005,"lat":34.032940000,"lon":-117.747123333,"alt":234.700,"epx":2.117,"epy":3.287,"epv":7.533,"track":119.2700,"speed":0.000,"mode":3} +$GPGGA,145244.000,3401.9764,N,11744.8274,W,2,10,0.87,234.7,M,-33.2,M,0000,0000*58 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,050,36,24,54,134,38,51,48,161,31*77 +$GPGSV,3,2,11,19,36,273,30,06,28,224,27,03,27,237,25,18,25,076,36*70 +$GPGSV,3,3,11,31,19,169,28,21,16,136,28,09,11,039,34*49 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.26,"pdop":1.93,"satellites":[{"PRN":14,"el":86,"az":335,"ss":41,"used":true},{"PRN":22,"el":54,"az":50,"ss":36,"used":true},{"PRN":24,"el":54,"az":134,"ss":38,"used":true},{"PRN":51,"el":48,"az":161,"ss":31,"used":false},{"PRN":19,"el":36,"az":273,"ss":30,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":25,"used":true},{"PRN":18,"el":25,"az":76,"ss":36,"used":true},{"PRN":31,"el":19,"az":169,"ss":28,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":11,"az":39,"ss":34,"used":true}]} +$GPRMC,145244.000,A,3401.9764,N,11744.8274,W,0.00,119.27,030610,,,D*77 +{"class":"TPV","tag":"RMC","time":1275576764.000,"ept":0.005,"lat":34.032940000,"lon":-117.747123333,"alt":234.700,"epx":2.117,"epy":3.287,"epv":9.347,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.57,"mode":3} +$GPGGA,145245.000,3401.9764,N,11744.8274,W,2,10,0.87,234.7,M,-33.2,M,0000,0000*59 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,050,36,24,54,134,38,51,48,161,31*77 +$GPGSV,3,2,11,19,36,273,30,06,28,224,27,03,27,237,25,18,25,076,35*73 +$GPGSV,3,3,11,31,19,169,28,21,16,136,27,09,11,039,34*46 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.26,"pdop":1.93,"satellites":[{"PRN":14,"el":86,"az":335,"ss":41,"used":true},{"PRN":22,"el":54,"az":50,"ss":36,"used":true},{"PRN":24,"el":54,"az":134,"ss":38,"used":true},{"PRN":51,"el":48,"az":161,"ss":31,"used":false},{"PRN":19,"el":36,"az":273,"ss":30,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":25,"used":true},{"PRN":18,"el":25,"az":76,"ss":35,"used":true},{"PRN":31,"el":19,"az":169,"ss":28,"used":true},{"PRN":21,"el":16,"az":136,"ss":27,"used":true},{"PRN":9,"el":11,"az":39,"ss":34,"used":true}]} +$GPRMC,145245.000,A,3401.9764,N,11744.8274,W,0.00,119.27,030610,,,D*76 +{"class":"TPV","tag":"RMC","time":1275576765.000,"ept":0.005,"lat":34.032940000,"lon":-117.747123333,"alt":234.700,"epx":2.116,"epy":3.297,"epv":9.344,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.58,"mode":3} +$GPGGA,145246.000,3401.9765,N,11744.8274,W,2,10,0.87,234.7,M,-33.2,M,0000,0000*5B +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,050,36,24,53,134,38,51,48,161,31*70 +$GPGSV,3,2,11,19,36,273,30,06,28,224,27,03,27,237,25,18,25,076,35*73 +$GPGSV,3,3,11,31,19,169,28,21,16,136,27,09,11,039,34*46 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":41,"used":true},{"PRN":22,"el":54,"az":50,"ss":36,"used":true},{"PRN":24,"el":53,"az":134,"ss":38,"used":true},{"PRN":51,"el":48,"az":161,"ss":31,"used":false},{"PRN":19,"el":36,"az":273,"ss":30,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":25,"used":true},{"PRN":18,"el":25,"az":76,"ss":35,"used":true},{"PRN":31,"el":19,"az":169,"ss":28,"used":true},{"PRN":21,"el":16,"az":136,"ss":27,"used":true},{"PRN":9,"el":11,"az":39,"ss":34,"used":true}]} +$GPRMC,145246.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*75 +{"class":"TPV","tag":"RMC","time":1275576766.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.700,"epx":2.116,"epy":3.297,"epv":9.344,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145247.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*55 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,40,22,54,050,35,24,53,134,38,51,48,161,30*73 +$GPGSV,3,2,11,19,36,273,29,06,28,224,25,03,27,237,25,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,27,21,16,136,26,09,11,039,33*4F +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":40,"used":true},{"PRN":22,"el":54,"az":50,"ss":35,"used":true},{"PRN":24,"el":53,"az":134,"ss":38,"used":true},{"PRN":51,"el":48,"az":161,"ss":30,"used":false},{"PRN":19,"el":36,"az":273,"ss":29,"used":true},{"PRN":6,"el":28,"az":224,"ss":25,"used":true},{"PRN":3,"el":27,"az":237,"ss":25,"used":true},{"PRN":18,"el":25,"az":76,"ss":34,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":26,"used":true},{"PRN":9,"el":11,"az":39,"ss":33,"used":true}]} +$GPRMC,145247.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*75 +{"class":"TPV","tag":"RMC","time":1275576767.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.000,"climb":0.100,"eps":6.59,"mode":3} +$GPGGA,145248.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*5A +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,050,36,24,53,134,38,51,48,161,30*71 +$GPGSV,3,2,11,19,36,273,29,06,28,224,26,03,27,237,26,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,27,21,16,136,27,09,11,039,34*49 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":41,"used":true},{"PRN":22,"el":54,"az":50,"ss":36,"used":true},{"PRN":24,"el":53,"az":134,"ss":38,"used":true},{"PRN":51,"el":48,"az":161,"ss":30,"used":false},{"PRN":19,"el":36,"az":273,"ss":29,"used":true},{"PRN":6,"el":28,"az":224,"ss":26,"used":true},{"PRN":3,"el":27,"az":237,"ss":26,"used":true},{"PRN":18,"el":25,"az":76,"ss":34,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":27,"used":true},{"PRN":9,"el":11,"az":39,"ss":34,"used":true}]} +$GPRMC,145248.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*7A +{"class":"TPV","tag":"RMC","time":1275576768.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145249.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*5B +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,42,22,54,050,36,24,53,134,38,51,48,161,30*72 +$GPGSV,3,2,11,19,36,273,29,06,28,224,27,03,27,237,27,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,27,21,16,136,28,09,11,039,34*46 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":42,"used":true},{"PRN":22,"el":54,"az":50,"ss":36,"used":true},{"PRN":24,"el":53,"az":134,"ss":38,"used":true},{"PRN":51,"el":48,"az":161,"ss":30,"used":false},{"PRN":19,"el":36,"az":273,"ss":29,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":27,"used":true},{"PRN":18,"el":25,"az":76,"ss":34,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":11,"az":39,"ss":34,"used":true}]} +$GPRMC,145249.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*7B +{"class":"TPV","tag":"RMC","time":1275576769.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145250.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*53 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,42,22,54,050,36,24,53,134,38,51,48,161,30*72 +$GPGSV,3,2,11,19,36,273,29,06,28,224,27,03,27,237,27,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,27,21,16,136,28,09,11,039,34*46 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":42,"used":true},{"PRN":22,"el":54,"az":50,"ss":36,"used":true},{"PRN":24,"el":53,"az":134,"ss":38,"used":true},{"PRN":51,"el":48,"az":161,"ss":30,"used":false},{"PRN":19,"el":36,"az":273,"ss":29,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":27,"used":true},{"PRN":18,"el":25,"az":76,"ss":34,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":11,"az":39,"ss":34,"used":true}]} +$GPRMC,145250.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*73 +{"class":"TPV","tag":"RMC","time":1275576770.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145251.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*52 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,42,22,54,050,36,24,53,134,38,51,48,161,30*72 +$GPGSV,3,2,11,19,36,273,29,06,28,224,27,03,27,237,27,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,26,21,16,136,28,09,11,039,34*47 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":42,"used":true},{"PRN":22,"el":54,"az":50,"ss":36,"used":true},{"PRN":24,"el":53,"az":134,"ss":38,"used":true},{"PRN":51,"el":48,"az":161,"ss":30,"used":false},{"PRN":19,"el":36,"az":273,"ss":29,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":27,"used":true},{"PRN":18,"el":25,"az":76,"ss":34,"used":true},{"PRN":31,"el":19,"az":169,"ss":26,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":11,"az":39,"ss":34,"used":true}]} +$GPRMC,145251.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*72 +{"class":"TPV","tag":"RMC","time":1275576771.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145252.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*51 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,41,22,54,050,35,24,53,134,39,51,48,161,29*7B +$GPGSV,3,2,11,19,36,273,28,06,28,224,27,03,27,237,26,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,25,21,16,136,28,09,11,039,33*43 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":41,"used":true},{"PRN":22,"el":54,"az":50,"ss":35,"used":true},{"PRN":24,"el":53,"az":134,"ss":39,"used":true},{"PRN":51,"el":48,"az":161,"ss":29,"used":false},{"PRN":19,"el":36,"az":273,"ss":28,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":26,"used":true},{"PRN":18,"el":25,"az":76,"ss":34,"used":true},{"PRN":31,"el":19,"az":169,"ss":25,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":11,"az":39,"ss":33,"used":true}]} +$GPRMC,145252.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*70 +{"class":"TPV","tag":"RMC","time":1275576772.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145253.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*50 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,40,22,54,050,34,24,53,134,38,51,48,161,28*7B +$GPGSV,3,2,11,19,36,273,27,06,28,224,27,03,27,237,25,18,25,076,33*73 +$GPGSV,3,3,11,31,19,169,25,21,16,136,28,09,11,039,32*42 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":40,"used":true},{"PRN":22,"el":54,"az":50,"ss":34,"used":true},{"PRN":24,"el":53,"az":134,"ss":38,"used":true},{"PRN":51,"el":48,"az":161,"ss":28,"used":false},{"PRN":19,"el":36,"az":273,"ss":27,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":25,"used":true},{"PRN":18,"el":25,"az":76,"ss":33,"used":true},{"PRN":31,"el":19,"az":169,"ss":25,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":11,"az":39,"ss":32,"used":true}]} +$GPRMC,145253.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*70 +{"class":"TPV","tag":"RMC","time":1275576773.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145254.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*57 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,40,22,54,050,34,24,53,134,39,51,48,161,28*7A +$GPGSV,3,2,11,19,36,273,27,06,28,224,28,03,27,237,24,18,25,076,34*7A +$GPGSV,3,3,11,31,19,169,25,21,16,136,28,09,11,039,33*43 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":40,"used":true},{"PRN":22,"el":54,"az":50,"ss":34,"used":true},{"PRN":24,"el":53,"az":134,"ss":39,"used":true},{"PRN":51,"el":48,"az":161,"ss":28,"used":false},{"PRN":19,"el":36,"az":273,"ss":27,"used":true},{"PRN":6,"el":28,"az":224,"ss":28,"used":true},{"PRN":3,"el":27,"az":237,"ss":24,"used":true},{"PRN":18,"el":25,"az":76,"ss":34,"used":true},{"PRN":31,"el":19,"az":169,"ss":25,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":11,"az":39,"ss":33,"used":true}]} +$GPRMC,145254.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*76 +{"class":"TPV","tag":"RMC","time":1275576774.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145255.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*56 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,39,22,54,050,34,24,53,134,40,51,48,161,28*7A +$GPGSV,3,2,11,19,36,273,28,06,28,224,27,03,27,237,26,18,25,076,34*78 +$GPGSV,3,3,11,31,19,169,26,21,16,136,28,09,11,039,32*41 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":39,"used":true},{"PRN":22,"el":54,"az":50,"ss":34,"used":true},{"PRN":24,"el":53,"az":134,"ss":40,"used":true},{"PRN":51,"el":48,"az":161,"ss":28,"used":false},{"PRN":19,"el":36,"az":273,"ss":28,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":26,"used":true},{"PRN":18,"el":25,"az":76,"ss":34,"used":true},{"PRN":31,"el":19,"az":169,"ss":26,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":11,"az":39,"ss":32,"used":true}]} +$GPRMC,145255.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*77 +{"class":"TPV","tag":"RMC","time":1275576775.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145256.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*55 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,39,22,54,050,33,24,53,134,41,51,48,161,*76 +$GPGSV,3,2,11,19,36,273,29,06,28,224,27,03,27,237,27,18,25,076,33*7F +$GPGSV,3,3,11,31,19,169,27,21,16,136,28,09,11,039,32*40 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":39,"used":true},{"PRN":22,"el":54,"az":50,"ss":33,"used":true},{"PRN":24,"el":53,"az":134,"ss":41,"used":true},{"PRN":51,"el":48,"az":161,"ss":0,"used":false},{"PRN":19,"el":36,"az":273,"ss":29,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":27,"used":true},{"PRN":18,"el":25,"az":76,"ss":33,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":11,"az":39,"ss":32,"used":true}]} +$GPRMC,145256.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*75 +{"class":"TPV","tag":"RMC","time":1275576776.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145257.000,3401.9765,N,11744.8274,W,2,10,0.87,234.8,M,-33.2,M,0000,0000*54 +$GPGSA,A,3,14,09,22,18,19,24,06,21,03,31,,,1.58,0.87,1.31*0D +$GPGSV,3,1,11,14,86,335,31,22,54,050,33,24,53,134,26,51,48,161,27*7A +$GPGSV,3,2,11,19,36,273,29,06,28,224,28,03,27,237,26,18,25,076,19*79 +$GPGSV,3,3,11,31,19,169,29,21,16,136,29,09,11,039,30*4D +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.88,"vdop":1.63,"tdop":1.17,"hdop":1.04,"gdop":2.27,"pdop":1.94,"satellites":[{"PRN":14,"el":86,"az":335,"ss":31,"used":true},{"PRN":22,"el":54,"az":50,"ss":33,"used":true},{"PRN":24,"el":53,"az":134,"ss":26,"used":true},{"PRN":51,"el":48,"az":161,"ss":27,"used":false},{"PRN":19,"el":36,"az":273,"ss":29,"used":true},{"PRN":6,"el":28,"az":224,"ss":28,"used":true},{"PRN":3,"el":27,"az":237,"ss":26,"used":true},{"PRN":18,"el":25,"az":76,"ss":19,"used":true},{"PRN":31,"el":19,"az":169,"ss":29,"used":true},{"PRN":21,"el":16,"az":136,"ss":29,"used":true},{"PRN":9,"el":11,"az":39,"ss":30,"used":true}]} +$GPRMC,145257.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*74 +{"class":"TPV","tag":"RMC","time":1275576777.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145258.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*64 +$GPGSA,A,3,14,09,22,19,24,06,21,03,31,,,,1.60,0.91,1.32*0B +$GPGSV,3,1,11,14,86,335,24,22,54,050,33,24,53,134,35,51,48,161,39*73 +$GPGSV,3,2,11,19,36,273,30,06,28,224,28,03,27,237,25,18,25,076,19*72 +$GPGSV,3,3,11,31,19,169,28,21,16,136,37,09,11,039,29*4B +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":335,"ss":24,"used":true},{"PRN":22,"el":54,"az":50,"ss":33,"used":true},{"PRN":24,"el":53,"az":134,"ss":35,"used":true},{"PRN":51,"el":48,"az":161,"ss":39,"used":false},{"PRN":19,"el":36,"az":273,"ss":30,"used":true},{"PRN":6,"el":28,"az":224,"ss":28,"used":true},{"PRN":3,"el":27,"az":237,"ss":25,"used":true},{"PRN":18,"el":25,"az":76,"ss":19,"used":false},{"PRN":31,"el":19,"az":169,"ss":28,"used":true},{"PRN":21,"el":16,"az":136,"ss":37,"used":true},{"PRN":9,"el":11,"az":39,"ss":29,"used":true}]} +$GPRMC,145258.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*7B +{"class":"TPV","tag":"RMC","time":1275576778.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.113,"epy":3.296,"epv":9.391,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.59,"mode":3} +$GPGGA,145259.000,3401.9765,N,11744.8274,W,2,9,0.93,234.8,M,-33.2,M,0000,0000*67 +$GPGSA,A,3,14,09,22,18,19,24,06,21,31,,,,1.63,0.93,1.34*06 +$GPGSV,3,1,11,14,86,335,24,22,54,050,25,24,53,134,36,51,48,161,34*7A +$GPGSV,3,2,11,19,36,273,30,06,28,224,27,03,27,237,16,18,25,076,21*76 +$GPGSV,3,3,11,31,19,169,29,21,16,136,37,09,11,039,30*42 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":335,"ss":24,"used":true},{"PRN":22,"el":54,"az":50,"ss":25,"used":true},{"PRN":24,"el":53,"az":134,"ss":36,"used":true},{"PRN":51,"el":48,"az":161,"ss":34,"used":false},{"PRN":19,"el":36,"az":273,"ss":30,"used":true},{"PRN":6,"el":28,"az":224,"ss":27,"used":true},{"PRN":3,"el":27,"az":237,"ss":16,"used":false},{"PRN":18,"el":25,"az":76,"ss":21,"used":true},{"PRN":31,"el":19,"az":169,"ss":29,"used":true},{"PRN":21,"el":16,"az":136,"ss":37,"used":true},{"PRN":9,"el":11,"az":39,"ss":30,"used":true}]} +$GPRMC,145259.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*7B +{"class":"TPV","tag":"RMC","time":1275576779.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.321,"epy":3.342,"epv":10.112,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.64,"mode":3} +$GPGGA,145300.000,3401.9765,N,11744.8274,W,2,9,0.88,234.8,M,-33.2,M,0000,0000*60 +$GPGSA,A,3,09,22,18,19,24,06,21,03,31,,,,1.87,0.88,1.65*04 +$GPGSV,3,1,11,14,86,335,17,22,54,050,27,24,53,134,37,51,48,161,38*75 +$GPGSV,3,2,11,19,36,273,29,06,28,224,17,03,27,237,17,18,25,076,29*74 +$GPGSV,3,3,11,31,19,169,28,21,16,136,27,09,11,039,29*4A +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":335,"ss":17,"used":false},{"PRN":22,"el":54,"az":50,"ss":27,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":38,"used":false},{"PRN":19,"el":36,"az":273,"ss":29,"used":true},{"PRN":6,"el":28,"az":224,"ss":17,"used":true},{"PRN":3,"el":27,"az":237,"ss":17,"used":true},{"PRN":18,"el":25,"az":76,"ss":29,"used":true},{"PRN":31,"el":19,"az":169,"ss":28,"used":true},{"PRN":21,"el":16,"az":136,"ss":27,"used":true},{"PRN":9,"el":11,"az":39,"ss":29,"used":true}]} +$GPRMC,145300.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*77 +{"class":"TPV","tag":"RMC","time":1275576780.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.321,"epy":3.342,"epv":10.112,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.68,"mode":3} +$GPGGA,145301.000,3401.9765,N,11744.8274,W,2,9,0.87,234.8,M,-33.2,M,0000,0000*6E +$GPGSA,A,3,09,22,18,19,24,06,21,03,31,,,,1.87,0.87,1.65*0B +$GPGSV,3,1,11,14,86,335,17,22,54,050,29,24,53,134,37,51,48,161,38*7B +$GPGSV,3,2,11,19,36,273,27,06,28,224,17,03,27,237,18,18,25,076,28*74 +$GPGSV,3,3,11,31,19,169,27,21,16,136,26,09,11,039,29*44 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":335,"ss":17,"used":false},{"PRN":22,"el":54,"az":50,"ss":29,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":38,"used":false},{"PRN":19,"el":36,"az":273,"ss":27,"used":true},{"PRN":6,"el":28,"az":224,"ss":17,"used":true},{"PRN":3,"el":27,"az":237,"ss":18,"used":true},{"PRN":18,"el":25,"az":76,"ss":28,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":26,"used":true},{"PRN":9,"el":11,"az":39,"ss":29,"used":true}]} +$GPRMC,145301.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*76 +{"class":"TPV","tag":"RMC","time":1275576781.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.321,"epy":3.342,"epv":10.112,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.68,"mode":3} +$GPGGA,145302.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6A +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,335,17,22,54,050,30,24,53,134,37,51,48,161,37*7C +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,25,09,11,039,29*47 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":335,"ss":17,"used":true},{"PRN":22,"el":54,"az":50,"ss":30,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":37,"used":false},{"PRN":19,"el":36,"az":273,"ss":26,"used":true},{"PRN":6,"el":28,"az":224,"ss":0,"used":false},{"PRN":3,"el":27,"az":237,"ss":18,"used":true},{"PRN":18,"el":25,"az":76,"ss":28,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":25,"used":true},{"PRN":9,"el":11,"az":39,"ss":29,"used":true}]} +$GPRMC,145302.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*74 +{"class":"TPV","tag":"RMC","time":1275576782.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.321,"epy":3.342,"epv":10.112,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.68,"mode":3} +$GPGGA,145303.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6B +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,335,16,22,54,050,31,24,53,134,37,51,48,161,37*7C +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,25,09,10,039,29*46 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":335,"ss":16,"used":true},{"PRN":22,"el":54,"az":50,"ss":31,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":37,"used":false},{"PRN":19,"el":36,"az":273,"ss":26,"used":true},{"PRN":6,"el":28,"az":224,"ss":0,"used":false},{"PRN":3,"el":27,"az":237,"ss":18,"used":true},{"PRN":18,"el":25,"az":76,"ss":28,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":25,"used":true},{"PRN":9,"el":10,"az":39,"ss":29,"used":true}]} +$GPRMC,145303.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*75 +{"class":"TPV","tag":"RMC","time":1275576783.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.321,"epy":3.342,"epv":10.112,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.68,"mode":3} +$GPGGA,145304.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6C +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,335,16,22,54,050,32,24,53,134,37,51,48,161,37*7F +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,26,09,10,039,28*44 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":335,"ss":16,"used":true},{"PRN":22,"el":54,"az":50,"ss":32,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":37,"used":false},{"PRN":19,"el":36,"az":273,"ss":26,"used":true},{"PRN":6,"el":28,"az":224,"ss":0,"used":false},{"PRN":3,"el":27,"az":237,"ss":18,"used":true},{"PRN":18,"el":25,"az":76,"ss":28,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":26,"used":true},{"PRN":9,"el":10,"az":39,"ss":28,"used":true}]} +$GPRMC,145304.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*73 +{"class":"TPV","tag":"RMC","time":1275576784.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.321,"epy":3.342,"epv":10.112,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.68,"mode":3} +$GPGGA,145305.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6D +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,335,16,22,54,050,32,24,53,134,37,51,48,161,37*7F +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,27,09,10,039,28*45 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":335,"ss":16,"used":true},{"PRN":22,"el":54,"az":50,"ss":32,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":37,"used":false},{"PRN":19,"el":36,"az":273,"ss":26,"used":true},{"PRN":6,"el":28,"az":224,"ss":0,"used":false},{"PRN":3,"el":27,"az":237,"ss":18,"used":true},{"PRN":18,"el":25,"az":76,"ss":28,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":27,"used":true},{"PRN":9,"el":10,"az":39,"ss":28,"used":true}]} +$GPRMC,145305.000,A,3401.9765,N,11744.8274,W,0.00,119.27,030610,,,D*72 +{"class":"TPV","tag":"RMC","time":1275576785.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.321,"epy":3.342,"epv":10.112,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.68,"mode":3} +$GPGGA,145306.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6E +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,335,16,22,54,050,32,24,53,134,37,51,48,161,38*70 +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,27,09,10,039,28*45 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":335,"ss":16,"used":true},{"PRN":22,"el":54,"az":50,"ss":32,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":38,"used":false},{"PRN":19,"el":36,"az":273,"ss":26,"used":true},{"PRN":6,"el":28,"az":224,"ss":0,"used":false},{"PRN":3,"el":27,"az":237,"ss":18,"used":true},{"PRN":18,"el":25,"az":76,"ss":28,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":27,"used":true},{"PRN":9,"el":10,"az":39,"ss":28,"used":true}]} +$GPRMC,145306.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*70 +{"class":"TPV","tag":"RMC","time":1275576786.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.321,"epy":3.342,"epv":10.112,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.68,"mode":3} +$GPGGA,145307.000,3401.9765,N,11744.8274,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*6F +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.60,0.91,1.32*04 +$GPGSV,3,1,11,14,86,335,16,22,54,050,32,24,53,134,37,51,48,161,38*70 +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,27,21,16,136,27,09,10,039,28*45 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":335,"ss":16,"used":true},{"PRN":22,"el":54,"az":50,"ss":32,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":38,"used":false},{"PRN":19,"el":36,"az":273,"ss":26,"used":true},{"PRN":6,"el":28,"az":224,"ss":0,"used":false},{"PRN":3,"el":27,"az":237,"ss":18,"used":true},{"PRN":18,"el":25,"az":76,"ss":28,"used":true},{"PRN":31,"el":19,"az":169,"ss":27,"used":true},{"PRN":21,"el":16,"az":136,"ss":27,"used":true},{"PRN":9,"el":10,"az":39,"ss":28,"used":true}]} +$GPRMC,145307.000,A,3401.9765,N,11744.8274,W,0.01,119.27,030610,,,D*71 +{"class":"TPV","tag":"RMC","time":1275576787.000,"ept":0.005,"lat":34.032941667,"lon":-117.747123333,"alt":234.800,"epx":2.321,"epy":3.342,"epv":10.112,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.68,"mode":3} +$GPGGA,145308.000,3401.9765,N,11744.8275,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*61 +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,338,16,22,54,050,32,24,53,134,37,51,48,161,38*7D +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,26,21,16,136,28,09,10,039,27*44 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":338,"ss":16,"used":true},{"PRN":22,"el":54,"az":50,"ss":32,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":38,"used":false},{"PRN":19,"el":36,"az":273,"ss":26,"used":true},{"PRN":6,"el":28,"az":224,"ss":0,"used":false},{"PRN":3,"el":27,"az":237,"ss":18,"used":true},{"PRN":18,"el":25,"az":76,"ss":28,"used":true},{"PRN":31,"el":19,"az":169,"ss":26,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":10,"az":39,"ss":27,"used":true}]} +$GPRMC,145308.000,A,3401.9765,N,11744.8275,W,0.00,119.27,030610,,,D*7E +{"class":"TPV","tag":"RMC","time":1275576788.000,"ept":0.005,"lat":34.032941667,"lon":-117.747125000,"alt":234.800,"epx":2.321,"epy":3.342,"epv":10.112,"track":119.2700,"speed":0.000,"climb":0.000,"eps":6.68,"mode":3} +$GPGGA,145309.000,3401.9765,N,11744.8275,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*60 +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,338,17,22,54,050,32,24,53,134,37,51,48,161,38*7C +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,26,21,16,136,28,09,10,039,27*44 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":338,"ss":17,"used":true},{"PRN":22,"el":54,"az":50,"ss":32,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":38,"used":false},{"PRN":19,"el":36,"az":273,"ss":26,"used":true},{"PRN":6,"el":28,"az":224,"ss":0,"used":false},{"PRN":3,"el":27,"az":237,"ss":18,"used":true},{"PRN":18,"el":25,"az":76,"ss":28,"used":true},{"PRN":31,"el":19,"az":169,"ss":26,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":10,"az":39,"ss":27,"used":true}]} +$GPRMC,145309.000,A,3401.9765,N,11744.8275,W,0.01,119.27,030610,,,D*7E +{"class":"TPV","tag":"RMC","time":1275576789.000,"ept":0.005,"lat":34.032941667,"lon":-117.747125000,"alt":234.800,"epx":2.322,"epy":3.342,"epv":10.116,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.68,"mode":3} +$GPGGA,145310.000,3401.9765,N,11744.8275,W,2,9,0.91,234.8,M,-33.2,M,0000,0000*68 +$GPGSA,A,3,14,09,22,18,19,24,21,03,31,,,,1.61,0.91,1.32*05 +$GPGSV,3,1,11,14,86,338,17,22,54,050,32,24,53,134,37,51,48,161,38*7C +$GPGSV,3,2,11,19,36,273,26,06,28,224,,03,27,237,18,18,25,076,28*73 +$GPGSV,3,3,11,31,19,169,26,21,16,136,28,09,10,039,27*44 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":0.89,"vdop":1.76,"tdop":1.26,"hdop":1.09,"gdop":2.42,"pdop":2.07,"satellites":[{"PRN":14,"el":86,"az":338,"ss":17,"used":true},{"PRN":22,"el":54,"az":50,"ss":32,"used":true},{"PRN":24,"el":53,"az":134,"ss":37,"used":true},{"PRN":51,"el":48,"az":161,"ss":38,"used":false},{"PRN":19,"el":36,"az":273,"ss":26,"used":true},{"PRN":6,"el":28,"az":224,"ss":0,"used":false},{"PRN":3,"el":27,"az":237,"ss":18,"used":true},{"PRN":18,"el":25,"az":76,"ss":28,"used":true},{"PRN":31,"el":19,"az":169,"ss":26,"used":true},{"PRN":21,"el":16,"az":136,"ss":28,"used":true},{"PRN":9,"el":10,"az":39,"ss":27,"used":true}]} +$GPRMC,145310.000,A,3401.9765,N,11744.8275,W,0.01,119.27,030610,,,D*76 +{"class":"TPV","tag":"RMC","time":1275576790.000,"ept":0.005,"lat":34.032941667,"lon":-117.747125000,"alt":234.800,"epx":2.322,"epy":3.342,"epv":10.116,"track":119.2700,"speed":0.005,"climb":0.000,"eps":6.68,"mode":3} diff --git a/test/daemon/bt451.log b/test/daemon/bt451.log new file mode 100644 index 0000000..868872b --- /dev/null +++ b/test/daemon/bt451.log @@ -0,0 +1,1045 @@ +# Name: BT-451 +# Chipset: ANTARIS ATR062x +# Cycle time: 1 +# Submitted-by: Mindaugas +# Date: 9 Dec 2009 +# Location: Lithuania, 55.8N 23.6E +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# No fix, indoors +$GPTXT,01,01,02,u-blox ag - www.u-blox.com*50 +$GPTXT,01,01,02,ANTARIS ATR062x HW 80040001*26 +$GPTXT,01,01,02,ROM CORE 5.00 Jan 09 2006 12:00:00*76 +$GPTXT,01,01,02,LIC 1EBF-BD07-E83D-6BE1-0F7A*50 +$GPTXT,01,01,02,ANTSUPERV=AC SD OD PDoS *0A +$GPTXT,01,01,02,ANTSTATUS=OK*3B +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +# Stationary +$GPGLL,5547.82107,N,02334.14132,E,152504.50,A,A*67 +$GPZDA,152504.50,09,12,2009,00,00*65 +$GPRMC,152505.00,A,5547.82113,N,02334.14130,E,0.253,,091209,,,A*7A +$GPVTG,,T,,M,0.253,N,0.469,K,A*2C +$GPGGA,152505.00,5547.82113,N,02334.14130,E,1,04,2.72,37.0,M,26.9,M,,*6B +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.25,2.72,5.62*05 +$GPGSV,2,1,07,26,34,052,33,19,,,36,32,45,237,42,06,,,34*75 +$GPGSV,2,2,07,22,,,40,11,57,277,40,14,51,083,38*7F +$GPGLL,5547.82113,N,02334.14130,E,152505.00,A,A*64 +$GPZDA,152505.00,09,12,2009,00,00*61 +$GPRMC,152505.50,A,5547.82119,N,02334.14124,E,0.265,,091209,,,A*75 +$GPVTG,,T,,M,0.265,N,0.491,K,A*2E +$GPGGA,152505.50,5547.82119,N,02334.14124,E,1,04,2.72,36.7,M,26.9,M,,*67 +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.72,5.62*04 +$GPGSV,2,1,07,26,34,052,34,19,,,36,32,45,237,42,06,,,34*72 +$GPGSV,2,2,07,22,,,40,11,57,277,41,14,51,083,38*7E +$GPGLL,5547.82119,N,02334.14124,E,152505.50,A,A*6E +$GPZDA,152505.50,09,12,2009,00,00*64 +$GPRMC,152506.00,A,5547.82126,N,02334.14117,E,0.340,,091209,,,A*79 +$GPVTG,,T,,M,0.340,N,0.631,K,A*20 +$GPGGA,152506.00,5547.82126,N,02334.14117,E,1,04,2.72,36.5,M,26.9,M,,*6F +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.25,2.72,5.62*05 +$GPGSV,2,1,07,26,34,052,34,19,,,37,32,45,237,42,06,,,34*73 +$GPGSV,2,2,07,22,,,40,11,57,277,41,14,51,083,39*7F +$GPGLL,5547.82126,N,02334.14117,E,152506.00,A,A*64 +$GPZDA,152506.00,09,12,2009,00,00*62 +$GPRMC,152506.50,A,5547.82132,N,02334.14113,E,0.336,,091209,,,A*7C +$GPVTG,,T,,M,0.336,N,0.623,K,A*22 +$GPGGA,152506.50,5547.82132,N,02334.14113,E,1,04,2.72,36.2,M,26.9,M,,*6C +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.72,5.62*04 +$GPGSV,2,1,07,26,34,052,35,19,,,37,32,45,237,43,06,,,35*72 +$GPGSV,2,2,07,22,,,41,11,57,277,41,14,51,083,39*7E +$GPGLL,5547.82132,N,02334.14113,E,152506.50,A,A*60 +$GPZDA,152506.50,09,12,2009,00,00*67 +$GPRMC,152507.00,A,5547.82139,N,02334.14105,E,0.371,16.99,091209,,,A*5E +$GPVTG,16.99,T,,M,0.371,N,0.687,K,A*06 +$GPGGA,152507.00,5547.82139,N,02334.14105,E,1,04,2.72,36.0,M,26.9,M,,*66 +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.72,5.62*04 +$GPGSV,2,1,07,26,34,052,35,19,,,37,32,45,237,42,06,,,35*73 +$GPGSV,2,2,07,22,,,40,11,57,277,41,14,51,083,39*7F +$GPGLL,5547.82139,N,02334.14105,E,152507.00,A,A*68 +$GPZDA,152507.00,09,12,2009,00,00*63 +$GPRMC,152507.50,A,5547.82145,N,02334.14098,E,0.309,,091209,,,A*73 +$GPVTG,,T,,M,0.309,N,0.572,K,A*29 +$GPGGA,152507.50,5547.82145,N,02334.14098,E,1,04,2.72,35.7,M,26.9,M,,*69 +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.72,5.62*04 +$GPGSV,2,1,07,26,34,052,35,19,,,37,32,45,237,42,06,,,34*72 +$GPGSV,2,2,07,22,,,40,11,57,277,41,14,51,083,39*7F +$GPGLL,5547.82145,N,02334.14098,E,152507.50,A,A*63 +$GPZDA,152507.50,09,12,2009,00,00*66 +$GPRMC,152508.00,A,5547.82150,N,02334.14092,E,0.309,,091209,,,A*77 +$GPVTG,,T,,M,0.309,N,0.573,K,A*28 +$GPGGA,152508.00,5547.82150,N,02334.14092,E,1,04,2.72,35.5,M,26.9,M,,*6F +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.72,5.62*04 +$GPGSV,2,1,07,26,34,052,33,19,,,36,32,45,237,41,06,,,33*71 +$GPGSV,2,2,07,22,,,39,11,57,277,40,14,51,083,38*71 +$GPGLL,5547.82150,N,02334.14092,E,152508.00,A,A*67 +$GPZDA,152508.00,09,12,2009,00,00*6C +$GPRMC,152508.50,A,5547.82156,N,02334.14086,E,0.296,,091209,,,A*76 +$GPVTG,,T,,M,0.296,N,0.549,K,A*26 +$GPGGA,152508.50,5547.82156,N,02334.14086,E,1,04,2.73,35.3,M,26.9,M,,*6E +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.73,5.62*05 +$GPGSV,3,1,11,26,34,052,32,19,,,34,20,,,29,32,45,237,39*74 +$GPGSV,3,2,11,02,,,26,06,,,31,18,,,30,24,,,27*73 +$GPGSV,3,3,11,22,,,37,11,57,277,38,14,51,083,36*79 +# Moving in car +$GPGGA,143306.00,5546.83315,N,02334.72613,E,1,08,1.28,129.9,M,26.9,M,,*5B +$GPGSA,A,3,09,19,11,14,03,22,06,26,,,,,3.65,1.28,3.41*0A +$GPGSV,3,1,10,32,22,227,34,09,12,038,29,19,58,204,39,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,30,28,,,32,22,47,070,42*43 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.83315,N,02334.72613,E,143306.00,A,A*63 +$GPZDA,143306.00,09,12,2009,00,00*64 +$GPRMC,143306.50,A,5546.82983,N,02334.72123,E,30.324,221.16,091209,,,A*52 +$GPVTG,221.16,T,,M,30.324,N,56.191,K,A*37 +$GPGGA,143306.50,5546.82983,N,02334.72123,E,1,09,1.26,128.9,M,26.9,M,,*50 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,2.99*05 +$GPGSV,3,1,10,32,22,227,35,09,12,038,29,19,58,204,39,11,36,285,36*76 +$GPGSV,3,2,10,14,45,118,34,03,31,183,30,28,,,34,22,47,070,42*45 +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +$GPGLL,5546.82983,N,02334.72123,E,143306.50,A,A*66 +$GPZDA,143306.50,09,12,2009,00,00*61 +$GPRMC,143307.00,A,5546.82649,N,02334.71625,E,30.860,221.48,091209,,,A*5D +$GPVTG,221.48,T,,M,30.860,N,57.183,K,A*35 +$GPGGA,143307.00,5546.82649,N,02334.71625,E,1,09,1.26,128.1,M,26.9,M,,*57 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,35,09,12,038,29,19,58,204,40,11,36,285,36*78 +$GPGSV,3,2,10,14,45,118,34,03,31,183,30,28,,,35,22,47,070,43*45 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.82649,N,02334.71625,E,143307.00,A,A*69 +$GPZDA,143307.00,09,12,2009,00,00*65 +$GPRMC,143307.50,A,5546.82314,N,02334.71118,E,31.351,221.51,091209,,,A*5C +$GPVTG,221.51,T,,M,31.351,N,58.092,K,A*3B +$GPGGA,143307.50,5546.82314,N,02334.71118,E,1,09,1.26,127.5,M,26.9,M,,*5D +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,35,09,12,038,29,19,58,204,40,11,36,285,36*78 +$GPGSV,3,2,10,14,45,118,34,03,31,183,30,28,,,33,22,47,070,43*43 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +$GPGLL,5546.82314,N,02334.71118,E,143307.50,A,A*68 +$GPZDA,143307.50,09,12,2009,00,00*60 +$GPRMC,143308.00,A,5546.81975,N,02334.70604,E,32.000,221.54,091209,,,A*52 +$GPVTG,221.54,T,,M,32.000,N,59.295,K,A*3E +$GPGGA,143308.00,5546.81975,N,02334.70604,E,1,09,1.26,127.1,M,26.9,M,,*56 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,36,09,12,038,29,19,58,204,41,11,36,285,37*7B +$GPGSV,3,2,10,14,45,118,35,03,31,183,29,28,,,33,22,47,070,43*4A +$GPGSV,3,3,10,06,26,174,35,26,44,080,38*79 +$GPGLL,5546.81975,N,02334.70604,E,143308.00,A,A*67 +$GPZDA,143308.00,09,12,2009,00,00*6A +$GPRMC,143308.50,A,5546.81633,N,02334.70079,E,32.273,221.54,091209,,,A*50 +$GPVTG,221.54,T,,M,32.273,N,59.802,K,A*3C +$GPGGA,143308.50,5546.81633,N,02334.70079,E,1,09,1.26,126.8,M,26.9,M,,*5A +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,34,09,12,038,29,19,58,204,40,11,36,285,35*7A +$GPGSV,3,2,10,14,45,118,35,03,31,183,27,28,,,32,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,37*77 +$GPGLL,5546.81633,N,02334.70079,E,143308.50,A,A*63 +$GPZDA,143308.50,09,12,2009,00,00*6F +$GPRMC,143309.00,A,5546.81291,N,02334.69552,E,32.094,221.48,091209,,,A*5A +$GPVTG,221.48,T,,M,32.094,N,59.470,K,A*33 +$GPGGA,143309.00,5546.81291,N,02334.69552,E,1,09,1.26,126.4,M,26.9,M,,*5A +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,2.99*05 +$GPGSV,3,1,10,32,22,227,34,09,12,038,29,19,58,204,39,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,27,28,,,32,22,47,070,42*45 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +$GPGLL,5546.81291,N,02334.69552,E,143309.00,A,A*6F +$GPZDA,143309.00,09,12,2009,00,00*6B +$GPRMC,143309.50,A,5546.80952,N,02334.69029,E,32.096,221.46,091209,,,A*5F +$GPVTG,221.46,T,,M,32.096,N,59.474,K,A*3B +$GPGGA,143309.50,5546.80952,N,02334.69029,E,1,09,1.26,126.2,M,26.9,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,34,09,12,038,28,19,58,204,40,11,36,285,35*7B +$GPGSV,3,2,10,14,45,118,33,03,31,183,29,28,,,32,22,47,070,42*4C +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +$GPGLL,5546.80952,N,02334.69029,E,143309.50,A,A*66 +$GPZDA,143309.50,09,12,2009,00,00*6E +$GPRMC,143310.00,A,5546.80598,N,02334.68514,E,32.192,221.20,091209,,,A*57 +$GPVTG,221.20,T,,M,32.192,N,59.652,K,A*38 +$GPGGA,143310.00,5546.80598,N,02334.68514,E,1,09,1.26,125.3,M,27.0,M,,*52 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,33,09,12,038,28,19,58,204,40,11,36,285,35*7C +$GPGSV,3,2,10,14,45,118,34,03,31,183,26,28,,,32,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +$GPGLL,5546.80598,N,02334.68514,E,143310.00,A,A*6B +$GPZDA,143310.00,09,12,2009,00,00*63 +$GPRMC,143310.50,A,5546.80248,N,02334.67996,E,32.361,221.42,091209,,,A*5B +$GPVTG,221.42,T,,M,32.361,N,59.964,K,A*38 +$GPGGA,143310.50,5546.80248,N,02334.67996,E,1,09,1.26,124.7,M,27.0,M,,*51 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,33,09,12,038,28,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,26,28,,,32,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +$GPGLL,5546.80248,N,02334.67996,E,143310.50,A,A*6D +$GPZDA,143310.50,09,12,2009,00,00*66 +$GPRMC,143311.00,A,5546.79900,N,02334.67471,E,32.559,221.33,091209,,,A*51 +$GPVTG,221.33,T,,M,32.559,N,60.331,K,A*33 +$GPGGA,143311.00,5546.79900,N,02334.67471,E,1,09,1.26,124.2,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,33,09,12,038,28,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,22,28,,,32,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +$GPGLL,5546.79900,N,02334.67471,E,143311.00,A,A*6C +$GPZDA,143311.00,09,12,2009,00,00*62 +$GPRMC,143311.50,A,5546.79553,N,02334.66940,E,32.825,221.71,091209,,,A*50 +$GPVTG,221.71,T,,M,32.825,N,60.825,K,A*3D +$GPGGA,143311.50,5546.79553,N,02334.66940,E,1,09,1.26,123.8,M,27.0,M,,*59 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,33,09,12,038,28,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,23,28,,,32,22,47,070,42*41 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.79553,N,02334.66940,E,143311.50,A,A*6D +$GPZDA,143311.50,09,12,2009,00,00*67 +$GPRMC,143312.00,A,5546.79205,N,02334.66400,E,33.180,221.70,091209,,,A*5D +$GPVTG,221.70,T,,M,33.180,N,61.482,K,A*3B +$GPGGA,143312.00,5546.79205,N,02334.66400,E,1,09,1.26,123.5,M,27.0,M,,*5F +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,33,09,12,038,28,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,32,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.79205,N,02334.66400,E,143312.00,A,A*66 +$GPZDA,143312.00,09,12,2009,00,00*61 +$GPRMC,143312.50,A,5546.78854,N,02334.65855,E,33.465,221.75,091209,,,A*53 +$GPVTG,221.75,T,,M,33.465,N,62.011,K,A*3D +$GPGGA,143312.50,5546.78854,N,02334.65855,E,1,09,1.26,123.3,M,27.0,M,,*5C +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,40,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,32,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.78854,N,02334.65855,E,143312.50,A,A*63 +$GPZDA,143312.50,09,12,2009,00,00*64 +$GPRMC,143313.00,A,5546.78498,N,02334.65304,E,33.998,221.45,091209,,,A*58 +$GPVTG,221.45,T,,M,33.998,N,62.999,K,A*38 +$GPGGA,143313.00,5546.78498,N,02334.65304,E,1,09,1.26,123.2,M,27.0,M,,*5A +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,40,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,21,28,,,32,22,47,070,42*42 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +$GPGLL,5546.78498,N,02334.65304,E,143313.00,A,A*64 +$GPZDA,143313.00,09,12,2009,00,00*60 +$GPRMC,143313.50,A,5546.78137,N,02334.64747,E,34.471,221.60,091209,,,A*55 +$GPVTG,221.60,T,,M,34.471,N,63.875,K,A*30 +$GPGGA,143313.50,5546.78137,N,02334.64747,E,1,09,1.26,123.0,M,27.0,M,,*5F +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,41,11,36,285,37*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,22,28,,,33,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.78137,N,02334.64747,E,143313.50,A,A*63 +$GPZDA,143313.50,09,12,2009,00,00*65 +$GPRMC,143314.00,A,5546.77773,N,02334.64182,E,34.916,221.39,091209,,,A*51 +$GPVTG,221.39,T,,M,34.916,N,64.699,K,A*3B +$GPGGA,143314.00,5546.77773,N,02334.64182,E,1,09,1.26,122.8,M,27.0,M,,*52 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,41,11,36,285,37*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,33,22,47,070,43*46 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +$GPGLL,5546.77773,N,02334.64182,E,143314.00,A,A*67 +$GPZDA,143314.00,09,12,2009,00,00*67 +$GPRMC,143314.50,A,5546.77404,N,02334.63610,E,35.259,221.42,091209,,,A*51 +$GPVTG,221.42,T,,M,35.259,N,65.335,K,A*34 +$GPGGA,143314.50,5546.77404,N,02334.63610,E,1,09,1.26,122.7,M,27.0,M,,*50 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,40,11,36,285,37*76 +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,33,22,47,070,42*47 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +$GPGLL,5546.77404,N,02334.63610,E,143314.50,A,A*6A +$GPZDA,143314.50,09,12,2009,00,00*62 +$GPRMC,143315.00,A,5546.77031,N,02334.63033,E,35.613,221.33,091209,,,A*5C +$GPVTG,221.33,T,,M,35.613,N,65.991,K,A*3C +$GPGGA,143315.00,5546.77031,N,02334.63033,E,1,09,1.26,122.5,M,27.0,M,,*53 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,41,11,36,285,37*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,,,33,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +$GPGLL,5546.77031,N,02334.63033,E,143315.00,A,A*6B +$GPZDA,143315.00,09,12,2009,00,00*66 +$GPRMC,143315.50,A,5546.76656,N,02334.62450,E,35.901,221.55,091209,,,A*53 +$GPVTG,221.55,T,,M,35.901,N,66.525,K,A*30 +$GPGGA,143315.50,5546.76656,N,02334.62450,E,1,09,1.26,122.4,M,27.0,M,,*51 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,40,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,20,28,,,32,22,47,070,42*43 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +$GPGLL,5546.76656,N,02334.62450,E,143315.50,A,A*68 +$GPZDA,143315.50,09,12,2009,00,00*63 +$GPRMC,143316.00,A,5546.76280,N,02334.61860,E,36.213,221.79,091209,,,A*53 +$GPVTG,221.79,T,,M,36.213,N,67.103,K,A*34 +$GPGGA,143316.00,5546.76280,N,02334.61860,E,1,09,1.26,122.2,M,27.0,M,,*52 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,40,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,21,28,,,33,22,47,070,42*43 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +$GPGLL,5546.76280,N,02334.61860,E,143316.00,A,A*6D +$GPZDA,143316.00,09,12,2009,00,00*65 +$GPRMC,143316.50,A,5546.75900,N,02334.61263,E,36.582,221.76,091209,,,A*5F +$GPVTG,221.76,T,,M,36.582,N,67.786,K,A*3F +$GPGGA,143316.50,5546.75900,N,02334.61263,E,1,09,1.26,122.1,M,27.0,M,,*5D +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,28,19,58,204,40,11,36,285,37*71 +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,33,22,47,070,42*47 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.75900,N,02334.61263,E,143316.50,A,A*61 +$GPZDA,143316.50,09,12,2009,00,00*60 +$GPRMC,143317.00,A,5546.75517,N,02334.60661,E,36.882,221.73,091209,,,A*5E +$GPVTG,221.73,T,,M,36.882,N,68.343,K,A*35 +$GPGGA,143317.00,5546.75517,N,02334.60661,E,1,09,1.26,122.0,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,28,19,58,204,40,11,36,285,37*71 +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,33,22,47,070,42*47 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.75517,N,02334.60661,E,143317.00,A,A*68 +$GPZDA,143317.00,09,12,2009,00,00*64 +$GPRMC,143317.50,A,5546.75131,N,02334.60056,E,37.099,221.59,091209,,,A*52 +$GPVTG,221.59,T,,M,37.099,N,68.744,K,A*3D +$GPGGA,143317.50,5546.75131,N,02334.60056,E,1,09,1.26,122.0,M,27.0,M,,*52 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,32,09,12,038,28,19,58,204,40,11,36,285,36*71 +$GPGSV,3,2,10,14,45,118,34,03,31,183,25,28,,,33,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.75131,N,02334.60056,E,143317.50,A,A*6F +$GPZDA,143317.50,09,12,2009,00,00*61 +$GPRMC,143318.00,A,5546.74742,N,02334.59448,E,37.130,221.51,091209,,,A*50 +$GPVTG,221.51,T,,M,37.130,N,68.801,K,A*39 +$GPGGA,143318.00,5546.74742,N,02334.59448,E,1,09,1.26,121.9,M,27.0,M,,*50 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,27,19,58,204,40,11,36,285,35*7C +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,,,33,22,47,070,42*47 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +$GPGLL,5546.74742,N,02334.59448,E,143318.00,A,A*67 +$GPZDA,143318.00,09,12,2009,00,00*6B +$GPRMC,143318.50,A,5546.74354,N,02334.58840,E,37.142,221.66,091209,,,A*52 +$GPVTG,221.66,T,,M,37.142,N,68.824,K,A*3F +$GPGGA,143318.50,5546.74354,N,02334.58840,E,1,09,1.26,121.8,M,27.0,M,,*52 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,28,19,58,204,40,11,36,285,36*70 +$GPGSV,3,2,10,14,45,118,35,03,31,183,22,28,,,33,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.74354,N,02334.58840,E,143318.50,A,A*64 +$GPZDA,143318.50,09,12,2009,00,00*6E +$GPRMC,143319.00,A,5546.73966,N,02334.58232,E,37.148,221.65,091209,,,A*5C +$GPVTG,221.65,T,,M,37.148,N,68.835,K,A*36 +$GPGGA,143319.00,5546.73966,N,02334.58232,E,1,09,1.26,121.8,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,27,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,25,28,,,33,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.73966,N,02334.58232,E,143319.00,A,A*63 +$GPZDA,143319.00,09,12,2009,00,00*6A +$GPRMC,143319.50,A,5546.73578,N,02334.57626,E,37.138,221.35,091209,,,A*56 +$GPVTG,221.35,T,,M,37.138,N,68.817,K,A*34 +$GPGGA,143319.50,5546.73578,N,02334.57626,E,1,09,1.26,121.8,M,27.0,M,,*5D +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,27,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,25,28,,,33,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.73578,N,02334.57626,E,143319.50,A,A*6B +$GPZDA,143319.50,09,12,2009,00,00*6F +$GPRMC,143320.00,A,5546.73191,N,02334.57020,E,37.095,221.51,091209,,,A*5E +$GPVTG,221.51,T,,M,37.095,N,68.737,K,A*3D +$GPGGA,143320.00,5546.73191,N,02334.57020,E,1,09,1.26,121.7,M,27.0,M,,*5E +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,27,19,58,204,41,11,36,285,36*7E +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,,,33,22,47,070,42*47 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +$GPGLL,5546.73191,N,02334.57020,E,143320.00,A,A*67 +$GPZDA,143320.00,09,12,2009,00,00*60 +$GPRMC,143320.50,A,5546.72805,N,02334.56415,E,36.982,221.56,091209,,,A*54 +$GPVTG,221.56,T,,M,36.982,N,68.528,K,A*38 +$GPGGA,143320.50,5546.72805,N,02334.56415,E,1,09,1.26,121.7,M,27.0,M,,*5D +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,32,09,12,038,27,19,58,204,40,11,36,285,35*7D +$GPGSV,3,2,10,14,45,118,34,03,31,183,22,28,,,32,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.72805,N,02334.56415,E,143320.50,A,A*64 +$GPZDA,143320.50,09,12,2009,00,00*65 +$GPRMC,143321.00,A,5546.72423,N,02334.55813,E,36.738,221.85,091209,,,A*50 +$GPVTG,221.85,T,,M,36.738,N,68.076,K,A*37 +$GPGGA,143321.00,5546.72423,N,02334.55813,E,1,09,1.26,121.7,M,27.0,M,,*58 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,27,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,23,28,,,33,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.72423,N,02334.55813,E,143321.00,A,A*61 +$GPZDA,143321.00,09,12,2009,00,00*61 +$GPRMC,143321.50,A,5546.72043,N,02334.55216,E,36.548,221.51,091209,,,A*54 +$GPVTG,221.51,T,,M,36.548,N,67.724,K,A*34 +$GPGGA,143321.50,5546.72043,N,02334.55216,E,1,09,1.26,121.7,M,27.0,M,,*50 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,32,09,12,038,27,19,58,204,40,11,36,285,36*7E +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,,,34,22,47,070,42*41 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.72043,N,02334.55216,E,143321.50,A,A*69 +$GPZDA,143321.50,09,12,2009,00,00*64 +$GPRMC,143322.00,A,5546.71665,N,02334.54623,E,36.296,221.61,091209,,,A*57 +$GPVTG,221.61,T,,M,36.296,N,67.257,K,A*32 +$GPGGA,143322.00,5546.71665,N,02334.54623,E,1,09,1.26,121.7,M,27.0,M,,*54 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,31,09,12,038,27,19,58,204,38,11,36,285,34*70 +$GPGSV,3,2,10,14,45,118,33,03,31,183,21,28,,,32,22,47,070,40*46 +$GPGSV,3,3,10,06,26,174,31,26,44,080,37*72 +$GPGLL,5546.71665,N,02334.54623,E,143322.00,A,A*6D +$GPZDA,143322.00,09,12,2009,00,00*62 +$GPRMC,143322.50,A,5546.71291,N,02334.54032,E,36.068,222.02,091209,,,A*5E +$GPVTG,222.02,T,,M,36.068,N,66.834,K,A*39 +$GPGGA,143322.50,5546.71291,N,02334.54032,E,1,09,1.26,121.7,M,27.0,M,,*58 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,30,09,12,038,27,19,58,204,38,11,36,285,34*71 +$GPGSV,3,2,10,14,45,118,32,03,31,183,22,28,,,31,22,47,070,40*47 +$GPGSV,3,3,10,06,26,174,32,26,44,080,36*70 +$GPGLL,5546.71291,N,02334.54032,E,143322.50,A,A*61 +$GPZDA,143322.50,09,12,2009,00,00*67 +$GPRMC,143323.00,A,5546.70920,N,02334.53442,E,35.897,221.92,091209,,,A*5F +$GPVTG,221.92,T,,M,35.897,N,66.516,K,A*35 +$GPGGA,143323.00,5546.70920,N,02334.53442,E,1,09,1.26,121.7,M,27.0,M,,*58 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,31,09,12,038,27,19,58,204,39,11,36,285,35*70 +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,,,32,22,47,070,41*45 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +$GPGLL,5546.70920,N,02334.53442,E,143323.00,A,A*61 +$GPZDA,143323.00,09,12,2009,00,00*63 +$GPRMC,143323.50,A,5546.70550,N,02334.52854,E,35.802,222.24,091209,,,A*59 +$GPVTG,222.24,T,,M,35.802,N,66.342,K,A*30 +$GPGGA,143323.50,5546.70550,N,02334.52854,E,1,09,1.26,121.5,M,27.0,M,,*5E +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,32,09,12,038,28,19,58,204,40,11,36,285,36*71 +$GPGSV,3,2,10,14,45,118,35,03,31,183,30,28,,,34,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.70550,N,02334.52854,E,143323.50,A,A*65 +$GPZDA,143323.50,09,12,2009,00,00*66 +$GPRMC,143324.00,A,5546.70183,N,02334.52263,E,35.829,222.00,091209,,,A*50 +$GPVTG,222.00,T,,M,35.829,N,66.391,K,A*31 +$GPGGA,143324.00,5546.70183,N,02334.52263,E,1,09,1.26,121.6,M,27.0,M,,*5B +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,30,19,58,204,40,11,36,285,36*79 +$GPGSV,3,2,10,14,45,118,35,03,31,183,27,28,,,33,22,47,070,41*46 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.70183,N,02334.52263,E,143324.00,A,A*63 +$GPZDA,143324.00,09,12,2009,00,00*64 +$GPRMC,143324.50,A,5546.69812,N,02334.51673,E,35.962,222.09,091209,,,A*5D +$GPVTG,222.09,T,,M,35.962,N,66.638,K,A*30 +$GPGGA,143324.50,5546.69812,N,02334.51673,E,1,09,1.26,121.6,M,27.0,M,,*51 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,30,19,58,204,40,11,36,285,35*7A +$GPGSV,3,2,10,14,45,118,35,03,31,183,27,28,,,32,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.69812,N,02334.51673,E,143324.50,A,A*69 +$GPZDA,143324.50,09,12,2009,00,00*61 +$GPRMC,143325.00,A,5546.69439,N,02334.51078,E,36.290,222.04,091209,,,A*59 +$GPVTG,222.04,T,,M,36.290,N,67.245,K,A*37 +$GPGGA,143325.00,5546.69439,N,02334.51078,E,1,09,1.26,121.5,M,27.0,M,,*5E +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,29,19,58,204,40,11,36,285,35*72 +$GPGSV,3,2,10,14,45,118,35,03,31,183,26,28,,,32,22,47,070,41*46 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +$GPGLL,5546.69439,N,02334.51078,E,143325.00,A,A*65 +$GPZDA,143325.00,09,12,2009,00,00*65 +$GPRMC,143325.50,A,5546.69063,N,02334.50478,E,36.575,221.93,091209,,,A*53 +$GPVTG,221.93,T,,M,36.575,N,67.774,K,A*31 +$GPGGA,143325.50,5546.69063,N,02334.50478,E,1,09,1.26,121.5,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,29,19,58,204,40,11,36,285,36*71 +$GPGSV,3,2,10,14,45,118,35,03,31,183,26,28,,,33,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.69063,N,02334.50478,E,143325.50,A,A*6E +$GPZDA,143325.50,09,12,2009,00,00*60 +$GPRMC,143326.00,A,5546.68683,N,02334.49875,E,36.874,221.81,091209,,,A*5A +$GPVTG,221.81,T,,M,36.874,N,68.328,K,A*3C +$GPGGA,143326.00,5546.68683,N,02334.49875,E,1,09,1.26,121.5,M,27.0,M,,*53 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.00*07 +$GPGSV,3,1,10,32,22,228,33,09,12,038,29,19,58,204,40,11,36,285,36*71 +$GPGSV,3,2,10,14,45,118,35,03,31,183,26,28,,,33,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +$GPGLL,5546.68683,N,02334.49875,E,143326.00,A,A*68 +$GPZDA,143326.00,09,12,2009,00,00*66 +$GPRMC,143326.50,A,5546.68299,N,02334.49268,E,37.174,221.56,091209,,,A*54 +$GPVTG,221.56,T,,M,37.174,N,68.883,K,A*34 +$GPGGA,143326.50,5546.68299,N,02334.49268,E,1,09,1.26,121.5,M,27.0,M,,*5F +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,32,09,12,037,27,19,58,204,40,11,36,285,36*71 +$GPGSV,3,2,10,14,45,118,34,03,31,183,26,28,,,33,22,47,070,42*45 +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +$GPGLL,5546.68299,N,02334.49268,E,143326.50,A,A*64 +$GPZDA,143326.50,09,12,2009,00,00*63 +$GPRMC,143327.00,A,5546.67914,N,02334.48657,E,37.433,221.51,091209,,,A*59 +$GPVTG,221.51,T,,M,37.433,N,69.363,K,A*31 +$GPGGA,143327.00,5546.67914,N,02334.48657,E,1,09,1.47,121.6,M,27.0,M,,*57 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.66,1.47,3.35*02 +$GPGSV,3,1,12,32,22,228,31,27,,,31,09,12,037,26,19,58,204,38*46 +$GPGSV,3,2,12,11,36,285,34,14,45,118,32,03,31,183,19,28,,,31*40 +$GPGSV,3,3,12,22,47,070,40,15,,,22,06,26,174,31,26,44,080,36*45 +$GPGLL,5546.67914,N,02334.48657,E,143327.00,A,A*68 +$GPZDA,143327.00,09,12,2009,00,00*67 +$GPRMC,143327.50,A,5546.67528,N,02334.48042,E,37.526,221.60,091209,,,A*5A +$GPVTG,221.60,T,,M,37.526,N,69.535,K,A*33 +$GPGGA,143327.50,5546.67528,N,02334.48042,E,1,09,1.48,121.7,M,27.0,M,,*5D +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.66,1.48,3.35*0D +$GPGSV,4,1,14,32,22,228,30,27,,,30,09,12,037,25,12,,,33*7F +$GPGSV,4,2,14,19,58,204,37,11,36,285,33,14,45,118,32,03,31,183,18*78 +$GPGSV,4,3,14,28,,,30,22,47,070,39,15,,,24,06,26,174,30*7D +$GPGSV,4,4,14,26,44,080,36,17,,,34*44 +$GPGLL,5546.67528,N,02334.48042,E,143327.50,A,A*6C +$GPZDA,143327.50,09,12,2009,00,00*62 +$GPRMC,143328.00,A,5546.67138,N,02334.47421,E,37.918,221.73,091209,,,A*58 +$GPVTG,221.73,T,,M,37.918,N,70.262,K,A*3D +$GPGGA,143328.00,5546.67138,N,02334.47421,E,1,09,1.19,121.7,M,27.0,M,,*58 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.23,1.19,3.00*0E +$GPGSV,4,1,14,32,22,228,29,27,,,29,09,12,037,25,12,,,32*7E +$GPGSV,4,2,14,19,58,204,37,11,36,285,33,14,45,118,32,03,31,183,19*79 +$GPGSV,4,3,14,28,,,29,22,47,070,38,15,,,24,06,26,174,29*7C +$GPGSV,4,4,14,26,44,080,36,17,,,33*43 +$GPGLL,5546.67138,N,02334.47421,E,143328.00,A,A*6D +$GPZDA,143328.00,09,12,2009,00,00*68 +$GPRMC,143328.50,A,5546.66742,N,02334.46793,E,38.036,221.73,091209,,,A*56 +$GPVTG,221.73,T,,M,38.036,N,70.482,K,A*3F +$GPGGA,143328.50,5546.66742,N,02334.46793,E,1,09,1.19,121.8,M,27.0,M,,*53 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.23,1.19,3.00*0E +$GPGSV,3,1,10,32,22,228,30,09,12,037,25,19,58,204,38,11,36,285,34*7C +$GPGSV,3,2,10,14,45,118,33,03,31,183,23,28,,,30,22,47,070,40*46 +$GPGSV,3,3,10,06,26,174,30,26,44,080,37*73 +$GPGLL,5546.66742,N,02334.46793,E,143328.50,A,A*69 +$GPZDA,143328.50,09,12,2009,00,00*6D +$GPRMC,143329.00,A,5546.66350,N,02334.46164,E,38.567,221.88,091209,,,A*5E +$GPVTG,221.88,T,,M,38.567,N,71.465,K,A*32 +$GPGGA,143329.00,5546.66350,N,02334.46164,E,1,09,1.19,121.8,M,27.0,M,,*5E +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.23,1.19,3.00*0E +$GPGSV,3,1,10,32,22,228,30,09,12,037,26,19,58,204,39,11,36,285,35*7F +$GPGSV,3,2,10,14,45,118,33,03,31,183,25,28,,,30,22,47,070,41*41 +$GPGSV,3,3,10,06,26,174,32,26,44,080,37*71 +$GPGLL,5546.66350,N,02334.46164,E,143329.00,A,A*64 +$GPZDA,143329.00,09,12,2009,00,00*69 +$GPRMC,143329.50,A,5546.65952,N,02334.45524,E,38.642,222.07,091209,,,A*53 +$GPVTG,222.07,T,,M,38.642,N,71.604,K,A*37 +$GPGGA,143329.50,5546.65952,N,02334.45524,E,1,09,1.28,121.9,M,27.0,M,,*50 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.65,1.28,3.41*0B +$GPGSV,3,1,10,32,22,228,30,09,12,037,26,19,58,204,39,11,36,285,34*7E +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,,,30,22,47,070,41*4C +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.65952,N,02334.45524,E,143329.50,A,A*69 +$GPZDA,143329.50,09,12,2009,00,00*6C +$GPRMC,143330.00,A,5546.65551,N,02334.44882,E,38.917,221.88,091209,,,A*5A +$GPVTG,221.88,T,,M,38.917,N,72.112,K,A*3F +$GPGGA,143330.00,5546.65551,N,02334.44882,E,1,09,1.28,121.9,M,27.0,M,,*52 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.64,1.28,3.41*0A +$GPGSV,3,1,10,32,22,228,31,09,12,037,26,19,58,204,39,11,36,285,35*7E +$GPGSV,3,2,10,14,45,118,33,03,31,183,24,28,,,31,22,47,070,41*41 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.65551,N,02334.44882,E,143330.00,A,A*6B +$GPZDA,143330.00,09,12,2009,00,00*61 +$GPRMC,143330.50,A,5546.65146,N,02334.44238,E,39.222,221.56,091209,,,A*59 +$GPVTG,221.56,T,,M,39.222,N,72.679,K,A*3A +$GPGGA,143330.50,5546.65146,N,02334.44238,E,1,09,1.28,122.0,M,27.0,M,,*54 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.64,1.28,3.41*0A +$GPGSV,3,1,10,32,22,228,33,09,12,037,26,19,58,204,39,11,36,285,35*7C +$GPGSV,3,2,10,14,45,118,33,03,31,183,20,28,,,31,22,47,070,41*45 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.65146,N,02334.44238,E,143330.50,A,A*67 +$GPZDA,143330.50,09,12,2009,00,00*64 +$GPRMC,143331.00,A,5546.64738,N,02334.43592,E,39.384,221.52,091209,,,A*5A +$GPVTG,221.52,T,,M,39.384,N,72.979,K,A*3C +$GPGGA,143331.00,5546.64738,N,02334.43592,E,1,09,1.26,122.1,M,27.0,M,,*51 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,33,09,12,037,26,19,58,204,39,11,36,285,34*7D +$GPGSV,3,2,10,14,45,118,34,03,31,183,20,28,,,31,22,47,070,41*42 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.64738,N,02334.43592,E,143331.00,A,A*6D +$GPZDA,143331.00,09,12,2009,00,00*60 +$GPRMC,143331.50,A,5546.64328,N,02334.42943,E,39.571,221.47,091209,,,A*53 +$GPVTG,221.47,T,,M,39.571,N,73.325,K,A*36 +$GPGGA,143331.50,5546.64328,N,02334.42943,E,1,09,1.26,122.2,M,27.0,M,,*53 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.00*07 +$GPGSV,3,1,10,32,22,228,32,09,12,037,26,19,58,203,39,11,36,285,35*7A +$GPGSV,3,2,10,14,45,118,33,03,31,183,19,28,,,31,22,47,070,41*4F +$GPGSV,3,3,10,06,26,174,31,26,44,080,37*72 +$GPGLL,5546.64328,N,02334.42943,E,143331.50,A,A*6C +$GPZDA,143331.50,09,12,2009,00,00*65 +$GPRMC,143332.00,A,5546.63918,N,02334.42294,E,39.806,221.51,091209,,,A*50 +$GPVTG,221.51,T,,M,39.806,N,73.761,K,A*38 +$GPGGA,143332.00,5546.63918,N,02334.42294,E,1,09,1.26,122.3,M,27.0,M,,*5B +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.00*07 +$GPGSV,3,1,10,32,22,228,32,09,12,037,26,19,58,203,38,11,36,285,33*7D +$GPGSV,3,2,10,14,45,118,33,03,31,183,19,28,,,30,22,47,070,40*4F +$GPGSV,3,3,10,06,26,174,31,26,44,080,37*72 +$GPGLL,5546.63918,N,02334.42294,E,143332.00,A,A*65 +$GPZDA,143332.00,09,12,2009,00,00*63 +$GPRMC,143332.50,A,5546.63505,N,02334.41641,E,39.985,221.44,091209,,,A*54 +$GPVTG,221.44,T,,M,39.985,N,74.092,K,A*3A +$GPGGA,143332.50,5546.63505,N,02334.41641,E,1,09,1.26,122.4,M,27.0,M,,*56 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,32,09,12,037,26,19,58,203,38,11,36,285,32*7C +$GPGSV,3,2,10,14,45,118,32,03,31,183,19,28,,,30,22,47,070,40*4E +$GPGSV,3,3,10,06,26,174,31,26,44,080,36*73 +$GPGLL,5546.63505,N,02334.41641,E,143332.50,A,A*6F +$GPZDA,143332.50,09,12,2009,00,00*66 +$GPRMC,143333.00,A,5546.63089,N,02334.40987,E,40.143,221.52,091209,,,A*5E +$GPVTG,221.52,T,,M,40.143,N,74.385,K,A*34 +$GPGGA,143333.00,5546.63089,N,02334.40987,E,1,09,1.26,122.6,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.00*07 +$GPGSV,3,1,10,32,22,228,31,09,12,037,26,19,58,203,38,11,36,285,32*7F +$GPGSV,3,2,10,14,45,118,32,03,31,183,19,28,,,30,22,47,070,40*4E +$GPGSV,3,3,10,06,26,174,31,26,44,080,36*73 +$GPGLL,5546.63089,N,02334.40987,E,143333.00,A,A*6E +$GPZDA,143333.00,09,12,2009,00,00*62 +$GPRMC,143333.50,A,5546.62673,N,02334.40329,E,40.300,221.56,091209,,,A*56 +$GPVTG,221.56,T,,M,40.300,N,74.676,K,A*3C +$GPGGA,143333.50,5546.62673,N,02334.40329,E,1,09,1.26,122.7,M,27.0,M,,*5D +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,40,11,36,285,34*75 +$GPGSV,3,2,10,14,45,118,34,03,31,183,19,28,,,31,22,47,070,42*4B +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.62673,N,02334.40329,E,143333.50,A,A*67 +$GPZDA,143333.50,09,12,2009,00,00*67 +$GPRMC,143334.00,A,5546.62247,N,02334.39671,E,40.502,221.59,091209,,,A*5A +$GPVTG,221.59,T,,M,40.502,N,75.050,K,A*34 +$GPGGA,143334.00,5546.62247,N,02334.39671,E,1,09,1.26,122.5,M,27.0,M,,*58 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,40,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,35,03,31,183,20,28,,,31,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +$GPGLL,5546.62247,N,02334.39671,E,143334.00,A,A*60 +$GPZDA,143334.00,09,12,2009,00,00*65 +$GPRMC,143334.50,A,5546.61820,N,02334.39009,E,40.736,221.63,091209,,,A*52 +$GPVTG,221.63,T,,M,40.736,N,75.483,K,A*32 +$GPGGA,143334.50,5546.61820,N,02334.39009,E,1,09,1.26,122.4,M,27.0,M,,*5D +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,40,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,20,28,,,31,22,47,070,42*41 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.61820,N,02334.39009,E,143334.50,A,A*64 +$GPZDA,143334.50,09,12,2009,00,00*60 +$GPRMC,143335.00,A,5546.61392,N,02334.38340,E,40.981,221.79,091209,,,A*52 +$GPVTG,221.79,T,,M,40.981,N,75.938,K,A*36 +$GPGGA,143335.00,5546.61392,N,02334.38340,E,1,09,1.26,122.3,M,27.0,M,,*53 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,32,09,12,037,27,19,58,203,40,11,36,285,35*75 +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,,,32,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.61392,N,02334.38340,E,143335.00,A,A*6D +$GPZDA,143335.00,09,12,2009,00,00*64 +$GPRMC,143335.50,A,5546.60964,N,02334.37668,E,41.196,221.79,091209,,,A*5A +$GPVTG,221.79,T,,M,41.196,N,76.336,K,A*3E +$GPGGA,143335.50,5546.60964,N,02334.37668,E,1,09,1.26,122.3,M,27.0,M,,*54 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,33,09,12,037,28,19,58,203,40,11,36,285,36*78 +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,,,33,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.60964,N,02334.37668,E,143335.50,A,A*6A +$GPZDA,143335.50,09,12,2009,00,00*61 +$GPRMC,143336.00,A,5546.60535,N,02334.36991,E,41.361,221.94,091209,,,A*55 +$GPVTG,221.94,T,,M,41.361,N,76.642,K,A*31 +$GPGGA,143336.00,5546.60535,N,02334.36991,E,1,09,1.26,122.3,M,27.0,M,,*52 +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.00*07 +$GPGSV,3,1,10,32,22,228,33,09,12,037,28,19,58,203,40,11,36,285,35*7B +$GPGSV,3,2,10,14,45,118,34,03,31,183,25,28,,,34,22,47,070,42*41 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.60535,N,02334.36991,E,143336.00,A,A*6C +$GPZDA,143336.00,09,12,2009,00,00*67 +$GPRMC,143336.50,A,5546.60106,N,02334.36309,E,41.477,221.87,091209,,,A*5D +$GPVTG,221.87,T,,M,41.477,N,76.857,K,A*39 +$GPGGA,143336.50,5546.60106,N,02334.36309,E,1,10,1.01,122.3,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,40,11,36,285,36*79 +$GPGSV,3,2,10,14,45,118,34,03,31,183,27,28,19,317,34,22,47,070,42*7E +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.60106,N,02334.36309,E,143336.50,A,A*66 +$GPZDA,143336.50,09,12,2009,00,00*62 +$GPRMC,143337.00,A,5546.59676,N,02334.35625,E,41.577,221.77,091209,,,A*55 +$GPVTG,221.77,T,,M,41.577,N,77.043,K,A*3B +$GPGGA,143337.00,5546.59676,N,02334.35625,E,1,10,1.01,122.3,M,27.0,M,,*53 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,40,11,36,285,35*7A +$GPGSV,3,2,10,14,45,118,35,03,31,183,27,28,19,317,33,22,47,070,42*78 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.59676,N,02334.35625,E,143337.00,A,A*60 +$GPZDA,143337.00,09,12,2009,00,00*66 +$GPRMC,143337.50,A,5546.59244,N,02334.34942,E,41.633,221.86,091209,,,A*57 +$GPVTG,221.86,T,,M,41.633,N,77.146,K,A*32 +$GPGGA,143337.50,5546.59244,N,02334.34942,E,1,10,1.01,122.3,M,27.0,M,,*5C +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,39,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,19,317,32,22,47,070,41*78 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.59244,N,02334.34942,E,143337.50,A,A*6F +$GPZDA,143337.50,09,12,2009,00,00*63 +$GPRMC,143338.00,A,5546.58812,N,02334.34258,E,41.700,221.99,091209,,,A*5A +$GPVTG,221.99,T,,M,41.700,N,77.270,K,A*3B +$GPGGA,143338.00,5546.58812,N,02334.34258,E,1,10,1.01,122.3,M,27.0,M,,*5E +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,39,11,36,285,35*77 +$GPGSV,3,2,10,14,45,118,34,03,31,183,27,28,19,317,34,22,47,070,41*7D +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.58812,N,02334.34258,E,143338.00,A,A*6D +$GPZDA,143338.00,09,12,2009,00,00*69 +$GPRMC,143338.50,A,5546.58377,N,02334.33571,E,41.763,222.02,091209,,,A*58 +$GPVTG,222.02,T,,M,41.763,N,77.387,K,A*36 +$GPGGA,143338.50,5546.58377,N,02334.33571,E,1,10,1.01,122.2,M,27.0,M,,*59 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,39,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,34,03,31,183,27,28,19,317,34,22,47,070,42*7E +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.58377,N,02334.33571,E,143338.50,A,A*6B +$GPZDA,143338.50,09,12,2009,00,00*6C +$GPRMC,143339.00,A,5546.57941,N,02334.32886,E,41.810,221.70,091209,,,A*55 +$GPVTG,221.70,T,,M,41.810,N,77.474,K,A*30 +$GPGGA,143339.00,5546.57941,N,02334.32886,E,1,10,1.01,122.2,M,27.0,M,,*59 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,39,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,34,03,31,183,27,28,19,317,34,22,47,070,42*7E +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.57941,N,02334.32886,E,143339.00,A,A*6B +$GPZDA,143339.00,09,12,2009,00,00*68 +$GPRMC,143339.50,A,5546.57509,N,02334.32202,E,41.805,221.61,091209,,,A*52 +$GPVTG,221.61,T,,M,41.805,N,77.464,K,A*35 +$GPGGA,143339.50,5546.57509,N,02334.32202,E,1,10,1.22,122.4,M,27.0,M,,*5D +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.23,1.22,2.99*0D +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,40,11,36,285,36*79 +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,19,317,34,22,47,070,42*7C +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +$GPGLL,5546.57509,N,02334.32202,E,143339.50,A,A*68 +$GPZDA,143339.50,09,12,2009,00,00*6D +$GPRMC,143340.00,A,5546.57072,N,02334.31519,E,41.831,221.43,091209,,,A*59 +$GPVTG,221.43,T,,M,41.831,N,77.512,K,A*32 +$GPGGA,143340.00,5546.57072,N,02334.31519,E,1,10,1.01,122.4,M,27.0,M,,*50 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,27,19,58,203,40,11,36,285,35*75 +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,19,317,32,22,47,070,42*7A +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +$GPGLL,5546.57072,N,02334.31519,E,143340.00,A,A*64 +$GPZDA,143340.00,09,12,2009,00,00*66 +$GPRMC,143340.50,A,5546.56636,N,02334.30835,E,41.860,221.62,091209,,,A*5E +$GPVTG,221.62,T,,M,41.860,N,77.566,K,A*36 +$GPGGA,143340.50,5546.56636,N,02334.30835,E,1,10,1.01,122.3,M,27.0,M,,*57 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,39,11,36,285,35*7A +$GPGSV,3,2,10,14,45,118,34,03,31,183,23,28,19,317,32,22,47,070,41*7F +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +$GPGLL,5546.56636,N,02334.30835,E,143340.50,A,A*64 +$GPZDA,143340.50,09,12,2009,00,00*63 +$GPRMC,143341.00,A,5546.56202,N,02334.30147,E,41.947,221.64,091209,,,A*57 +$GPVTG,221.64,T,,M,41.947,N,77.727,K,A*33 +$GPGGA,143341.00,5546.56202,N,02334.30147,E,1,10,1.01,122.4,M,27.0,M,,*5B +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,40,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,19,317,33,22,47,070,41*79 +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +$GPGLL,5546.56202,N,02334.30147,E,143341.00,A,A*6F +$GPZDA,143341.00,09,12,2009,00,00*67 +$GPRMC,143341.50,A,5546.55766,N,02334.29457,E,41.998,221.76,091209,,,A*5B +$GPVTG,221.76,T,,M,41.998,N,77.822,K,A*38 +$GPGGA,143341.50,5546.55766,N,02334.29457,E,1,10,1.01,122.3,M,27.0,M,,*51 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,40,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,19,317,35,22,47,070,42*7C +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.55766,N,02334.29457,E,143341.50,A,A*62 +$GPZDA,143341.50,09,12,2009,00,00*62 +$GPRMC,143342.00,A,5546.55331,N,02334.28765,E,42.085,221.64,091209,,,A*5D +$GPVTG,221.64,T,,M,42.085,N,77.984,K,A*30 +$GPGGA,143342.00,5546.55331,N,02334.28765,E,1,10,1.01,122.4,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,34,09,12,037,27,19,58,203,40,11,36,285,35*73 +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,19,317,34,22,47,070,42*7C +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +$GPGLL,5546.55331,N,02334.28765,E,143342.00,A,A*61 +$GPZDA,143342.00,09,12,2009,00,00*64 +$GPRMC,143342.50,A,5546.54894,N,02334.28072,E,42.096,221.79,091209,,,A*52 +$GPVTG,221.79,T,,M,42.096,N,78.004,K,A*30 +$GPGGA,143342.50,5546.54894,N,02334.28072,E,1,10,1.01,122.4,M,27.0,M,,*54 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,34,09,12,037,27,19,58,203,39,11,36,285,35*7D +$GPGSV,3,2,10,14,45,118,34,03,31,183,26,28,19,317,33,22,47,070,41*7B +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.54894,N,02334.28072,E,143342.50,A,A*60 +$GPZDA,143342.50,09,12,2009,00,00*61 +$GPRMC,143343.00,A,5546.54457,N,02334.27380,E,42.128,221.81,091209,,,A*57 +$GPVTG,221.81,T,,M,42.128,N,78.064,K,A*35 +$GPGGA,143343.00,5546.54457,N,02334.27380,E,1,10,1.01,122.4,M,27.0,M,,*52 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,34,09,12,037,27,19,58,203,39,11,36,285,35*7D +$GPGSV,3,2,10,14,45,118,34,03,31,183,26,28,19,317,32,22,47,070,41*7A +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.54457,N,02334.27380,E,143343.00,A,A*66 +$GPZDA,143343.00,09,12,2009,00,00*65 +$GPRMC,143343.50,A,5546.54019,N,02334.26687,E,42.223,221.67,091209,,,A*5F +$GPVTG,221.67,T,,M,42.223,N,78.240,K,A*31 +$GPGGA,143343.50,5546.54019,N,02334.26687,E,1,10,1.26,122.5,M,27.0,M,,*5E +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,34,09,12,037,27,19,58,203,39,11,36,285,35*7D +$GPGSV,3,2,10,14,45,118,34,03,31,183,23,28,19,317,31,22,47,070,41*7C +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.54019,N,02334.26687,E,143343.50,A,A*6E +$GPZDA,143343.50,09,12,2009,00,00*60 +$GPRMC,143344.00,A,5546.53579,N,02334.25993,E,42.261,221.65,091209,,,A*54 +$GPVTG,221.65,T,,M,42.261,N,78.309,K,A*39 +$GPGGA,143344.00,5546.53579,N,02334.25993,E,1,10,1.01,122.4,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,39,11,36,285,34*7B +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,19,317,32,22,47,070,41*78 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.53579,N,02334.25993,E,143344.00,A,A*61 +$GPZDA,143344.00,09,12,2009,00,00*62 +$GPRMC,143344.50,A,5546.53138,N,02334.25301,E,42.303,221.61,091209,,,A*50 +$GPVTG,221.61,T,,M,42.303,N,78.388,K,A*31 +$GPGGA,143344.50,5546.53138,N,02334.25301,E,1,10,1.01,122.3,M,27.0,M,,*57 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,39,11,36,285,34*7B +$GPGSV,3,2,10,14,45,118,34,03,31,183,28,28,19,317,32,22,47,070,41*74 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.53138,N,02334.25301,E,143344.50,A,A*64 +$GPZDA,143344.50,09,12,2009,00,00*67 +$GPRMC,143345.00,A,5546.52698,N,02334.24607,E,42.393,221.82,091209,,,A*5E +$GPVTG,221.82,T,,M,42.393,N,78.553,K,A*35 +$GPGGA,143345.00,5546.52698,N,02334.24607,E,1,10,1.01,122.2,M,27.0,M,,*5C +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,39,11,36,285,33*72 +$GPGSV,3,2,10,14,45,118,34,03,31,183,28,28,19,317,31,22,47,070,41*77 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.52698,N,02334.24607,E,143345.00,A,A*6E +$GPZDA,143345.00,09,12,2009,00,00*63 +$GPRMC,143345.50,A,5546.52259,N,02334.23909,E,42.434,221.88,091209,,,A*54 +$GPVTG,221.88,T,,M,42.434,N,78.630,K,A*33 +$GPGGA,143345.50,5546.52259,N,02334.23909,E,1,10,1.01,122.1,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,27,19,58,203,39,11,36,285,32*7C +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,31,22,47,070,41*70 +$GPGSV,3,3,10,06,26,174,32,26,44,080,37*71 +$GPGLL,5546.52259,N,02334.23909,E,143345.50,A,A*64 +$GPZDA,143345.50,09,12,2009,00,00*66 +$GPRMC,143346.00,A,5546.51820,N,02334.23212,E,42.324,221.82,091209,,,A*58 +$GPVTG,221.82,T,,M,42.324,N,78.426,K,A*3A +$GPGGA,143346.00,5546.51820,N,02334.23212,E,1,10,1.26,122.2,M,27.0,M,,*53 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,27,19,58,203,38,11,36,285,32*7E +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,30,22,47,070,40*70 +$GPGSV,3,3,10,06,26,174,32,26,44,080,37*71 +$GPGLL,5546.51820,N,02334.23212,E,143346.00,A,A*64 +$GPZDA,143346.00,09,12,2009,00,00*60 +$GPRMC,143346.50,A,5546.51382,N,02334.22519,E,42.016,221.97,091209,,,A*55 +$GPVTG,221.97,T,,M,42.016,N,77.855,K,A*3B +$GPGGA,143346.50,5546.51382,N,02334.22519,E,1,10,1.26,122.2,M,27.0,M,,*58 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,30,09,12,037,28,19,58,203,39,11,36,285,33*70 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,30,22,47,070,40*70 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.51382,N,02334.22519,E,143346.50,A,A*6F +$GPZDA,143346.50,09,12,2009,00,00*65 +$GPRMC,143347.00,A,5546.50947,N,02334.21831,E,41.750,221.78,091209,,,A*50 +$GPVTG,221.78,T,,M,41.750,N,77.363,K,A*32 +$GPGGA,143347.00,5546.50947,N,02334.21831,E,1,10,1.26,122.2,M,27.0,M,,*5A +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,39,11,36,285,33*71 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,30,22,47,070,41*71 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.50947,N,02334.21831,E,143347.00,A,A*6D +$GPZDA,143347.00,09,12,2009,00,00*61 +$GPRMC,143347.50,A,5546.50515,N,02334.21149,E,41.450,221.70,091209,,,A*53 +$GPVTG,221.70,T,,M,41.450,N,76.806,K,A*30 +$GPGGA,143347.50,5546.50515,N,02334.21149,E,1,10,1.90,122.2,M,27.0,M,,*5F +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.58,1.90,3.04*0D +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,39,11,36,285,33*71 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,30,22,47,070,40*70 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.50515,N,02334.21149,E,143347.50,A,A*65 +$GPZDA,143347.50,09,12,2009,00,00*64 +$GPRMC,143348.00,A,5546.50086,N,02334.20472,E,41.139,221.46,091209,,,A*55 +$GPVTG,221.46,T,,M,41.139,N,76.231,K,A*31 +$GPGGA,143348.00,5546.50086,N,02334.20472,E,1,10,1.26,122.2,M,27.0,M,,*5B +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,30,09,12,037,27,19,58,203,38,11,36,285,33*7E +$GPGSV,3,2,10,14,45,118,33,03,31,183,27,28,19,317,30,22,47,070,41*7E +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.50086,N,02334.20472,E,143348.00,A,A*6C +$GPZDA,143348.00,09,12,2009,00,00*6E +$GPRMC,143348.50,A,5546.49657,N,02334.19806,E,40.840,221.86,091209,,,A*5D +$GPVTG,221.86,T,,M,40.840,N,75.676,K,A*3F +$GPGGA,143348.50,5546.49657,N,02334.19806,E,1,10,1.26,122.2,M,27.0,M,,*59 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,38,11,36,285,33*70 +$GPGSV,3,2,10,14,45,118,33,03,31,183,27,28,19,317,30,22,47,070,40*7F +$GPGSV,3,3,10,06,26,174,32,26,44,080,37*71 +$GPGLL,5546.49657,N,02334.19806,E,143348.50,A,A*6E +$GPZDA,143348.50,09,12,2009,00,00*6B +$GPRMC,143349.00,A,5546.49236,N,02334.19138,E,40.570,221.54,091209,,,A*5F +$GPVTG,221.54,T,,M,40.570,N,75.176,K,A*39 +$GPGGA,143349.00,5546.49236,N,02334.19138,E,1,10,1.26,122.3,M,27.0,M,,*5B +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,39,11,36,285,34*76 +$GPGSV,3,2,10,14,45,118,32,03,31,183,28,28,19,317,30,22,47,070,41*70 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.49236,N,02334.19138,E,143349.00,A,A*6D +$GPZDA,143349.00,09,12,2009,00,00*6F +$GPRMC,143349.50,A,5546.48814,N,02334.18482,E,40.283,221.44,091209,,,A*5E +$GPVTG,221.44,T,,M,40.283,N,74.645,K,A*35 +$GPGGA,143349.50,5546.48814,N,02334.18482,E,1,10,1.26,122.3,M,27.0,M,,*50 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,27,19,58,203,39,11,36,285,34*79 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,30,22,47,070,41*71 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.48814,N,02334.18482,E,143349.50,A,A*66 +$GPZDA,143349.50,09,12,2009,00,00*6A +$GPRMC,143350.00,A,5546.48395,N,02334.17830,E,39.946,221.60,091209,,,A*51 +$GPVTG,221.60,T,,M,39.946,N,74.020,K,A*3A +$GPGGA,143350.00,5546.48395,N,02334.17830,E,1,10,1.26,122.3,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,27,19,58,203,39,11,36,285,34*79 +$GPGSV,3,2,10,14,45,118,32,03,31,183,27,28,19,317,30,22,47,070,41*7F +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +$GPGLL,5546.48395,N,02334.17830,E,143350.00,A,A*63 +$GPZDA,143350.00,09,12,2009,00,00*67 +$GPRMC,143350.50,A,5546.47981,N,02334.17183,E,39.607,221.50,091209,,,A*5C +$GPVTG,221.50,T,,M,39.607,N,73.391,K,A*3D +$GPGGA,143350.50,5546.47981,N,02334.17183,E,1,10,1.26,122.4,M,27.0,M,,*56 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,27,19,58,203,38,11,36,285,33*7F +$GPGSV,3,2,10,14,45,118,32,03,31,183,28,28,19,317,29,22,47,070,40*79 +$GPGSV,3,3,10,06,25,174,32,26,44,080,38*7D +$GPGLL,5546.47981,N,02334.17183,E,143350.50,A,A*67 +$GPZDA,143350.50,09,12,2009,00,00*62 +$GPRMC,143351.00,A,5546.47570,N,02334.16543,E,39.198,221.80,091209,,,A*5F +$GPVTG,221.80,T,,M,39.198,N,72.634,K,A*3A +$GPGGA,143351.00,5546.47570,N,02334.16543,E,1,10,1.26,122.5,M,27.0,M,,*58 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,32,09,12,037,27,19,58,203,38,11,36,285,33*7C +$GPGSV,3,2,10,14,45,118,32,03,31,183,27,28,19,317,29,22,47,070,40*76 +$GPGSV,3,3,10,06,25,174,33,26,44,080,38*7C +$GPGLL,5546.47570,N,02334.16543,E,143351.00,A,A*68 +$GPZDA,143351.00,09,12,2009,00,00*66 +$GPRMC,143351.50,A,5546.47167,N,02334.15908,E,38.658,221.91,091209,,,A*52 +$GPVTG,221.91,T,,M,38.658,N,71.633,K,A*34 +$GPGGA,143351.50,5546.47167,N,02334.15908,E,1,10,1.26,122.6,M,27.0,M,,*5C +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,38,11,36,285,33*73 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,29,22,47,070,40*78 +$GPGSV,3,3,10,06,25,174,33,26,44,080,38*7C +$GPGLL,5546.47167,N,02334.15908,E,143351.50,A,A*6F +$GPZDA,143351.50,09,12,2009,00,00*63 +$GPRMC,143352.00,A,5546.46768,N,02334.15280,E,38.178,222.25,091209,,,A*5E +$GPVTG,222.25,T,,M,38.178,N,70.744,K,A*3D +$GPGGA,143352.00,5546.46768,N,02334.15280,E,1,10,1.25,122.7,M,27.0,M,,*5B +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.25,3.01*0F +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,38,11,36,285,34*74 +$GPGSV,3,2,10,14,45,118,32,03,31,183,28,28,19,317,29,22,47,070,40*79 +$GPGSV,3,3,10,06,25,174,33,26,44,080,38*7C +$GPGLL,5546.46768,N,02334.15280,E,143352.00,A,A*6A +$GPZDA,143352.00,09,12,2009,00,00*65 +$GPRMC,143352.50,A,5546.46376,N,02334.14654,E,37.932,221.95,091209,,,A*5D +$GPVTG,221.95,T,,M,37.932,N,70.288,K,A*39 +$GPGGA,143352.50,5546.46376,N,02334.14654,E,1,10,1.26,122.8,M,27.0,M,,*55 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,30,09,12,037,28,19,58,203,38,11,36,285,34*76 +$GPGSV,3,2,10,14,45,118,32,03,31,183,28,28,19,317,29,22,47,070,40*79 +$GPGSV,3,3,10,06,25,174,33,26,44,080,38*7C +$GPGLL,5546.46376,N,02334.14654,E,143352.50,A,A*68 +$GPZDA,143352.50,09,12,2009,00,00*60 +$GPRMC,143353.00,A,5546.45986,N,02334.14036,E,37.561,221.99,091209,,,A*5B +$GPVTG,221.99,T,,M,37.561,N,69.601,K,A*32 +$GPGGA,143353.00,5546.45986,N,02334.14036,E,1,10,1.26,123.0,M,27.0,M,,*5C +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,38,11,36,285,33*70 +$GPGSV,3,2,10,14,45,118,32,03,31,183,29,28,19,317,29,22,47,070,40*78 +$GPGSV,3,3,10,06,25,174,33,26,44,080,38*7C +$GPGLL,5546.45986,N,02334.14036,E,143353.00,A,A*68 +$GPZDA,143353.00,09,12,2009,00,00*64 +$GPRMC,143353.50,A,5546.45601,N,02334.13425,E,36.999,221.72,091209,,,A*50 +$GPVTG,221.72,T,,M,36.999,N,68.559,K,A*32 +$GPGGA,143353.50,5546.45601,N,02334.13425,E,1,10,1.26,123.1,M,27.0,M,,*59 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,38,11,36,285,33*73 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,29,22,47,070,40*78 +$GPGSV,3,3,10,06,25,174,32,26,44,080,38*7D +$GPGLL,5546.45601,N,02334.13425,E,143353.50,A,A*6C +$GPZDA,143353.50,09,12,2009,00,00*61 +$GPRMC,143354.00,A,5546.45220,N,02334.12827,E,36.320,221.89,091209,,,A*56 +$GPVTG,221.89,T,,M,36.320,N,67.300,K,A*3B +$GPGGA,143354.00,5546.45220,N,02334.12827,E,1,10,1.26,123.3,M,27.0,M,,*51 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,38,11,36,285,33*70 +$GPGSV,3,2,10,14,45,118,32,03,31,183,28,28,19,317,29,22,47,070,40*79 +$GPGSV,3,3,10,06,25,174,32,26,44,080,38*7D +$GPGLL,5546.45220,N,02334.12827,E,143354.00,A,A*66 +$GPZDA,143354.00,09,12,2009,00,00*63 +$GPRMC,143354.50,A,5546.44845,N,02334.12240,E,35.710,221.48,091209,,,A*59 +$GPVTG,221.48,T,,M,35.710,N,66.170,K,A*36 +$GPGGA,143354.50,5546.44845,N,02334.12240,E,1,10,1.26,123.5,M,27.0,M,,*51 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,38,11,36,285,34*77 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,29,22,47,070,40*78 +$GPGSV,3,3,10,06,25,174,32,26,44,080,37*72 +$GPGLL,5546.44845,N,02334.12240,E,143354.50,A,A*60 +$GPZDA,143354.50,09,12,2009,00,00*66 +$GPRMC,143355.00,A,5546.44478,N,02334.11667,E,34.871,221.47,091209,,,A*5B +$GPVTG,221.47,T,,M,34.871,N,64.615,K,A*36 +$GPGGA,143355.00,5546.44478,N,02334.11667,E,1,10,1.25,123.5,M,27.0,M,,*56 +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.25,3.01*0F +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,38,11,36,285,34*74 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,29,22,47,070,40*78 +$GPGSV,3,3,10,06,25,174,32,26,44,080,38*7D +$GPGLL,5546.44478,N,02334.11667,E,143355.00,A,A*64 +$GPZDA,143355.00,09,12,2009,00,00*62 diff --git a/test/daemon/bt451.log.chk b/test/daemon/bt451.log.chk new file mode 100644 index 0000000..13d9fc6 --- /dev/null +++ b/test/daemon/bt451.log.chk @@ -0,0 +1,1355 @@ +$GPTXT,01,01,02,u-blox ag - www.u-blox.com*50 +$GPTXT,01,01,02,ANTARIS ATR062x HW 80040001*26 +$GPTXT,01,01,02,ROM CORE 5.00 Jan 09 2006 12:00:00*76 +$GPTXT,01,01,02,LIC 1EBF-BD07-E83D-6BE1-0F7A*50 +$GPTXT,01,01,02,ANTSUPERV=AC SD OD PDoS *0A +$GPTXT,01,01,02,ANTSTATUS=OK*3B +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,,V,,,,,,,,,,N*53 +$GPVTG,,,,,,,,,N*30 +$GPGGA,,,,,,0,00,99.99,,,,,,*48 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,00*79 +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPGLL,5547.82107,N,02334.14132,E,152504.50,A,A*67 +{"class":"TPV","tag":"GLL","lat":55.797017833,"lon":23.569022000,"mode":2} +$GPZDA,152504.50,09,12,2009,00,00*65 +$GPRMC,152505.00,A,5547.82113,N,02334.14130,E,0.253,,091209,,,A*7A +$GPVTG,,T,,M,0.253,N,0.469,K,A*2C +$GPGGA,152505.00,5547.82113,N,02334.14130,E,1,04,2.72,37.0,M,26.9,M,,*6B +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.25,2.72,5.62*05 +$GPGSV,2,1,07,26,34,052,33,19,,,36,32,45,237,42,06,,,34*75 +$GPGSV,2,2,07,22,,,40,11,57,277,40,14,51,083,38*7F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":26,"el":34,"az":52,"ss":33,"used":true},{"PRN":19,"el":0,"az":0,"ss":36,"used":false},{"PRN":32,"el":45,"az":237,"ss":42,"used":true},{"PRN":6,"el":0,"az":0,"ss":34,"used":false},{"PRN":22,"el":0,"az":0,"ss":40,"used":false},{"PRN":11,"el":57,"az":277,"ss":40,"used":true},{"PRN":14,"el":51,"az":83,"ss":38,"used":true}]} +$GPGLL,5547.82113,N,02334.14130,E,152505.00,A,A*64 +{"class":"TPV","tag":"GLL","time":1260372305.000,"ept":0.005,"lat":55.797018833,"lon":23.569021667,"alt":37.000,"epv":129.260,"track":0.0000,"speed":0.130,"climb":0.000,"mode":3} +$GPZDA,152505.00,09,12,2009,00,00*61 +$GPRMC,152505.50,A,5547.82119,N,02334.14124,E,0.265,,091209,,,A*75 +$GPVTG,,T,,M,0.265,N,0.491,K,A*2E +$GPGGA,152505.50,5547.82119,N,02334.14124,E,1,04,2.72,36.7,M,26.9,M,,*67 +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.72,5.62*04 +$GPGSV,2,1,07,26,34,052,34,19,,,36,32,45,237,42,06,,,34*72 +$GPGSV,2,2,07,22,,,40,11,57,277,41,14,51,083,38*7E +{"class":"SKY","tag":"GSV","satellites":[{"PRN":26,"el":34,"az":52,"ss":34,"used":true},{"PRN":19,"el":0,"az":0,"ss":36,"used":false},{"PRN":32,"el":45,"az":237,"ss":42,"used":true},{"PRN":6,"el":0,"az":0,"ss":34,"used":false},{"PRN":22,"el":0,"az":0,"ss":40,"used":false},{"PRN":11,"el":57,"az":277,"ss":41,"used":true},{"PRN":14,"el":51,"az":83,"ss":38,"used":true}]} +$GPGLL,5547.82119,N,02334.14124,E,152505.50,A,A*6E +{"class":"TPV","tag":"GLL","time":1260372305.500,"ept":0.005,"lat":55.797019833,"lon":23.569020667,"alt":36.700,"epv":129.260,"track":0.0000,"speed":0.136,"climb":0.000,"mode":3} +$GPZDA,152505.50,09,12,2009,00,00*64 +$GPRMC,152506.00,A,5547.82126,N,02334.14117,E,0.340,,091209,,,A*79 +$GPVTG,,T,,M,0.340,N,0.631,K,A*20 +$GPGGA,152506.00,5547.82126,N,02334.14117,E,1,04,2.72,36.5,M,26.9,M,,*6F +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.25,2.72,5.62*05 +$GPGSV,2,1,07,26,34,052,34,19,,,37,32,45,237,42,06,,,34*73 +$GPGSV,2,2,07,22,,,40,11,57,277,41,14,51,083,39*7F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":26,"el":34,"az":52,"ss":34,"used":true},{"PRN":19,"el":0,"az":0,"ss":37,"used":false},{"PRN":32,"el":45,"az":237,"ss":42,"used":true},{"PRN":6,"el":0,"az":0,"ss":34,"used":false},{"PRN":22,"el":0,"az":0,"ss":40,"used":false},{"PRN":11,"el":57,"az":277,"ss":41,"used":true},{"PRN":14,"el":51,"az":83,"ss":39,"used":true}]} +$GPGLL,5547.82126,N,02334.14117,E,152506.00,A,A*64 +{"class":"TPV","tag":"GLL","time":1260372306.000,"ept":0.005,"lat":55.797021000,"lon":23.569019500,"alt":36.500,"epv":129.260,"track":0.0000,"speed":0.175,"climb":0.000,"mode":3} +$GPZDA,152506.00,09,12,2009,00,00*62 +$GPRMC,152506.50,A,5547.82132,N,02334.14113,E,0.336,,091209,,,A*7C +$GPVTG,,T,,M,0.336,N,0.623,K,A*22 +$GPGGA,152506.50,5547.82132,N,02334.14113,E,1,04,2.72,36.2,M,26.9,M,,*6C +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.72,5.62*04 +$GPGSV,2,1,07,26,34,052,35,19,,,37,32,45,237,43,06,,,35*72 +$GPGSV,2,2,07,22,,,41,11,57,277,41,14,51,083,39*7E +{"class":"SKY","tag":"GSV","satellites":[{"PRN":26,"el":34,"az":52,"ss":35,"used":true},{"PRN":19,"el":0,"az":0,"ss":37,"used":false},{"PRN":32,"el":45,"az":237,"ss":43,"used":true},{"PRN":6,"el":0,"az":0,"ss":35,"used":false},{"PRN":22,"el":0,"az":0,"ss":41,"used":false},{"PRN":11,"el":57,"az":277,"ss":41,"used":true},{"PRN":14,"el":51,"az":83,"ss":39,"used":true}]} +$GPGLL,5547.82132,N,02334.14113,E,152506.50,A,A*60 +{"class":"TPV","tag":"GLL","time":1260372306.500,"ept":0.005,"lat":55.797022000,"lon":23.569018833,"alt":36.200,"epv":129.260,"track":0.0000,"speed":0.173,"climb":0.000,"mode":3} +$GPZDA,152506.50,09,12,2009,00,00*67 +$GPRMC,152507.00,A,5547.82139,N,02334.14105,E,0.371,16.99,091209,,,A*5E +$GPVTG,16.99,T,,M,0.371,N,0.687,K,A*06 +$GPGGA,152507.00,5547.82139,N,02334.14105,E,1,04,2.72,36.0,M,26.9,M,,*66 +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.72,5.62*04 +$GPGSV,2,1,07,26,34,052,35,19,,,37,32,45,237,42,06,,,35*73 +$GPGSV,2,2,07,22,,,40,11,57,277,41,14,51,083,39*7F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":26,"el":34,"az":52,"ss":35,"used":true},{"PRN":19,"el":0,"az":0,"ss":37,"used":false},{"PRN":32,"el":45,"az":237,"ss":42,"used":true},{"PRN":6,"el":0,"az":0,"ss":35,"used":false},{"PRN":22,"el":0,"az":0,"ss":40,"used":false},{"PRN":11,"el":57,"az":277,"ss":41,"used":true},{"PRN":14,"el":51,"az":83,"ss":39,"used":true}]} +$GPGLL,5547.82139,N,02334.14105,E,152507.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1260372307.000,"ept":0.005,"lat":55.797023167,"lon":23.569017500,"alt":36.000,"epv":129.260,"track":16.9900,"speed":0.191,"climb":0.000,"mode":3} +$GPZDA,152507.00,09,12,2009,00,00*63 +$GPRMC,152507.50,A,5547.82145,N,02334.14098,E,0.309,,091209,,,A*73 +$GPVTG,,T,,M,0.309,N,0.572,K,A*29 +$GPGGA,152507.50,5547.82145,N,02334.14098,E,1,04,2.72,35.7,M,26.9,M,,*69 +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.72,5.62*04 +$GPGSV,2,1,07,26,34,052,35,19,,,37,32,45,237,42,06,,,34*72 +$GPGSV,2,2,07,22,,,40,11,57,277,41,14,51,083,39*7F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":26,"el":34,"az":52,"ss":35,"used":true},{"PRN":19,"el":0,"az":0,"ss":37,"used":false},{"PRN":32,"el":45,"az":237,"ss":42,"used":true},{"PRN":6,"el":0,"az":0,"ss":34,"used":false},{"PRN":22,"el":0,"az":0,"ss":40,"used":false},{"PRN":11,"el":57,"az":277,"ss":41,"used":true},{"PRN":14,"el":51,"az":83,"ss":39,"used":true}]} +$GPGLL,5547.82145,N,02334.14098,E,152507.50,A,A*63 +{"class":"TPV","tag":"GLL","time":1260372307.500,"ept":0.005,"lat":55.797024167,"lon":23.569016333,"alt":35.700,"epv":129.260,"track":0.0000,"speed":0.159,"climb":0.000,"mode":3} +$GPZDA,152507.50,09,12,2009,00,00*66 +$GPRMC,152508.00,A,5547.82150,N,02334.14092,E,0.309,,091209,,,A*77 +$GPVTG,,T,,M,0.309,N,0.573,K,A*28 +$GPGGA,152508.00,5547.82150,N,02334.14092,E,1,04,2.72,35.5,M,26.9,M,,*6F +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.72,5.62*04 +$GPGSV,2,1,07,26,34,052,33,19,,,36,32,45,237,41,06,,,33*71 +$GPGSV,2,2,07,22,,,39,11,57,277,40,14,51,083,38*71 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":26,"el":34,"az":52,"ss":33,"used":true},{"PRN":19,"el":0,"az":0,"ss":36,"used":false},{"PRN":32,"el":45,"az":237,"ss":41,"used":true},{"PRN":6,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":0,"az":0,"ss":39,"used":false},{"PRN":11,"el":57,"az":277,"ss":40,"used":true},{"PRN":14,"el":51,"az":83,"ss":38,"used":true}]} +$GPGLL,5547.82150,N,02334.14092,E,152508.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1260372308.000,"ept":0.005,"lat":55.797025000,"lon":23.569015333,"alt":35.500,"epv":129.260,"track":0.0000,"speed":0.159,"climb":0.000,"mode":3} +$GPZDA,152508.00,09,12,2009,00,00*6C +$GPRMC,152508.50,A,5547.82156,N,02334.14086,E,0.296,,091209,,,A*76 +$GPVTG,,T,,M,0.296,N,0.549,K,A*26 +$GPGGA,152508.50,5547.82156,N,02334.14086,E,1,04,2.73,35.3,M,26.9,M,,*6E +$GPGSA,A,3,26,32,11,14,,,,,,,,,6.24,2.73,5.62*05 +$GPGSV,3,1,11,26,34,052,32,19,,,34,20,,,29,32,45,237,39*74 +$GPGSV,3,2,11,02,,,26,06,,,31,18,,,30,24,,,27*73 +$GPGSV,3,3,11,22,,,37,11,57,277,38,14,51,083,36*79 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":26,"el":34,"az":52,"ss":32,"used":true},{"PRN":19,"el":0,"az":0,"ss":34,"used":false},{"PRN":20,"el":0,"az":0,"ss":29,"used":false},{"PRN":32,"el":45,"az":237,"ss":39,"used":true},{"PRN":2,"el":0,"az":0,"ss":26,"used":false},{"PRN":6,"el":0,"az":0,"ss":31,"used":false},{"PRN":18,"el":0,"az":0,"ss":30,"used":false},{"PRN":24,"el":0,"az":0,"ss":27,"used":false},{"PRN":22,"el":0,"az":0,"ss":37,"used":false},{"PRN":11,"el":57,"az":277,"ss":38,"used":true},{"PRN":14,"el":51,"az":83,"ss":36,"used":true}]} +$GPGGA,143306.00,5546.83315,N,02334.72613,E,1,08,1.28,129.9,M,26.9,M,,*5B +{"class":"TPV","tag":"GGA","time":1260455586.000,"ept":0.005,"lat":55.780552500,"lon":23.578768833,"alt":129.900,"speed":0.023,"climb":0.001,"mode":3} +$GPGSA,A,3,09,19,11,14,03,22,06,26,,,,,3.65,1.28,3.41*0A +$GPGSV,3,1,10,32,22,227,34,09,12,038,29,19,58,204,39,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,30,28,,,32,22,47,070,42*43 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.73,"ydop":0.78,"vdop":1.74,"tdop":0.92,"hdop":1.07,"gdop":2.24,"pdop":2.04,"satellites":[{"PRN":32,"el":22,"az":227,"ss":34,"used":false},{"PRN":9,"el":12,"az":38,"ss":29,"used":true},{"PRN":19,"el":58,"az":204,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":30,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.83315,N,02334.72613,E,143306.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1260455586.000,"ept":0.005,"lat":55.780552500,"lon":23.578768833,"alt":129.900,"epx":10.912,"epy":11.668,"epv":78.430,"speed":0.023,"climb":0.001,"mode":3} +$GPZDA,143306.00,09,12,2009,00,00*64 +$GPRMC,143306.50,A,5546.82983,N,02334.72123,E,30.324,221.16,091209,,,A*52 +$GPVTG,221.16,T,,M,30.324,N,56.191,K,A*37 +$GPGGA,143306.50,5546.82983,N,02334.72123,E,1,09,1.26,128.9,M,26.9,M,,*50 +{"class":"TPV","tag":"GGA","time":1260369186.500,"ept":0.005,"lat":55.780497167,"lon":23.578687167,"alt":128.900,"epx":10.912,"epy":11.668,"epv":39.995,"track":221.1600,"speed":15.600,"eps":46.67,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,2.99*05 +$GPGSV,3,1,10,32,22,227,35,09,12,038,29,19,58,204,39,11,36,285,36*76 +$GPGSV,3,2,10,14,45,118,34,03,31,183,30,28,,,34,22,47,070,42*45 +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":35,"used":true},{"PRN":9,"el":12,"az":38,"ss":29,"used":true},{"PRN":19,"el":58,"az":204,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":30,"used":true},{"PRN":28,"el":0,"az":0,"ss":34,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.82983,N,02334.72123,E,143306.50,A,A*66 +{"class":"TPV","tag":"GLL","time":1260369186.500,"ept":0.005,"lat":55.780497167,"lon":23.578687167,"alt":128.900,"epx":10.912,"epy":11.668,"epv":39.995,"track":221.1600,"speed":15.600,"climb":0.000,"eps":46.67,"mode":3} +$GPZDA,143306.50,09,12,2009,00,00*61 +$GPRMC,143307.00,A,5546.82649,N,02334.71625,E,30.860,221.48,091209,,,A*5D +$GPVTG,221.48,T,,M,30.860,N,57.183,K,A*35 +$GPGGA,143307.00,5546.82649,N,02334.71625,E,1,09,1.26,128.1,M,26.9,M,,*57 +{"class":"TPV","tag":"GGA","time":1260369187.000,"ept":0.005,"lat":55.780441500,"lon":23.578604167,"alt":128.100,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.4800,"speed":15.876,"eps":44.29,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,35,09,12,038,29,19,58,204,40,11,36,285,36*78 +$GPGSV,3,2,10,14,45,118,34,03,31,183,30,28,,,35,22,47,070,43*45 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":35,"used":true},{"PRN":9,"el":12,"az":38,"ss":29,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":30,"used":true},{"PRN":28,"el":0,"az":0,"ss":35,"used":false},{"PRN":22,"el":47,"az":70,"ss":43,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.82649,N,02334.71625,E,143307.00,A,A*69 +{"class":"TPV","tag":"GLL","time":1260369187.000,"ept":0.005,"lat":55.780441500,"lon":23.578604167,"alt":128.100,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.4800,"speed":15.876,"climb":0.000,"eps":44.29,"mode":3} +$GPZDA,143307.00,09,12,2009,00,00*65 +$GPRMC,143307.50,A,5546.82314,N,02334.71118,E,31.351,221.51,091209,,,A*5C +$GPVTG,221.51,T,,M,31.351,N,58.092,K,A*3B +$GPGGA,143307.50,5546.82314,N,02334.71118,E,1,09,1.26,127.5,M,26.9,M,,*5D +{"class":"TPV","tag":"GGA","time":1260369187.500,"ept":0.005,"lat":55.780385667,"lon":23.578519667,"alt":127.500,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.5100,"speed":16.128,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,35,09,12,038,29,19,58,204,40,11,36,285,36*78 +$GPGSV,3,2,10,14,45,118,34,03,31,183,30,28,,,33,22,47,070,43*43 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":35,"used":true},{"PRN":9,"el":12,"az":38,"ss":29,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":30,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":43,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.82314,N,02334.71118,E,143307.50,A,A*68 +{"class":"TPV","tag":"GLL","time":1260369187.500,"ept":0.005,"lat":55.780385667,"lon":23.578519667,"alt":127.500,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.5100,"speed":16.128,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143307.50,09,12,2009,00,00*60 +$GPRMC,143308.00,A,5546.81975,N,02334.70604,E,32.000,221.54,091209,,,A*52 +$GPVTG,221.54,T,,M,32.000,N,59.295,K,A*3E +$GPGGA,143308.00,5546.81975,N,02334.70604,E,1,09,1.26,127.1,M,26.9,M,,*56 +{"class":"TPV","tag":"GGA","time":1260369188.000,"ept":0.005,"lat":55.780329167,"lon":23.578434000,"alt":127.100,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.5400,"speed":16.462,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,36,09,12,038,29,19,58,204,41,11,36,285,37*7B +$GPGSV,3,2,10,14,45,118,35,03,31,183,29,28,,,33,22,47,070,43*4A +$GPGSV,3,3,10,06,26,174,35,26,44,080,38*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":36,"used":true},{"PRN":9,"el":12,"az":38,"ss":29,"used":true},{"PRN":19,"el":58,"az":204,"ss":41,"used":true},{"PRN":11,"el":36,"az":285,"ss":37,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":29,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":43,"used":true},{"PRN":6,"el":26,"az":174,"ss":35,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.81975,N,02334.70604,E,143308.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1260369188.000,"ept":0.005,"lat":55.780329167,"lon":23.578434000,"alt":127.100,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.5400,"speed":16.462,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143308.00,09,12,2009,00,00*6A +$GPRMC,143308.50,A,5546.81633,N,02334.70079,E,32.273,221.54,091209,,,A*50 +$GPVTG,221.54,T,,M,32.273,N,59.802,K,A*3C +$GPGGA,143308.50,5546.81633,N,02334.70079,E,1,09,1.26,126.8,M,26.9,M,,*5A +{"class":"TPV","tag":"GGA","time":1260369188.500,"ept":0.005,"lat":55.780272167,"lon":23.578346500,"alt":126.800,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.5400,"speed":16.603,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,34,09,12,038,29,19,58,204,40,11,36,285,35*7A +$GPGSV,3,2,10,14,45,118,35,03,31,183,27,28,,,32,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,37*77 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":29,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":37,"used":true}]} +$GPGLL,5546.81633,N,02334.70079,E,143308.50,A,A*63 +{"class":"TPV","tag":"GLL","time":1260369188.500,"ept":0.005,"lat":55.780272167,"lon":23.578346500,"alt":126.800,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.5400,"speed":16.603,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143308.50,09,12,2009,00,00*6F +$GPRMC,143309.00,A,5546.81291,N,02334.69552,E,32.094,221.48,091209,,,A*5A +$GPVTG,221.48,T,,M,32.094,N,59.470,K,A*33 +$GPGGA,143309.00,5546.81291,N,02334.69552,E,1,09,1.26,126.4,M,26.9,M,,*5A +{"class":"TPV","tag":"GGA","time":1260369189.000,"ept":0.005,"lat":55.780215167,"lon":23.578258667,"alt":126.400,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.4800,"speed":16.511,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,2.99*05 +$GPGSV,3,1,10,32,22,227,34,09,12,038,29,19,58,204,39,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,27,28,,,32,22,47,070,42*45 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":29,"used":true},{"PRN":19,"el":58,"az":204,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.81291,N,02334.69552,E,143309.00,A,A*6F +{"class":"TPV","tag":"GLL","time":1260369189.000,"ept":0.005,"lat":55.780215167,"lon":23.578258667,"alt":126.400,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.4800,"speed":16.511,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143309.00,09,12,2009,00,00*6B +$GPRMC,143309.50,A,5546.80952,N,02334.69029,E,32.096,221.46,091209,,,A*5F +$GPVTG,221.46,T,,M,32.096,N,59.474,K,A*3B +$GPGGA,143309.50,5546.80952,N,02334.69029,E,1,09,1.26,126.2,M,26.9,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369189.500,"ept":0.005,"lat":55.780158667,"lon":23.578171500,"alt":126.200,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.4600,"speed":16.512,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,34,09,12,038,28,19,58,204,40,11,36,285,35*7B +$GPGSV,3,2,10,14,45,118,33,03,31,183,29,28,,,32,22,47,070,42*4C +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":29,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.80952,N,02334.69029,E,143309.50,A,A*66 +{"class":"TPV","tag":"GLL","time":1260369189.500,"ept":0.005,"lat":55.780158667,"lon":23.578171500,"alt":126.200,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.4600,"speed":16.512,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143309.50,09,12,2009,00,00*6E +$GPRMC,143310.00,A,5546.80598,N,02334.68514,E,32.192,221.20,091209,,,A*57 +$GPVTG,221.20,T,,M,32.192,N,59.652,K,A*38 +$GPGGA,143310.00,5546.80598,N,02334.68514,E,1,09,1.26,125.3,M,27.0,M,,*52 +{"class":"TPV","tag":"GGA","time":1260369190.000,"ept":0.005,"lat":55.780099667,"lon":23.578085667,"alt":125.300,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.2000,"speed":16.561,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,33,09,12,038,28,19,58,204,40,11,36,285,35*7C +$GPGSV,3,2,10,14,45,118,34,03,31,183,26,28,,,32,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":26,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.80598,N,02334.68514,E,143310.00,A,A*6B +{"class":"TPV","tag":"GLL","time":1260369190.000,"ept":0.005,"lat":55.780099667,"lon":23.578085667,"alt":125.300,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.2000,"speed":16.561,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143310.00,09,12,2009,00,00*63 +$GPRMC,143310.50,A,5546.80248,N,02334.67996,E,32.361,221.42,091209,,,A*5B +$GPVTG,221.42,T,,M,32.361,N,59.964,K,A*38 +$GPGGA,143310.50,5546.80248,N,02334.67996,E,1,09,1.26,124.7,M,27.0,M,,*51 +{"class":"TPV","tag":"GGA","time":1260369190.500,"ept":0.005,"lat":55.780041333,"lon":23.577999333,"alt":124.700,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.4200,"speed":16.648,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,33,09,12,038,28,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,26,28,,,32,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":26,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.80248,N,02334.67996,E,143310.50,A,A*6D +{"class":"TPV","tag":"GLL","time":1260369190.500,"ept":0.005,"lat":55.780041333,"lon":23.577999333,"alt":124.700,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.4200,"speed":16.648,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143310.50,09,12,2009,00,00*66 +$GPRMC,143311.00,A,5546.79900,N,02334.67471,E,32.559,221.33,091209,,,A*51 +$GPVTG,221.33,T,,M,32.559,N,60.331,K,A*33 +$GPGGA,143311.00,5546.79900,N,02334.67471,E,1,09,1.26,124.2,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369191.000,"ept":0.005,"lat":55.779983333,"lon":23.577911833,"alt":124.200,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.3300,"speed":16.750,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,33,09,12,038,28,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,22,28,,,32,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":22,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.79900,N,02334.67471,E,143311.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1260369191.000,"ept":0.005,"lat":55.779983333,"lon":23.577911833,"alt":124.200,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.3300,"speed":16.750,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143311.00,09,12,2009,00,00*62 +$GPRMC,143311.50,A,5546.79553,N,02334.66940,E,32.825,221.71,091209,,,A*50 +$GPVTG,221.71,T,,M,32.825,N,60.825,K,A*3D +$GPGGA,143311.50,5546.79553,N,02334.66940,E,1,09,1.26,123.8,M,27.0,M,,*59 +{"class":"TPV","tag":"GGA","time":1260369191.500,"ept":0.005,"lat":55.779925500,"lon":23.577823333,"alt":123.800,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.7100,"speed":16.887,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,33,09,12,038,28,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,23,28,,,32,22,47,070,42*41 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":23,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.79553,N,02334.66940,E,143311.50,A,A*6D +{"class":"TPV","tag":"GLL","time":1260369191.500,"ept":0.005,"lat":55.779925500,"lon":23.577823333,"alt":123.800,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.7100,"speed":16.887,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143311.50,09,12,2009,00,00*67 +$GPRMC,143312.00,A,5546.79205,N,02334.66400,E,33.180,221.70,091209,,,A*5D +$GPVTG,221.70,T,,M,33.180,N,61.482,K,A*3B +$GPGGA,143312.00,5546.79205,N,02334.66400,E,1,09,1.26,123.5,M,27.0,M,,*5F +{"class":"TPV","tag":"GGA","time":1260369192.000,"ept":0.005,"lat":55.779867500,"lon":23.577733333,"alt":123.500,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.7000,"speed":17.069,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,227,33,09,12,038,28,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,32,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":227,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.79205,N,02334.66400,E,143312.00,A,A*66 +{"class":"TPV","tag":"GLL","time":1260369192.000,"ept":0.005,"lat":55.779867500,"lon":23.577733333,"alt":123.500,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.7000,"speed":17.069,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143312.00,09,12,2009,00,00*61 +$GPRMC,143312.50,A,5546.78854,N,02334.65855,E,33.465,221.75,091209,,,A*53 +$GPVTG,221.75,T,,M,33.465,N,62.011,K,A*3D +$GPGGA,143312.50,5546.78854,N,02334.65855,E,1,09,1.26,123.3,M,27.0,M,,*5C +{"class":"TPV","tag":"GGA","time":1260369192.500,"ept":0.005,"lat":55.779809000,"lon":23.577642500,"alt":123.300,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.7500,"speed":17.216,"eps":41.91,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,40,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,32,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.78854,N,02334.65855,E,143312.50,A,A*63 +{"class":"TPV","tag":"GLL","time":1260369192.500,"ept":0.005,"lat":55.779809000,"lon":23.577642500,"alt":123.300,"epx":10.478,"epy":9.434,"epv":36.127,"track":221.7500,"speed":17.216,"climb":0.000,"eps":41.91,"mode":3} +$GPZDA,143312.50,09,12,2009,00,00*64 +$GPRMC,143313.00,A,5546.78498,N,02334.65304,E,33.998,221.45,091209,,,A*58 +$GPVTG,221.45,T,,M,33.998,N,62.999,K,A*38 +$GPGGA,143313.00,5546.78498,N,02334.65304,E,1,09,1.26,123.2,M,27.0,M,,*5A +{"class":"TPV","tag":"GGA","time":1260369193.000,"ept":0.005,"lat":55.779749667,"lon":23.577550667,"alt":123.200,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.4500,"speed":17.490,"eps":41.84,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,40,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,21,28,,,32,22,47,070,42*42 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":21,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":35,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.78498,N,02334.65304,E,143313.00,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369193.000,"ept":0.005,"lat":55.779749667,"lon":23.577550667,"alt":123.200,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.4500,"speed":17.490,"climb":0.000,"eps":41.84,"mode":3} +$GPZDA,143313.00,09,12,2009,00,00*60 +$GPRMC,143313.50,A,5546.78137,N,02334.64747,E,34.471,221.60,091209,,,A*55 +$GPVTG,221.60,T,,M,34.471,N,63.875,K,A*30 +$GPGGA,143313.50,5546.78137,N,02334.64747,E,1,09,1.26,123.0,M,27.0,M,,*5F +{"class":"TPV","tag":"GGA","time":1260369193.500,"ept":0.005,"lat":55.779689500,"lon":23.577457833,"alt":123.000,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.6000,"speed":17.733,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,41,11,36,285,37*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,22,28,,,33,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":41,"used":true},{"PRN":11,"el":36,"az":285,"ss":37,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":22,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.78137,N,02334.64747,E,143313.50,A,A*63 +{"class":"TPV","tag":"GLL","time":1260369193.500,"ept":0.005,"lat":55.779689500,"lon":23.577457833,"alt":123.000,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.6000,"speed":17.733,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143313.50,09,12,2009,00,00*65 +$GPRMC,143314.00,A,5546.77773,N,02334.64182,E,34.916,221.39,091209,,,A*51 +$GPVTG,221.39,T,,M,34.916,N,64.699,K,A*3B +$GPGGA,143314.00,5546.77773,N,02334.64182,E,1,09,1.26,122.8,M,27.0,M,,*52 +{"class":"TPV","tag":"GGA","time":1260369194.000,"ept":0.005,"lat":55.779628833,"lon":23.577363667,"alt":122.800,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.3900,"speed":17.962,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,41,11,36,285,37*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,33,22,47,070,43*46 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":41,"used":true},{"PRN":11,"el":36,"az":285,"ss":37,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":43,"used":true},{"PRN":6,"el":26,"az":174,"ss":35,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.77773,N,02334.64182,E,143314.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1260369194.000,"ept":0.005,"lat":55.779628833,"lon":23.577363667,"alt":122.800,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.3900,"speed":17.962,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143314.00,09,12,2009,00,00*67 +$GPRMC,143314.50,A,5546.77404,N,02334.63610,E,35.259,221.42,091209,,,A*51 +$GPVTG,221.42,T,,M,35.259,N,65.335,K,A*34 +$GPGGA,143314.50,5546.77404,N,02334.63610,E,1,09,1.26,122.7,M,27.0,M,,*50 +{"class":"TPV","tag":"GGA","time":1260369194.500,"ept":0.005,"lat":55.779567333,"lon":23.577268333,"alt":122.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.4200,"speed":18.139,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,40,11,36,285,37*76 +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,33,22,47,070,42*47 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":37,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":35,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.77404,N,02334.63610,E,143314.50,A,A*6A +{"class":"TPV","tag":"GLL","time":1260369194.500,"ept":0.005,"lat":55.779567333,"lon":23.577268333,"alt":122.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.4200,"speed":18.139,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143314.50,09,12,2009,00,00*62 +$GPRMC,143315.00,A,5546.77031,N,02334.63033,E,35.613,221.33,091209,,,A*5C +$GPVTG,221.33,T,,M,35.613,N,65.991,K,A*3C +$GPGGA,143315.00,5546.77031,N,02334.63033,E,1,09,1.26,122.5,M,27.0,M,,*53 +{"class":"TPV","tag":"GGA","time":1260369195.000,"ept":0.005,"lat":55.779505167,"lon":23.577172167,"alt":122.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.3300,"speed":18.321,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,41,11,36,285,37*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,,,33,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":41,"used":true},{"PRN":11,"el":36,"az":285,"ss":37,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":35,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.77031,N,02334.63033,E,143315.00,A,A*6B +{"class":"TPV","tag":"GLL","time":1260369195.000,"ept":0.005,"lat":55.779505167,"lon":23.577172167,"alt":122.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.3300,"speed":18.321,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143315.00,09,12,2009,00,00*66 +$GPRMC,143315.50,A,5546.76656,N,02334.62450,E,35.901,221.55,091209,,,A*53 +$GPVTG,221.55,T,,M,35.901,N,66.525,K,A*30 +$GPGGA,143315.50,5546.76656,N,02334.62450,E,1,09,1.26,122.4,M,27.0,M,,*51 +{"class":"TPV","tag":"GGA","time":1260369195.500,"ept":0.005,"lat":55.779442667,"lon":23.577075000,"alt":122.400,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5500,"speed":18.469,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,40,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,20,28,,,32,22,47,070,42*43 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":20,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":35,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.76656,N,02334.62450,E,143315.50,A,A*68 +{"class":"TPV","tag":"GLL","time":1260369195.500,"ept":0.005,"lat":55.779442667,"lon":23.577075000,"alt":122.400,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5500,"speed":18.469,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143315.50,09,12,2009,00,00*63 +$GPRMC,143316.00,A,5546.76280,N,02334.61860,E,36.213,221.79,091209,,,A*53 +$GPVTG,221.79,T,,M,36.213,N,67.103,K,A*34 +$GPGGA,143316.00,5546.76280,N,02334.61860,E,1,09,1.26,122.2,M,27.0,M,,*52 +{"class":"TPV","tag":"GGA","time":1260369196.000,"ept":0.005,"lat":55.779380000,"lon":23.576976667,"alt":122.200,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.7900,"speed":18.630,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,34,09,12,038,28,19,58,204,40,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,35,03,31,183,21,28,,,33,22,47,070,42*43 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":21,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":35,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.76280,N,02334.61860,E,143316.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1260369196.000,"ept":0.005,"lat":55.779380000,"lon":23.576976667,"alt":122.200,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.7900,"speed":18.630,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143316.00,09,12,2009,00,00*65 +$GPRMC,143316.50,A,5546.75900,N,02334.61263,E,36.582,221.76,091209,,,A*5F +$GPVTG,221.76,T,,M,36.582,N,67.786,K,A*3F +$GPGGA,143316.50,5546.75900,N,02334.61263,E,1,09,1.26,122.1,M,27.0,M,,*5D +{"class":"TPV","tag":"GGA","time":1260369196.500,"ept":0.005,"lat":55.779316667,"lon":23.576877167,"alt":122.100,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.7600,"speed":18.819,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,28,19,58,204,40,11,36,285,37*71 +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,33,22,47,070,42*47 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":37,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.75900,N,02334.61263,E,143316.50,A,A*61 +{"class":"TPV","tag":"GLL","time":1260369196.500,"ept":0.005,"lat":55.779316667,"lon":23.576877167,"alt":122.100,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.7600,"speed":18.819,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143316.50,09,12,2009,00,00*60 +$GPRMC,143317.00,A,5546.75517,N,02334.60661,E,36.882,221.73,091209,,,A*5E +$GPVTG,221.73,T,,M,36.882,N,68.343,K,A*35 +$GPGGA,143317.00,5546.75517,N,02334.60661,E,1,09,1.26,122.0,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369197.000,"ept":0.005,"lat":55.779252833,"lon":23.576776833,"alt":122.000,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.7300,"speed":18.974,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,28,19,58,204,40,11,36,285,37*71 +$GPGSV,3,2,10,14,45,118,35,03,31,183,25,28,,,33,22,47,070,42*47 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":37,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.75517,N,02334.60661,E,143317.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1260369197.000,"ept":0.005,"lat":55.779252833,"lon":23.576776833,"alt":122.000,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.7300,"speed":18.974,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143317.00,09,12,2009,00,00*64 +$GPRMC,143317.50,A,5546.75131,N,02334.60056,E,37.099,221.59,091209,,,A*52 +$GPVTG,221.59,T,,M,37.099,N,68.744,K,A*3D +$GPGGA,143317.50,5546.75131,N,02334.60056,E,1,09,1.26,122.0,M,27.0,M,,*52 +{"class":"TPV","tag":"GGA","time":1260369197.500,"ept":0.005,"lat":55.779188500,"lon":23.576676000,"alt":122.000,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5900,"speed":19.085,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,32,09,12,038,28,19,58,204,40,11,36,285,36*71 +$GPGSV,3,2,10,14,45,118,34,03,31,183,25,28,,,33,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.75131,N,02334.60056,E,143317.50,A,A*6F +{"class":"TPV","tag":"GLL","time":1260369197.500,"ept":0.005,"lat":55.779188500,"lon":23.576676000,"alt":122.000,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5900,"speed":19.085,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143317.50,09,12,2009,00,00*61 +$GPRMC,143318.00,A,5546.74742,N,02334.59448,E,37.130,221.51,091209,,,A*50 +$GPVTG,221.51,T,,M,37.130,N,68.801,K,A*39 +$GPGGA,143318.00,5546.74742,N,02334.59448,E,1,09,1.26,121.9,M,27.0,M,,*50 +{"class":"TPV","tag":"GGA","time":1260369198.000,"ept":0.005,"lat":55.779123667,"lon":23.576574667,"alt":121.900,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5100,"speed":19.101,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,27,19,58,204,40,11,36,285,35*7C +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,,,33,22,47,070,42*47 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":35,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.74742,N,02334.59448,E,143318.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1260369198.000,"ept":0.005,"lat":55.779123667,"lon":23.576574667,"alt":121.900,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5100,"speed":19.101,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143318.00,09,12,2009,00,00*6B +$GPRMC,143318.50,A,5546.74354,N,02334.58840,E,37.142,221.66,091209,,,A*52 +$GPVTG,221.66,T,,M,37.142,N,68.824,K,A*3F +$GPGGA,143318.50,5546.74354,N,02334.58840,E,1,09,1.26,121.8,M,27.0,M,,*52 +{"class":"TPV","tag":"GGA","time":1260369198.500,"ept":0.005,"lat":55.779059000,"lon":23.576473333,"alt":121.800,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.6600,"speed":19.107,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,28,19,58,204,40,11,36,285,36*70 +$GPGSV,3,2,10,14,45,118,35,03,31,183,22,28,,,33,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":22,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.74354,N,02334.58840,E,143318.50,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369198.500,"ept":0.005,"lat":55.779059000,"lon":23.576473333,"alt":121.800,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.6600,"speed":19.107,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143318.50,09,12,2009,00,00*6E +$GPRMC,143319.00,A,5546.73966,N,02334.58232,E,37.148,221.65,091209,,,A*5C +$GPVTG,221.65,T,,M,37.148,N,68.835,K,A*36 +$GPGGA,143319.00,5546.73966,N,02334.58232,E,1,09,1.26,121.8,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369199.000,"ept":0.005,"lat":55.778994333,"lon":23.576372000,"alt":121.800,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.6500,"speed":19.111,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,27,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,25,28,,,33,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.73966,N,02334.58232,E,143319.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1260369199.000,"ept":0.005,"lat":55.778994333,"lon":23.576372000,"alt":121.800,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.6500,"speed":19.111,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143319.00,09,12,2009,00,00*6A +$GPRMC,143319.50,A,5546.73578,N,02334.57626,E,37.138,221.35,091209,,,A*56 +$GPVTG,221.35,T,,M,37.138,N,68.817,K,A*34 +$GPGGA,143319.50,5546.73578,N,02334.57626,E,1,09,1.26,121.8,M,27.0,M,,*5D +{"class":"TPV","tag":"GGA","time":1260369199.500,"ept":0.005,"lat":55.778929667,"lon":23.576271000,"alt":121.800,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.3500,"speed":19.105,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,27,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,25,28,,,33,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.73578,N,02334.57626,E,143319.50,A,A*6B +{"class":"TPV","tag":"GLL","time":1260369199.500,"ept":0.005,"lat":55.778929667,"lon":23.576271000,"alt":121.800,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.3500,"speed":19.105,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143319.50,09,12,2009,00,00*6F +$GPRMC,143320.00,A,5546.73191,N,02334.57020,E,37.095,221.51,091209,,,A*5E +$GPVTG,221.51,T,,M,37.095,N,68.737,K,A*3D +$GPGGA,143320.00,5546.73191,N,02334.57020,E,1,09,1.26,121.7,M,27.0,M,,*5E +{"class":"TPV","tag":"GGA","time":1260369200.000,"ept":0.005,"lat":55.778865167,"lon":23.576170000,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5100,"speed":19.083,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,27,19,58,204,41,11,36,285,36*7E +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,,,33,22,47,070,42*47 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":41,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":35,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.73191,N,02334.57020,E,143320.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1260369200.000,"ept":0.005,"lat":55.778865167,"lon":23.576170000,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5100,"speed":19.083,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143320.00,09,12,2009,00,00*60 +$GPRMC,143320.50,A,5546.72805,N,02334.56415,E,36.982,221.56,091209,,,A*54 +$GPVTG,221.56,T,,M,36.982,N,68.528,K,A*38 +$GPGGA,143320.50,5546.72805,N,02334.56415,E,1,09,1.26,121.7,M,27.0,M,,*5D +{"class":"TPV","tag":"GGA","time":1260369200.500,"ept":0.005,"lat":55.778800833,"lon":23.576069167,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5600,"speed":19.025,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,32,09,12,038,27,19,58,204,40,11,36,285,35*7D +$GPGSV,3,2,10,14,45,118,34,03,31,183,22,28,,,32,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":38,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":22,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.72805,N,02334.56415,E,143320.50,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369200.500,"ept":0.005,"lat":55.778800833,"lon":23.576069167,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5600,"speed":19.025,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143320.50,09,12,2009,00,00*65 +$GPRMC,143321.00,A,5546.72423,N,02334.55813,E,36.738,221.85,091209,,,A*50 +$GPVTG,221.85,T,,M,36.738,N,68.076,K,A*37 +$GPGGA,143321.00,5546.72423,N,02334.55813,E,1,09,1.26,121.7,M,27.0,M,,*58 +{"class":"TPV","tag":"GGA","time":1260369201.000,"ept":0.005,"lat":55.778737167,"lon":23.575968833,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.8500,"speed":18.900,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,27,19,58,204,40,11,36,285,36*7F +$GPGSV,3,2,10,14,45,118,34,03,31,183,23,28,,,33,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":23,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.72423,N,02334.55813,E,143321.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1260369201.000,"ept":0.005,"lat":55.778737167,"lon":23.575968833,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.8500,"speed":18.900,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143321.00,09,12,2009,00,00*61 +$GPRMC,143321.50,A,5546.72043,N,02334.55216,E,36.548,221.51,091209,,,A*54 +$GPVTG,221.51,T,,M,36.548,N,67.724,K,A*34 +$GPGGA,143321.50,5546.72043,N,02334.55216,E,1,09,1.26,121.7,M,27.0,M,,*50 +{"class":"TPV","tag":"GGA","time":1260369201.500,"ept":0.005,"lat":55.778673833,"lon":23.575869333,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5100,"speed":18.802,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,32,09,12,038,27,19,58,204,40,11,36,285,36*7E +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,,,34,22,47,070,42*41 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":38,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":0,"az":0,"ss":34,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.72043,N,02334.55216,E,143321.50,A,A*69 +{"class":"TPV","tag":"GLL","time":1260369201.500,"ept":0.005,"lat":55.778673833,"lon":23.575869333,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5100,"speed":18.802,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143321.50,09,12,2009,00,00*64 +$GPRMC,143322.00,A,5546.71665,N,02334.54623,E,36.296,221.61,091209,,,A*57 +$GPVTG,221.61,T,,M,36.296,N,67.257,K,A*32 +$GPGGA,143322.00,5546.71665,N,02334.54623,E,1,09,1.26,121.7,M,27.0,M,,*54 +{"class":"TPV","tag":"GGA","time":1260369202.000,"ept":0.005,"lat":55.778610833,"lon":23.575770500,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.6100,"speed":18.672,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,31,09,12,038,27,19,58,204,38,11,36,285,34*70 +$GPGSV,3,2,10,14,45,118,33,03,31,183,21,28,,,32,22,47,070,40*46 +$GPGSV,3,3,10,06,26,174,31,26,44,080,37*72 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":38,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":21,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":26,"az":174,"ss":31,"used":true},{"PRN":26,"el":44,"az":80,"ss":37,"used":true}]} +$GPGLL,5546.71665,N,02334.54623,E,143322.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1260369202.000,"ept":0.005,"lat":55.778610833,"lon":23.575770500,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.6100,"speed":18.672,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143322.00,09,12,2009,00,00*62 +$GPRMC,143322.50,A,5546.71291,N,02334.54032,E,36.068,222.02,091209,,,A*5E +$GPVTG,222.02,T,,M,36.068,N,66.834,K,A*39 +$GPGGA,143322.50,5546.71291,N,02334.54032,E,1,09,1.26,121.7,M,27.0,M,,*58 +{"class":"TPV","tag":"GGA","time":1260369202.500,"ept":0.005,"lat":55.778548500,"lon":23.575672000,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":222.0200,"speed":18.555,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,30,09,12,038,27,19,58,204,38,11,36,285,34*71 +$GPGSV,3,2,10,14,45,118,32,03,31,183,22,28,,,31,22,47,070,40*47 +$GPGSV,3,3,10,06,26,174,32,26,44,080,36*70 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":30,"used":true},{"PRN":9,"el":12,"az":38,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":22,"used":true},{"PRN":28,"el":0,"az":0,"ss":31,"used":false},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":36,"used":true}]} +$GPGLL,5546.71291,N,02334.54032,E,143322.50,A,A*61 +{"class":"TPV","tag":"GLL","time":1260369202.500,"ept":0.005,"lat":55.778548500,"lon":23.575672000,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":222.0200,"speed":18.555,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143322.50,09,12,2009,00,00*67 +$GPRMC,143323.00,A,5546.70920,N,02334.53442,E,35.897,221.92,091209,,,A*5F +$GPVTG,221.92,T,,M,35.897,N,66.516,K,A*35 +$GPGGA,143323.00,5546.70920,N,02334.53442,E,1,09,1.26,121.7,M,27.0,M,,*58 +{"class":"TPV","tag":"GGA","time":1260369203.000,"ept":0.005,"lat":55.778486667,"lon":23.575573667,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.9200,"speed":18.467,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,31,09,12,038,27,19,58,204,39,11,36,285,35*70 +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,,,32,22,47,070,41*45 +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":38,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.70920,N,02334.53442,E,143323.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1260369203.000,"ept":0.005,"lat":55.778486667,"lon":23.575573667,"alt":121.700,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.9200,"speed":18.467,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143323.00,09,12,2009,00,00*63 +$GPRMC,143323.50,A,5546.70550,N,02334.52854,E,35.802,222.24,091209,,,A*59 +$GPVTG,222.24,T,,M,35.802,N,66.342,K,A*30 +$GPGGA,143323.50,5546.70550,N,02334.52854,E,1,09,1.26,121.5,M,27.0,M,,*5E +{"class":"TPV","tag":"GGA","time":1260369203.500,"ept":0.005,"lat":55.778425000,"lon":23.575475667,"alt":121.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":222.2400,"speed":18.418,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,32,09,12,038,28,19,58,204,40,11,36,285,36*71 +$GPGSV,3,2,10,14,45,118,35,03,31,183,30,28,,,34,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":38,"ss":28,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":30,"used":true},{"PRN":28,"el":0,"az":0,"ss":34,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.70550,N,02334.52854,E,143323.50,A,A*65 +{"class":"TPV","tag":"GLL","time":1260369203.500,"ept":0.005,"lat":55.778425000,"lon":23.575475667,"alt":121.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":222.2400,"speed":18.418,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143323.50,09,12,2009,00,00*66 +$GPRMC,143324.00,A,5546.70183,N,02334.52263,E,35.829,222.00,091209,,,A*50 +$GPVTG,222.00,T,,M,35.829,N,66.391,K,A*31 +$GPGGA,143324.00,5546.70183,N,02334.52263,E,1,09,1.26,121.6,M,27.0,M,,*5B +{"class":"TPV","tag":"GGA","time":1260369204.000,"ept":0.005,"lat":55.778363833,"lon":23.575377167,"alt":121.600,"epx":10.441,"epy":9.459,"epv":36.180,"track":222.0000,"speed":18.432,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,30,19,58,204,40,11,36,285,36*79 +$GPGSV,3,2,10,14,45,118,35,03,31,183,27,28,,,33,22,47,070,41*46 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":30,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.70183,N,02334.52263,E,143324.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1260369204.000,"ept":0.005,"lat":55.778363833,"lon":23.575377167,"alt":121.600,"epx":10.441,"epy":9.459,"epv":36.180,"track":222.0000,"speed":18.432,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143324.00,09,12,2009,00,00*64 +$GPRMC,143324.50,A,5546.69812,N,02334.51673,E,35.962,222.09,091209,,,A*5D +$GPVTG,222.09,T,,M,35.962,N,66.638,K,A*30 +$GPGGA,143324.50,5546.69812,N,02334.51673,E,1,09,1.26,121.6,M,27.0,M,,*51 +{"class":"TPV","tag":"GGA","time":1260369204.500,"ept":0.005,"lat":55.778302000,"lon":23.575278833,"alt":121.600,"epx":10.441,"epy":9.459,"epv":36.180,"track":222.0900,"speed":18.500,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,30,19,58,204,40,11,36,285,35*7A +$GPGSV,3,2,10,14,45,118,35,03,31,183,27,28,,,32,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":30,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.69812,N,02334.51673,E,143324.50,A,A*69 +{"class":"TPV","tag":"GLL","time":1260369204.500,"ept":0.005,"lat":55.778302000,"lon":23.575278833,"alt":121.600,"epx":10.441,"epy":9.459,"epv":36.180,"track":222.0900,"speed":18.500,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143324.50,09,12,2009,00,00*61 +$GPRMC,143325.00,A,5546.69439,N,02334.51078,E,36.290,222.04,091209,,,A*59 +$GPVTG,222.04,T,,M,36.290,N,67.245,K,A*37 +$GPGGA,143325.00,5546.69439,N,02334.51078,E,1,09,1.26,121.5,M,27.0,M,,*5E +{"class":"TPV","tag":"GGA","time":1260369205.000,"ept":0.005,"lat":55.778239833,"lon":23.575179667,"alt":121.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":222.0400,"speed":18.669,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,29,19,58,204,40,11,36,285,35*72 +$GPGSV,3,2,10,14,45,118,35,03,31,183,26,28,,,32,22,47,070,41*46 +$GPGSV,3,3,10,06,26,174,35,26,44,080,39*78 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":29,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":26,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":35,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.69439,N,02334.51078,E,143325.00,A,A*65 +{"class":"TPV","tag":"GLL","time":1260369205.000,"ept":0.005,"lat":55.778239833,"lon":23.575179667,"alt":121.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":222.0400,"speed":18.669,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143325.00,09,12,2009,00,00*65 +$GPRMC,143325.50,A,5546.69063,N,02334.50478,E,36.575,221.93,091209,,,A*53 +$GPVTG,221.93,T,,M,36.575,N,67.774,K,A*31 +$GPGGA,143325.50,5546.69063,N,02334.50478,E,1,09,1.26,121.5,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369205.500,"ept":0.005,"lat":55.778177167,"lon":23.575079667,"alt":121.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.9300,"speed":18.816,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,33,09,12,038,29,19,58,204,40,11,36,285,36*71 +$GPGSV,3,2,10,14,45,118,35,03,31,183,26,28,,,33,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":29,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":26,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.69063,N,02334.50478,E,143325.50,A,A*6E +{"class":"TPV","tag":"GLL","time":1260369205.500,"ept":0.005,"lat":55.778177167,"lon":23.575079667,"alt":121.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.9300,"speed":18.816,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143325.50,09,12,2009,00,00*60 +$GPRMC,143326.00,A,5546.68683,N,02334.49875,E,36.874,221.81,091209,,,A*5A +$GPVTG,221.81,T,,M,36.874,N,68.328,K,A*3C +$GPGGA,143326.00,5546.68683,N,02334.49875,E,1,09,1.26,121.5,M,27.0,M,,*53 +{"class":"TPV","tag":"GGA","time":1260369206.000,"ept":0.005,"lat":55.778113833,"lon":23.574979167,"alt":121.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.8100,"speed":18.970,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.00*07 +$GPGSV,3,1,10,32,22,228,33,09,12,038,29,19,58,204,40,11,36,285,36*71 +$GPGSV,3,2,10,14,45,118,35,03,31,183,26,28,,,33,22,47,070,42*44 +$GPGSV,3,3,10,06,26,174,34,26,44,080,39*79 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.80,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":38,"ss":29,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":26,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.68683,N,02334.49875,E,143326.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1260369206.000,"ept":0.005,"lat":55.778113833,"lon":23.574979167,"alt":121.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.8100,"speed":18.970,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143326.00,09,12,2009,00,00*66 +$GPRMC,143326.50,A,5546.68299,N,02334.49268,E,37.174,221.56,091209,,,A*54 +$GPVTG,221.56,T,,M,37.174,N,68.883,K,A*34 +$GPGGA,143326.50,5546.68299,N,02334.49268,E,1,09,1.26,121.5,M,27.0,M,,*5F +{"class":"TPV","tag":"GGA","time":1260369206.500,"ept":0.005,"lat":55.778049833,"lon":23.574878000,"alt":121.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5600,"speed":19.124,"eps":41.76,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.25,1.26,3.00*04 +$GPGSV,3,1,10,32,22,228,32,09,12,037,27,19,58,204,40,11,36,285,36*71 +$GPGSV,3,2,10,14,45,118,34,03,31,183,26,28,,,33,22,47,070,42*45 +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.81,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":204,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":26,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.68299,N,02334.49268,E,143326.50,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369206.500,"ept":0.005,"lat":55.778049833,"lon":23.574878000,"alt":121.500,"epx":10.441,"epy":9.459,"epv":36.180,"track":221.5600,"speed":19.124,"climb":0.000,"eps":41.76,"mode":3} +$GPZDA,143326.50,09,12,2009,00,00*63 +$GPRMC,143327.00,A,5546.67914,N,02334.48657,E,37.433,221.51,091209,,,A*59 +$GPVTG,221.51,T,,M,37.433,N,69.363,K,A*31 +$GPGGA,143327.00,5546.67914,N,02334.48657,E,1,09,1.47,121.6,M,27.0,M,,*57 +{"class":"TPV","tag":"GGA","time":1260369207.000,"ept":0.005,"lat":55.777985667,"lon":23.574776167,"alt":121.600,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.5100,"speed":19.257,"eps":41.84,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.66,1.47,3.35*02 +$GPGSV,3,1,12,32,22,228,31,27,,,31,09,12,037,26,19,58,204,38*46 +$GPGSV,3,2,12,11,36,285,34,14,45,118,32,03,31,183,19,28,,,31*40 +$GPGSV,3,3,12,22,47,070,40,15,,,22,06,26,174,31,26,44,080,36*45 +{"class":"SKY","tag":"GSV","xdop":0.73,"ydop":0.77,"vdop":1.68,"tdop":0.87,"hdop":1.06,"gdop":2.17,"pdop":1.99,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":27,"el":0,"az":0,"ss":31,"used":false},{"PRN":9,"el":12,"az":37,"ss":26,"used":true},{"PRN":19,"el":58,"az":204,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":19,"used":true},{"PRN":28,"el":0,"az":0,"ss":31,"used":false},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":15,"el":0,"az":0,"ss":22,"used":false},{"PRN":6,"el":26,"az":174,"ss":31,"used":true},{"PRN":26,"el":44,"az":80,"ss":36,"used":true}]} +$GPGLL,5546.67914,N,02334.48657,E,143327.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1260369207.000,"ept":0.005,"lat":55.777985667,"lon":23.574776167,"alt":121.600,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.5100,"speed":19.257,"climb":0.000,"eps":41.84,"mode":3} +$GPZDA,143327.00,09,12,2009,00,00*67 +$GPRMC,143327.50,A,5546.67528,N,02334.48042,E,37.526,221.60,091209,,,A*5A +$GPVTG,221.60,T,,M,37.526,N,69.535,K,A*33 +$GPGGA,143327.50,5546.67528,N,02334.48042,E,1,09,1.48,121.7,M,27.0,M,,*5D +{"class":"TPV","tag":"GGA","time":1260369207.500,"ept":0.005,"lat":55.777921333,"lon":23.574673667,"alt":121.700,"epx":10.906,"epy":11.531,"epv":38.655,"track":221.6000,"speed":19.305,"eps":44.02,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.66,1.48,3.35*0D +$GPGSV,4,1,14,32,22,228,30,27,,,30,09,12,037,25,12,,,33*7F +$GPGSV,4,2,14,19,58,204,37,11,36,285,33,14,45,118,32,03,31,183,18*78 +$GPGSV,4,3,14,28,,,30,22,47,070,39,15,,,24,06,26,174,30*7D +$GPGSV,4,4,14,26,44,080,36,17,,,34*44 +{"class":"SKY","tag":"GSV","xdop":0.77,"ydop":0.82,"vdop":1.89,"tdop":0.89,"hdop":1.12,"gdop":2.37,"pdop":2.20,"satellites":[{"PRN":32,"el":22,"az":228,"ss":30,"used":true},{"PRN":27,"el":0,"az":0,"ss":30,"used":false},{"PRN":9,"el":12,"az":37,"ss":25,"used":true},{"PRN":12,"el":0,"az":0,"ss":33,"used":false},{"PRN":19,"el":58,"az":204,"ss":37,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":18,"used":true},{"PRN":28,"el":0,"az":0,"ss":30,"used":false},{"PRN":22,"el":47,"az":70,"ss":39,"used":true},{"PRN":15,"el":0,"az":0,"ss":24,"used":false},{"PRN":6,"el":26,"az":174,"ss":30,"used":true},{"PRN":26,"el":44,"az":80,"ss":36,"used":true},{"PRN":17,"el":0,"az":0,"ss":34,"used":false}]} +$GPGLL,5546.67528,N,02334.48042,E,143327.50,A,A*6C +{"class":"TPV","tag":"GLL","time":1260369207.500,"ept":0.005,"lat":55.777921333,"lon":23.574673667,"alt":121.700,"epx":10.906,"epy":11.531,"epv":38.655,"track":221.6000,"speed":19.305,"climb":0.000,"eps":44.02,"mode":3} +$GPZDA,143327.50,09,12,2009,00,00*62 +$GPRMC,143328.00,A,5546.67138,N,02334.47421,E,37.918,221.73,091209,,,A*58 +$GPVTG,221.73,T,,M,37.918,N,70.262,K,A*3D +$GPGGA,143328.00,5546.67138,N,02334.47421,E,1,09,1.19,121.7,M,27.0,M,,*58 +{"class":"TPV","tag":"GGA","time":1260369208.000,"ept":0.005,"lat":55.777856333,"lon":23.574570167,"alt":121.700,"epx":11.523,"epy":12.231,"epv":43.582,"track":221.7300,"speed":19.507,"eps":47.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.23,1.19,3.00*0E +$GPGSV,4,1,14,32,22,228,29,27,,,29,09,12,037,25,12,,,32*7E +$GPGSV,4,2,14,19,58,204,37,11,36,285,33,14,45,118,32,03,31,183,19*79 +$GPGSV,4,3,14,28,,,29,22,47,070,38,15,,,24,06,26,174,29*7C +$GPGSV,4,4,14,26,44,080,36,17,,,33*43 +{"class":"SKY","tag":"GSV","xdop":0.77,"ydop":0.82,"vdop":1.89,"tdop":0.89,"hdop":1.12,"gdop":2.37,"pdop":2.20,"satellites":[{"PRN":32,"el":22,"az":228,"ss":29,"used":true},{"PRN":27,"el":0,"az":0,"ss":29,"used":false},{"PRN":9,"el":12,"az":37,"ss":25,"used":true},{"PRN":12,"el":0,"az":0,"ss":32,"used":false},{"PRN":19,"el":58,"az":204,"ss":37,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":19,"used":true},{"PRN":28,"el":0,"az":0,"ss":29,"used":false},{"PRN":22,"el":47,"az":70,"ss":38,"used":true},{"PRN":15,"el":0,"az":0,"ss":24,"used":false},{"PRN":6,"el":26,"az":174,"ss":29,"used":true},{"PRN":26,"el":44,"az":80,"ss":36,"used":true},{"PRN":17,"el":0,"az":0,"ss":33,"used":false}]} +$GPGLL,5546.67138,N,02334.47421,E,143328.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1260369208.000,"ept":0.005,"lat":55.777856333,"lon":23.574570167,"alt":121.700,"epx":11.523,"epy":12.231,"epv":43.582,"track":221.7300,"speed":19.507,"climb":0.000,"eps":47.52,"mode":3} +$GPZDA,143328.00,09,12,2009,00,00*68 +$GPRMC,143328.50,A,5546.66742,N,02334.46793,E,38.036,221.73,091209,,,A*56 +$GPVTG,221.73,T,,M,38.036,N,70.482,K,A*3F +$GPGGA,143328.50,5546.66742,N,02334.46793,E,1,09,1.19,121.8,M,27.0,M,,*53 +{"class":"TPV","tag":"GGA","time":1260369208.500,"ept":0.005,"lat":55.777790333,"lon":23.574465500,"alt":121.800,"epx":11.523,"epy":12.231,"epv":43.582,"track":221.7300,"speed":19.567,"eps":48.93,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.23,1.19,3.00*0E +$GPGSV,3,1,10,32,22,228,30,09,12,037,25,19,58,204,38,11,36,285,34*7C +$GPGSV,3,2,10,14,45,118,33,03,31,183,23,28,,,30,22,47,070,40*46 +$GPGSV,3,3,10,06,26,174,30,26,44,080,37*73 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.81,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":30,"used":true},{"PRN":9,"el":12,"az":37,"ss":25,"used":true},{"PRN":19,"el":58,"az":204,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":23,"used":true},{"PRN":28,"el":0,"az":0,"ss":30,"used":false},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":26,"az":174,"ss":30,"used":true},{"PRN":26,"el":44,"az":80,"ss":37,"used":true}]} +$GPGLL,5546.66742,N,02334.46793,E,143328.50,A,A*69 +{"class":"TPV","tag":"GLL","time":1260369208.500,"ept":0.005,"lat":55.777790333,"lon":23.574465500,"alt":121.800,"epx":11.523,"epy":12.231,"epv":43.582,"track":221.7300,"speed":19.567,"climb":0.000,"eps":48.93,"mode":3} +$GPZDA,143328.50,09,12,2009,00,00*6D +$GPRMC,143329.00,A,5546.66350,N,02334.46164,E,38.567,221.88,091209,,,A*5E +$GPVTG,221.88,T,,M,38.567,N,71.465,K,A*32 +$GPGGA,143329.00,5546.66350,N,02334.46164,E,1,09,1.19,121.8,M,27.0,M,,*5E +{"class":"TPV","tag":"GGA","time":1260369209.000,"ept":0.005,"lat":55.777725000,"lon":23.574360667,"alt":121.800,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.8800,"speed":19.841,"eps":45.42,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.23,1.19,3.00*0E +$GPGSV,3,1,10,32,22,228,30,09,12,037,26,19,58,204,39,11,36,285,35*7F +$GPGSV,3,2,10,14,45,118,33,03,31,183,25,28,,,30,22,47,070,41*41 +$GPGSV,3,3,10,06,26,174,32,26,44,080,37*71 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.81,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":30,"used":true},{"PRN":9,"el":12,"az":37,"ss":26,"used":true},{"PRN":19,"el":58,"az":204,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":30,"used":false},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":37,"used":true}]} +$GPGLL,5546.66350,N,02334.46164,E,143329.00,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369209.000,"ept":0.005,"lat":55.777725000,"lon":23.574360667,"alt":121.800,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.8800,"speed":19.841,"climb":0.000,"eps":45.42,"mode":3} +$GPZDA,143329.00,09,12,2009,00,00*69 +$GPRMC,143329.50,A,5546.65952,N,02334.45524,E,38.642,222.07,091209,,,A*53 +$GPVTG,222.07,T,,M,38.642,N,71.604,K,A*37 +$GPGGA,143329.50,5546.65952,N,02334.45524,E,1,09,1.28,121.9,M,27.0,M,,*50 +{"class":"TPV","tag":"GGA","time":1260369209.500,"ept":0.005,"lat":55.777658667,"lon":23.574254000,"alt":121.900,"epx":10.479,"epy":9.442,"epv":36.224,"track":222.0700,"speed":19.879,"eps":41.92,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.65,1.28,3.41*0B +$GPGSV,3,1,10,32,22,228,30,09,12,037,26,19,58,204,39,11,36,285,34*7E +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,,,30,22,47,070,41*4C +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.81,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":30,"used":true},{"PRN":9,"el":12,"az":37,"ss":26,"used":true},{"PRN":19,"el":58,"az":204,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":0,"az":0,"ss":30,"used":false},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.65952,N,02334.45524,E,143329.50,A,A*69 +{"class":"TPV","tag":"GLL","time":1260369209.500,"ept":0.005,"lat":55.777658667,"lon":23.574254000,"alt":121.900,"epx":10.479,"epy":9.442,"epv":36.224,"track":222.0700,"speed":19.879,"climb":0.000,"eps":41.92,"mode":3} +$GPZDA,143329.50,09,12,2009,00,00*6C +$GPRMC,143330.00,A,5546.65551,N,02334.44882,E,38.917,221.88,091209,,,A*5A +$GPVTG,221.88,T,,M,38.917,N,72.112,K,A*3F +$GPGGA,143330.00,5546.65551,N,02334.44882,E,1,09,1.28,121.9,M,27.0,M,,*52 +{"class":"TPV","tag":"GGA","time":1260369210.000,"ept":0.005,"lat":55.777591833,"lon":23.574147000,"alt":121.900,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.8800,"speed":20.021,"eps":41.92,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.64,1.28,3.41*0A +$GPGSV,3,1,10,32,22,228,31,09,12,037,26,19,58,204,39,11,36,285,35*7E +$GPGSV,3,2,10,14,45,118,33,03,31,183,24,28,,,31,22,47,070,41*41 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.81,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":26,"used":true},{"PRN":19,"el":58,"az":204,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":0,"az":0,"ss":31,"used":false},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.65551,N,02334.44882,E,143330.00,A,A*6B +{"class":"TPV","tag":"GLL","time":1260369210.000,"ept":0.005,"lat":55.777591833,"lon":23.574147000,"alt":121.900,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.8800,"speed":20.021,"climb":0.000,"eps":41.92,"mode":3} +$GPZDA,143330.00,09,12,2009,00,00*61 +$GPRMC,143330.50,A,5546.65146,N,02334.44238,E,39.222,221.56,091209,,,A*59 +$GPVTG,221.56,T,,M,39.222,N,72.679,K,A*3A +$GPGGA,143330.50,5546.65146,N,02334.44238,E,1,09,1.28,122.0,M,27.0,M,,*54 +{"class":"TPV","tag":"GGA","time":1260369210.500,"ept":0.005,"lat":55.777524333,"lon":23.574039667,"alt":122.000,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.5600,"speed":20.178,"eps":41.92,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.64,1.28,3.41*0A +$GPGSV,3,1,10,32,22,228,33,09,12,037,26,19,58,204,39,11,36,285,35*7C +$GPGSV,3,2,10,14,45,118,33,03,31,183,20,28,,,31,22,47,070,41*45 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.81,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":26,"used":true},{"PRN":19,"el":58,"az":204,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":20,"used":true},{"PRN":28,"el":0,"az":0,"ss":31,"used":false},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.65146,N,02334.44238,E,143330.50,A,A*67 +{"class":"TPV","tag":"GLL","time":1260369210.500,"ept":0.005,"lat":55.777524333,"lon":23.574039667,"alt":122.000,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.5600,"speed":20.178,"climb":0.000,"eps":41.92,"mode":3} +$GPZDA,143330.50,09,12,2009,00,00*64 +$GPRMC,143331.00,A,5546.64738,N,02334.43592,E,39.384,221.52,091209,,,A*5A +$GPVTG,221.52,T,,M,39.384,N,72.979,K,A*3C +$GPGGA,143331.00,5546.64738,N,02334.43592,E,1,09,1.26,122.1,M,27.0,M,,*51 +{"class":"TPV","tag":"GGA","time":1260369211.000,"ept":0.005,"lat":55.777456333,"lon":23.573932000,"alt":122.100,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.5200,"speed":20.261,"eps":41.92,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,33,09,12,037,26,19,58,204,39,11,36,285,34*7D +$GPGSV,3,2,10,14,45,118,34,03,31,183,20,28,,,31,22,47,070,41*42 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.57,"tdop":0.81,"hdop":0.94,"gdop":2.00,"pdop":1.83,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":26,"used":true},{"PRN":19,"el":58,"az":204,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":20,"used":true},{"PRN":28,"el":0,"az":0,"ss":31,"used":false},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.64738,N,02334.43592,E,143331.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1260369211.000,"ept":0.005,"lat":55.777456333,"lon":23.573932000,"alt":122.100,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.5200,"speed":20.261,"climb":0.000,"eps":41.92,"mode":3} +$GPZDA,143331.00,09,12,2009,00,00*60 +$GPRMC,143331.50,A,5546.64328,N,02334.42943,E,39.571,221.47,091209,,,A*53 +$GPVTG,221.47,T,,M,39.571,N,73.325,K,A*36 +$GPGGA,143331.50,5546.64328,N,02334.42943,E,1,09,1.26,122.2,M,27.0,M,,*53 +{"class":"TPV","tag":"GGA","time":1260369211.500,"ept":0.005,"lat":55.777388000,"lon":23.573823833,"alt":122.200,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.4700,"speed":20.357,"eps":41.92,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.00*07 +$GPGSV,3,1,10,32,22,228,32,09,12,037,26,19,58,203,39,11,36,285,35*7A +$GPGSV,3,2,10,14,45,118,33,03,31,183,19,28,,,31,22,47,070,41*4F +$GPGSV,3,3,10,06,26,174,31,26,44,080,37*72 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.58,"tdop":0.81,"hdop":0.94,"gdop":2.01,"pdop":1.84,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":26,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":19,"used":true},{"PRN":28,"el":0,"az":0,"ss":31,"used":false},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":31,"used":true},{"PRN":26,"el":44,"az":80,"ss":37,"used":true}]} +$GPGLL,5546.64328,N,02334.42943,E,143331.50,A,A*6C +{"class":"TPV","tag":"GLL","time":1260369211.500,"ept":0.005,"lat":55.777388000,"lon":23.573823833,"alt":122.200,"epx":10.479,"epy":9.442,"epv":36.224,"track":221.4700,"speed":20.357,"climb":0.000,"eps":41.92,"mode":3} +$GPZDA,143331.50,09,12,2009,00,00*65 +$GPRMC,143332.00,A,5546.63918,N,02334.42294,E,39.806,221.51,091209,,,A*50 +$GPVTG,221.51,T,,M,39.806,N,73.761,K,A*38 +$GPGGA,143332.00,5546.63918,N,02334.42294,E,1,09,1.26,122.3,M,27.0,M,,*5B +{"class":"TPV","tag":"GGA","time":1260369212.000,"ept":0.005,"lat":55.777319667,"lon":23.573715667,"alt":122.300,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.5100,"speed":20.478,"eps":41.94,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.00*07 +$GPGSV,3,1,10,32,22,228,32,09,12,037,26,19,58,203,38,11,36,285,33*7D +$GPGSV,3,2,10,14,45,118,33,03,31,183,19,28,,,30,22,47,070,40*4F +$GPGSV,3,3,10,06,26,174,31,26,44,080,37*72 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.58,"tdop":0.81,"hdop":0.94,"gdop":2.01,"pdop":1.84,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":26,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":19,"used":true},{"PRN":28,"el":0,"az":0,"ss":30,"used":false},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":26,"az":174,"ss":31,"used":true},{"PRN":26,"el":44,"az":80,"ss":37,"used":true}]} +$GPGLL,5546.63918,N,02334.42294,E,143332.00,A,A*65 +{"class":"TPV","tag":"GLL","time":1260369212.000,"ept":0.005,"lat":55.777319667,"lon":23.573715667,"alt":122.300,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.5100,"speed":20.478,"climb":0.000,"eps":41.94,"mode":3} +$GPZDA,143332.00,09,12,2009,00,00*63 +$GPRMC,143332.50,A,5546.63505,N,02334.41641,E,39.985,221.44,091209,,,A*54 +$GPVTG,221.44,T,,M,39.985,N,74.092,K,A*3A +$GPGGA,143332.50,5546.63505,N,02334.41641,E,1,09,1.26,122.4,M,27.0,M,,*56 +{"class":"TPV","tag":"GGA","time":1260369212.500,"ept":0.005,"lat":55.777250833,"lon":23.573606833,"alt":122.400,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.4400,"speed":20.570,"eps":41.97,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,32,09,12,037,26,19,58,203,38,11,36,285,32*7C +$GPGSV,3,2,10,14,45,118,32,03,31,183,19,28,,,30,22,47,070,40*4E +$GPGSV,3,3,10,06,26,174,31,26,44,080,36*73 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.58,"tdop":0.81,"hdop":0.94,"gdop":2.01,"pdop":1.84,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":26,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":32,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":19,"used":true},{"PRN":28,"el":0,"az":0,"ss":30,"used":false},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":26,"az":174,"ss":31,"used":true},{"PRN":26,"el":44,"az":80,"ss":36,"used":true}]} +$GPGLL,5546.63505,N,02334.41641,E,143332.50,A,A*6F +{"class":"TPV","tag":"GLL","time":1260369212.500,"ept":0.005,"lat":55.777250833,"lon":23.573606833,"alt":122.400,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.4400,"speed":20.570,"climb":0.000,"eps":41.97,"mode":3} +$GPZDA,143332.50,09,12,2009,00,00*66 +$GPRMC,143333.00,A,5546.63089,N,02334.40987,E,40.143,221.52,091209,,,A*5E +$GPVTG,221.52,T,,M,40.143,N,74.385,K,A*34 +$GPGGA,143333.00,5546.63089,N,02334.40987,E,1,09,1.26,122.6,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369213.000,"ept":0.005,"lat":55.777181500,"lon":23.573497833,"alt":122.600,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.5200,"speed":20.651,"eps":41.97,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.00*07 +$GPGSV,3,1,10,32,22,228,31,09,12,037,26,19,58,203,38,11,36,285,32*7F +$GPGSV,3,2,10,14,45,118,32,03,31,183,19,28,,,30,22,47,070,40*4E +$GPGSV,3,3,10,06,26,174,31,26,44,080,36*73 +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.58,"tdop":0.81,"hdop":0.94,"gdop":2.01,"pdop":1.84,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":26,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":32,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":19,"used":true},{"PRN":28,"el":0,"az":0,"ss":30,"used":false},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":26,"az":174,"ss":31,"used":true},{"PRN":26,"el":44,"az":80,"ss":36,"used":true}]} +$GPGLL,5546.63089,N,02334.40987,E,143333.00,A,A*6E +{"class":"TPV","tag":"GLL","time":1260369213.000,"ept":0.005,"lat":55.777181500,"lon":23.573497833,"alt":122.600,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.5200,"speed":20.651,"climb":0.000,"eps":41.97,"mode":3} +$GPZDA,143333.00,09,12,2009,00,00*62 +$GPRMC,143333.50,A,5546.62673,N,02334.40329,E,40.300,221.56,091209,,,A*56 +$GPVTG,221.56,T,,M,40.300,N,74.676,K,A*3C +$GPGGA,143333.50,5546.62673,N,02334.40329,E,1,09,1.26,122.7,M,27.0,M,,*5D +{"class":"TPV","tag":"GGA","time":1260369213.500,"ept":0.005,"lat":55.777112167,"lon":23.573388167,"alt":122.700,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.5600,"speed":20.732,"eps":41.97,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,40,11,36,285,34*75 +$GPGSV,3,2,10,14,45,118,34,03,31,183,19,28,,,31,22,47,070,42*4B +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.58,"tdop":0.81,"hdop":0.94,"gdop":2.01,"pdop":1.84,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":19,"used":true},{"PRN":28,"el":0,"az":0,"ss":31,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.62673,N,02334.40329,E,143333.50,A,A*67 +{"class":"TPV","tag":"GLL","time":1260369213.500,"ept":0.005,"lat":55.777112167,"lon":23.573388167,"alt":122.700,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.5600,"speed":20.732,"climb":0.000,"eps":41.97,"mode":3} +$GPZDA,143333.50,09,12,2009,00,00*67 +$GPRMC,143334.00,A,5546.62247,N,02334.39671,E,40.502,221.59,091209,,,A*5A +$GPVTG,221.59,T,,M,40.502,N,75.050,K,A*34 +$GPGGA,143334.00,5546.62247,N,02334.39671,E,1,09,1.26,122.5,M,27.0,M,,*58 +{"class":"TPV","tag":"GGA","time":1260369214.000,"ept":0.005,"lat":55.777041167,"lon":23.573278500,"alt":122.500,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.5900,"speed":20.836,"eps":41.97,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,40,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,35,03,31,183,20,28,,,31,22,47,070,42*40 +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.58,"tdop":0.81,"hdop":0.94,"gdop":2.01,"pdop":1.84,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":20,"used":true},{"PRN":28,"el":0,"az":0,"ss":31,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.62247,N,02334.39671,E,143334.00,A,A*60 +{"class":"TPV","tag":"GLL","time":1260369214.000,"ept":0.005,"lat":55.777041167,"lon":23.573278500,"alt":122.500,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.5900,"speed":20.836,"climb":0.000,"eps":41.97,"mode":3} +$GPZDA,143334.00,09,12,2009,00,00*65 +$GPRMC,143334.50,A,5546.61820,N,02334.39009,E,40.736,221.63,091209,,,A*52 +$GPVTG,221.63,T,,M,40.736,N,75.483,K,A*32 +$GPGGA,143334.50,5546.61820,N,02334.39009,E,1,09,1.26,122.4,M,27.0,M,,*5D +{"class":"TPV","tag":"GGA","time":1260369214.500,"ept":0.005,"lat":55.776970000,"lon":23.573168167,"alt":122.400,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.6300,"speed":20.956,"eps":41.97,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,40,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,20,28,,,31,22,47,070,42*41 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.58,"tdop":0.81,"hdop":0.94,"gdop":2.01,"pdop":1.84,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":20,"used":true},{"PRN":28,"el":0,"az":0,"ss":31,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.61820,N,02334.39009,E,143334.50,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369214.500,"ept":0.005,"lat":55.776970000,"lon":23.573168167,"alt":122.400,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.6300,"speed":20.956,"climb":0.000,"eps":41.97,"mode":3} +$GPZDA,143334.50,09,12,2009,00,00*60 +$GPRMC,143335.00,A,5546.61392,N,02334.38340,E,40.981,221.79,091209,,,A*52 +$GPVTG,221.79,T,,M,40.981,N,75.938,K,A*36 +$GPGGA,143335.00,5546.61392,N,02334.38340,E,1,09,1.26,122.3,M,27.0,M,,*53 +{"class":"TPV","tag":"GGA","time":1260369215.000,"ept":0.005,"lat":55.776898667,"lon":23.573056667,"alt":122.300,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.7900,"speed":21.082,"eps":41.97,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,32,09,12,037,27,19,58,203,40,11,36,285,35*75 +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,,,32,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.58,"tdop":0.81,"hdop":0.94,"gdop":2.01,"pdop":1.84,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":0,"az":0,"ss":32,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.61392,N,02334.38340,E,143335.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1260369215.000,"ept":0.005,"lat":55.776898667,"lon":23.573056667,"alt":122.300,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.7900,"speed":21.082,"climb":0.000,"eps":41.97,"mode":3} +$GPZDA,143335.00,09,12,2009,00,00*64 +$GPRMC,143335.50,A,5546.60964,N,02334.37668,E,41.196,221.79,091209,,,A*5A +$GPVTG,221.79,T,,M,41.196,N,76.336,K,A*3E +$GPGGA,143335.50,5546.60964,N,02334.37668,E,1,09,1.26,122.3,M,27.0,M,,*54 +{"class":"TPV","tag":"GGA","time":1260369215.500,"ept":0.005,"lat":55.776827333,"lon":23.572944667,"alt":122.300,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.7900,"speed":21.193,"eps":41.97,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.01*06 +$GPGSV,3,1,10,32,22,228,33,09,12,037,28,19,58,203,40,11,36,285,36*78 +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,,,33,22,47,070,42*46 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.58,"tdop":0.81,"hdop":0.94,"gdop":2.01,"pdop":1.84,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":0,"az":0,"ss":33,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.60964,N,02334.37668,E,143335.50,A,A*6A +{"class":"TPV","tag":"GLL","time":1260369215.500,"ept":0.005,"lat":55.776827333,"lon":23.572944667,"alt":122.300,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.7900,"speed":21.193,"climb":0.000,"eps":41.97,"mode":3} +$GPZDA,143335.50,09,12,2009,00,00*61 +$GPRMC,143336.00,A,5546.60535,N,02334.36991,E,41.361,221.94,091209,,,A*55 +$GPVTG,221.94,T,,M,41.361,N,76.642,K,A*31 +$GPGGA,143336.00,5546.60535,N,02334.36991,E,1,09,1.26,122.3,M,27.0,M,,*52 +{"class":"TPV","tag":"GGA","time":1260369216.000,"ept":0.005,"lat":55.776755833,"lon":23.572831833,"alt":122.300,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.9400,"speed":21.278,"eps":41.97,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,22,06,26,,,,3.26,1.26,3.00*07 +$GPGSV,3,1,10,32,22,228,33,09,12,037,28,19,58,203,40,11,36,285,35*7B +$GPGSV,3,2,10,14,45,118,34,03,31,183,25,28,,,34,22,47,070,42*41 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.70,"ydop":0.63,"vdop":1.58,"tdop":0.81,"hdop":0.94,"gdop":2.01,"pdop":1.84,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":25,"used":true},{"PRN":28,"el":0,"az":0,"ss":34,"used":false},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.60535,N,02334.36991,E,143336.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1260369216.000,"ept":0.005,"lat":55.776755833,"lon":23.572831833,"alt":122.300,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.9400,"speed":21.278,"climb":0.000,"eps":41.97,"mode":3} +$GPZDA,143336.00,09,12,2009,00,00*67 +$GPRMC,143336.50,A,5546.60106,N,02334.36309,E,41.477,221.87,091209,,,A*5D +$GPVTG,221.87,T,,M,41.477,N,76.857,K,A*39 +$GPGGA,143336.50,5546.60106,N,02334.36309,E,1,10,1.01,122.3,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369216.500,"ept":0.005,"lat":55.776684333,"lon":23.572718167,"alt":122.300,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.8700,"speed":21.338,"eps":41.97,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,40,11,36,285,36*79 +$GPGSV,3,2,10,14,45,118,34,03,31,183,27,28,19,317,34,22,47,070,42*7E +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":19,"az":317,"ss":34,"used":true},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.60106,N,02334.36309,E,143336.50,A,A*66 +{"class":"TPV","tag":"GLL","time":1260369216.500,"ept":0.005,"lat":55.776684333,"lon":23.572718167,"alt":122.300,"epx":10.493,"epy":9.447,"epv":36.266,"track":221.8700,"speed":21.338,"climb":0.000,"eps":41.97,"mode":3} +$GPZDA,143336.50,09,12,2009,00,00*62 +$GPRMC,143337.00,A,5546.59676,N,02334.35625,E,41.577,221.77,091209,,,A*55 +$GPVTG,221.77,T,,M,41.577,N,77.043,K,A*3B +$GPGGA,143337.00,5546.59676,N,02334.35625,E,1,10,1.01,122.3,M,27.0,M,,*53 +{"class":"TPV","tag":"GGA","time":1260369217.000,"ept":0.005,"lat":55.776612667,"lon":23.572604167,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7700,"speed":21.389,"eps":38.75,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,40,11,36,285,35*7A +$GPGSV,3,2,10,14,45,118,35,03,31,183,27,28,19,317,33,22,47,070,42*78 +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":19,"az":317,"ss":33,"used":true},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.59676,N,02334.35625,E,143337.00,A,A*60 +{"class":"TPV","tag":"GLL","time":1260369217.000,"ept":0.005,"lat":55.776612667,"lon":23.572604167,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7700,"speed":21.389,"climb":0.000,"eps":38.75,"mode":3} +$GPZDA,143337.00,09,12,2009,00,00*66 +$GPRMC,143337.50,A,5546.59244,N,02334.34942,E,41.633,221.86,091209,,,A*57 +$GPVTG,221.86,T,,M,41.633,N,77.146,K,A*32 +$GPGGA,143337.50,5546.59244,N,02334.34942,E,1,10,1.01,122.3,M,27.0,M,,*5C +{"class":"TPV","tag":"GGA","time":1260369217.500,"ept":0.005,"lat":55.776540667,"lon":23.572490333,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8600,"speed":21.418,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,39,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,19,317,32,22,47,070,41*78 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":19,"az":317,"ss":32,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.59244,N,02334.34942,E,143337.50,A,A*6F +{"class":"TPV","tag":"GLL","time":1260369217.500,"ept":0.005,"lat":55.776540667,"lon":23.572490333,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8600,"speed":21.418,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143337.50,09,12,2009,00,00*63 +$GPRMC,143338.00,A,5546.58812,N,02334.34258,E,41.700,221.99,091209,,,A*5A +$GPVTG,221.99,T,,M,41.700,N,77.270,K,A*3B +$GPGGA,143338.00,5546.58812,N,02334.34258,E,1,10,1.01,122.3,M,27.0,M,,*5E +{"class":"TPV","tag":"GGA","time":1260369218.000,"ept":0.005,"lat":55.776468667,"lon":23.572376333,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.9900,"speed":21.452,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,39,11,36,285,35*77 +$GPGSV,3,2,10,14,45,118,34,03,31,183,27,28,19,317,34,22,47,070,41*7D +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":19,"az":317,"ss":34,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.58812,N,02334.34258,E,143338.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1260369218.000,"ept":0.005,"lat":55.776468667,"lon":23.572376333,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.9900,"speed":21.452,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143338.00,09,12,2009,00,00*69 +$GPRMC,143338.50,A,5546.58377,N,02334.33571,E,41.763,222.02,091209,,,A*58 +$GPVTG,222.02,T,,M,41.763,N,77.387,K,A*36 +$GPGGA,143338.50,5546.58377,N,02334.33571,E,1,10,1.01,122.2,M,27.0,M,,*59 +{"class":"TPV","tag":"GGA","time":1260369218.500,"ept":0.005,"lat":55.776396167,"lon":23.572261833,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":222.0200,"speed":21.485,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,39,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,34,03,31,183,27,28,19,317,34,22,47,070,42*7E +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":19,"az":317,"ss":34,"used":true},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.58377,N,02334.33571,E,143338.50,A,A*6B +{"class":"TPV","tag":"GLL","time":1260369218.500,"ept":0.005,"lat":55.776396167,"lon":23.572261833,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":222.0200,"speed":21.485,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143338.50,09,12,2009,00,00*6C +$GPRMC,143339.00,A,5546.57941,N,02334.32886,E,41.810,221.70,091209,,,A*55 +$GPVTG,221.70,T,,M,41.810,N,77.474,K,A*30 +$GPGGA,143339.00,5546.57941,N,02334.32886,E,1,10,1.01,122.2,M,27.0,M,,*59 +{"class":"TPV","tag":"GGA","time":1260369219.000,"ept":0.005,"lat":55.776323500,"lon":23.572147667,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7000,"speed":21.509,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,39,11,36,285,36*77 +$GPGSV,3,2,10,14,45,118,34,03,31,183,27,28,19,317,34,22,47,070,42*7E +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":19,"az":317,"ss":34,"used":true},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.57941,N,02334.32886,E,143339.00,A,A*6B +{"class":"TPV","tag":"GLL","time":1260369219.000,"ept":0.005,"lat":55.776323500,"lon":23.572147667,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7000,"speed":21.509,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143339.00,09,12,2009,00,00*68 +$GPRMC,143339.50,A,5546.57509,N,02334.32202,E,41.805,221.61,091209,,,A*52 +$GPVTG,221.61,T,,M,41.805,N,77.464,K,A*35 +$GPGGA,143339.50,5546.57509,N,02334.32202,E,1,10,1.22,122.4,M,27.0,M,,*5D +{"class":"TPV","tag":"GGA","time":1260369219.500,"ept":0.005,"lat":55.776251500,"lon":23.572033667,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6100,"speed":21.506,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.23,1.22,2.99*0D +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,40,11,36,285,36*79 +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,19,317,34,22,47,070,42*7C +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":36,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":19,"az":317,"ss":34,"used":true},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.57509,N,02334.32202,E,143339.50,A,A*68 +{"class":"TPV","tag":"GLL","time":1260369219.500,"ept":0.005,"lat":55.776251500,"lon":23.572033667,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6100,"speed":21.506,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143339.50,09,12,2009,00,00*6D +$GPRMC,143340.00,A,5546.57072,N,02334.31519,E,41.831,221.43,091209,,,A*59 +$GPVTG,221.43,T,,M,41.831,N,77.512,K,A*32 +$GPGGA,143340.00,5546.57072,N,02334.31519,E,1,10,1.01,122.4,M,27.0,M,,*50 +{"class":"TPV","tag":"GGA","time":1260369220.000,"ept":0.005,"lat":55.776178667,"lon":23.571919833,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.4300,"speed":21.520,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,27,19,58,203,40,11,36,285,35*75 +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,19,317,32,22,47,070,42*7A +$GPGSV,3,3,10,06,26,174,34,26,44,080,38*78 +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":19,"az":317,"ss":32,"used":true},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":34,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.57072,N,02334.31519,E,143340.00,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369220.000,"ept":0.005,"lat":55.776178667,"lon":23.571919833,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.4300,"speed":21.520,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143340.00,09,12,2009,00,00*66 +$GPRMC,143340.50,A,5546.56636,N,02334.30835,E,41.860,221.62,091209,,,A*5E +$GPVTG,221.62,T,,M,41.860,N,77.566,K,A*36 +$GPGGA,143340.50,5546.56636,N,02334.30835,E,1,10,1.01,122.3,M,27.0,M,,*57 +{"class":"TPV","tag":"GGA","time":1260369220.500,"ept":0.005,"lat":55.776106000,"lon":23.571805833,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6200,"speed":21.535,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,39,11,36,285,35*7A +$GPGSV,3,2,10,14,45,118,34,03,31,183,23,28,19,317,32,22,47,070,41*7F +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":23,"used":true},{"PRN":28,"el":19,"az":317,"ss":32,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.56636,N,02334.30835,E,143340.50,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369220.500,"ept":0.005,"lat":55.776106000,"lon":23.571805833,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6200,"speed":21.535,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143340.50,09,12,2009,00,00*63 +$GPRMC,143341.00,A,5546.56202,N,02334.30147,E,41.947,221.64,091209,,,A*57 +$GPVTG,221.64,T,,M,41.947,N,77.727,K,A*33 +$GPGGA,143341.00,5546.56202,N,02334.30147,E,1,10,1.01,122.4,M,27.0,M,,*5B +{"class":"TPV","tag":"GGA","time":1260369221.000,"ept":0.005,"lat":55.776033667,"lon":23.571691167,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6400,"speed":21.579,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,40,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,19,317,33,22,47,070,41*79 +$GPGSV,3,3,10,06,26,174,33,26,44,080,38*7F +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":19,"az":317,"ss":33,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.56202,N,02334.30147,E,143341.00,A,A*6F +{"class":"TPV","tag":"GLL","time":1260369221.000,"ept":0.005,"lat":55.776033667,"lon":23.571691167,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6400,"speed":21.579,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143341.00,09,12,2009,00,00*67 +$GPRMC,143341.50,A,5546.55766,N,02334.29457,E,41.998,221.76,091209,,,A*5B +$GPVTG,221.76,T,,M,41.998,N,77.822,K,A*38 +$GPGGA,143341.50,5546.55766,N,02334.29457,E,1,10,1.01,122.3,M,27.0,M,,*51 +{"class":"TPV","tag":"GGA","time":1260369221.500,"ept":0.005,"lat":55.775961000,"lon":23.571576167,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7600,"speed":21.606,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,40,11,36,285,35*74 +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,19,317,35,22,47,070,42*7C +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":19,"az":317,"ss":35,"used":true},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.55766,N,02334.29457,E,143341.50,A,A*62 +{"class":"TPV","tag":"GLL","time":1260369221.500,"ept":0.005,"lat":55.775961000,"lon":23.571576167,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7600,"speed":21.606,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143341.50,09,12,2009,00,00*62 +$GPRMC,143342.00,A,5546.55331,N,02334.28765,E,42.085,221.64,091209,,,A*5D +$GPVTG,221.64,T,,M,42.085,N,77.984,K,A*30 +$GPGGA,143342.00,5546.55331,N,02334.28765,E,1,10,1.01,122.4,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369222.000,"ept":0.005,"lat":55.775888500,"lon":23.571460833,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6400,"speed":21.650,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,34,09,12,037,27,19,58,203,40,11,36,285,35*73 +$GPGSV,3,2,10,14,45,118,35,03,31,183,24,28,19,317,34,22,47,070,42*7C +$GPGSV,3,3,10,06,26,174,33,26,44,080,39*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":40,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":35,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":19,"az":317,"ss":34,"used":true},{"PRN":22,"el":47,"az":70,"ss":42,"used":true},{"PRN":6,"el":26,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":39,"used":true}]} +$GPGLL,5546.55331,N,02334.28765,E,143342.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1260369222.000,"ept":0.005,"lat":55.775888500,"lon":23.571460833,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6400,"speed":21.650,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143342.00,09,12,2009,00,00*64 +$GPRMC,143342.50,A,5546.54894,N,02334.28072,E,42.096,221.79,091209,,,A*52 +$GPVTG,221.79,T,,M,42.096,N,78.004,K,A*30 +$GPGGA,143342.50,5546.54894,N,02334.28072,E,1,10,1.01,122.4,M,27.0,M,,*54 +{"class":"TPV","tag":"GGA","time":1260369222.500,"ept":0.005,"lat":55.775815667,"lon":23.571345333,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7900,"speed":21.656,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,34,09,12,037,27,19,58,203,39,11,36,285,35*7D +$GPGSV,3,2,10,14,45,118,34,03,31,183,26,28,19,317,33,22,47,070,41*7B +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":26,"used":true},{"PRN":28,"el":19,"az":317,"ss":33,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.54894,N,02334.28072,E,143342.50,A,A*60 +{"class":"TPV","tag":"GLL","time":1260369222.500,"ept":0.005,"lat":55.775815667,"lon":23.571345333,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7900,"speed":21.656,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143342.50,09,12,2009,00,00*61 +$GPRMC,143343.00,A,5546.54457,N,02334.27380,E,42.128,221.81,091209,,,A*57 +$GPVTG,221.81,T,,M,42.128,N,78.064,K,A*35 +$GPGGA,143343.00,5546.54457,N,02334.27380,E,1,10,1.01,122.4,M,27.0,M,,*52 +{"class":"TPV","tag":"GGA","time":1260369223.000,"ept":0.005,"lat":55.775742833,"lon":23.571230000,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8100,"speed":21.673,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,34,09,12,037,27,19,58,203,39,11,36,285,35*7D +$GPGSV,3,2,10,14,45,118,34,03,31,183,26,28,19,317,32,22,47,070,41*7A +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":26,"used":true},{"PRN":28,"el":19,"az":317,"ss":32,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.54457,N,02334.27380,E,143343.00,A,A*66 +{"class":"TPV","tag":"GLL","time":1260369223.000,"ept":0.005,"lat":55.775742833,"lon":23.571230000,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8100,"speed":21.673,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143343.00,09,12,2009,00,00*65 +$GPRMC,143343.50,A,5546.54019,N,02334.26687,E,42.223,221.67,091209,,,A*5F +$GPVTG,221.67,T,,M,42.223,N,78.240,K,A*31 +$GPGGA,143343.50,5546.54019,N,02334.26687,E,1,10,1.26,122.5,M,27.0,M,,*5E +{"class":"TPV","tag":"GGA","time":1260369223.500,"ept":0.005,"lat":55.775669833,"lon":23.571114500,"alt":122.500,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6700,"speed":21.721,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,34,09,12,037,27,19,58,203,39,11,36,285,35*7D +$GPGSV,3,2,10,14,45,118,34,03,31,183,23,28,19,317,31,22,47,070,41*7C +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":34,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":35,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":23,"used":true},{"PRN":28,"el":19,"az":317,"ss":31,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.54019,N,02334.26687,E,143343.50,A,A*6E +{"class":"TPV","tag":"GLL","time":1260369223.500,"ept":0.005,"lat":55.775669833,"lon":23.571114500,"alt":122.500,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6700,"speed":21.721,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143343.50,09,12,2009,00,00*60 +$GPRMC,143344.00,A,5546.53579,N,02334.25993,E,42.261,221.65,091209,,,A*54 +$GPVTG,221.65,T,,M,42.261,N,78.309,K,A*39 +$GPGGA,143344.00,5546.53579,N,02334.25993,E,1,10,1.01,122.4,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369224.000,"ept":0.005,"lat":55.775596500,"lon":23.570998833,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6500,"speed":21.741,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,39,11,36,285,34*7B +$GPGSV,3,2,10,14,45,118,34,03,31,183,24,28,19,317,32,22,47,070,41*78 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":24,"used":true},{"PRN":28,"el":19,"az":317,"ss":32,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.53579,N,02334.25993,E,143344.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1260369224.000,"ept":0.005,"lat":55.775596500,"lon":23.570998833,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6500,"speed":21.741,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143344.00,09,12,2009,00,00*62 +$GPRMC,143344.50,A,5546.53138,N,02334.25301,E,42.303,221.61,091209,,,A*50 +$GPVTG,221.61,T,,M,42.303,N,78.388,K,A*31 +$GPGGA,143344.50,5546.53138,N,02334.25301,E,1,10,1.01,122.3,M,27.0,M,,*57 +{"class":"TPV","tag":"GGA","time":1260369224.500,"ept":0.005,"lat":55.775523000,"lon":23.570883500,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6100,"speed":21.763,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,33,09,12,037,27,19,58,203,39,11,36,285,34*7B +$GPGSV,3,2,10,14,45,118,34,03,31,183,28,28,19,317,32,22,47,070,41*74 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":33,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":32,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.53138,N,02334.25301,E,143344.50,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369224.500,"ept":0.005,"lat":55.775523000,"lon":23.570883500,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6100,"speed":21.763,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143344.50,09,12,2009,00,00*67 +$GPRMC,143345.00,A,5546.52698,N,02334.24607,E,42.393,221.82,091209,,,A*5E +$GPVTG,221.82,T,,M,42.393,N,78.553,K,A*35 +$GPGGA,143345.00,5546.52698,N,02334.24607,E,1,10,1.01,122.2,M,27.0,M,,*5C +{"class":"TPV","tag":"GGA","time":1260369225.000,"ept":0.005,"lat":55.775449667,"lon":23.570767833,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8200,"speed":21.809,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,39,11,36,285,33*72 +$GPGSV,3,2,10,14,45,118,34,03,31,183,28,28,19,317,31,22,47,070,41*77 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":34,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":31,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.52698,N,02334.24607,E,143345.00,A,A*6E +{"class":"TPV","tag":"GLL","time":1260369225.000,"ept":0.005,"lat":55.775449667,"lon":23.570767833,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8200,"speed":21.809,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143345.00,09,12,2009,00,00*63 +$GPRMC,143345.50,A,5546.52259,N,02334.23909,E,42.434,221.88,091209,,,A*54 +$GPVTG,221.88,T,,M,42.434,N,78.630,K,A*33 +$GPGGA,143345.50,5546.52259,N,02334.23909,E,1,10,1.01,122.1,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369225.500,"ept":0.005,"lat":55.775376500,"lon":23.570651500,"alt":122.100,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8800,"speed":21.830,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,2.66,1.01,2.46*0E +$GPGSV,3,1,10,32,22,228,32,09,12,037,27,19,58,203,39,11,36,285,32*7C +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,31,22,47,070,41*70 +$GPGSV,3,3,10,06,26,174,32,26,44,080,37*71 +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":32,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":31,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":37,"used":true}]} +$GPGLL,5546.52259,N,02334.23909,E,143345.50,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369225.500,"ept":0.005,"lat":55.775376500,"lon":23.570651500,"alt":122.100,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8800,"speed":21.830,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143345.50,09,12,2009,00,00*66 +$GPRMC,143346.00,A,5546.51820,N,02334.23212,E,42.324,221.82,091209,,,A*58 +$GPVTG,221.82,T,,M,42.324,N,78.426,K,A*3A +$GPGGA,143346.00,5546.51820,N,02334.23212,E,1,10,1.26,122.2,M,27.0,M,,*53 +{"class":"TPV","tag":"GGA","time":1260369226.000,"ept":0.005,"lat":55.775303333,"lon":23.570535333,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8200,"speed":21.773,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,27,19,58,203,38,11,36,285,32*7E +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,30,22,47,070,40*70 +$GPGSV,3,3,10,06,26,174,32,26,44,080,37*71 +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":32,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":30,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":37,"used":true}]} +$GPGLL,5546.51820,N,02334.23212,E,143346.00,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369226.000,"ept":0.005,"lat":55.775303333,"lon":23.570535333,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8200,"speed":21.773,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143346.00,09,12,2009,00,00*60 +$GPRMC,143346.50,A,5546.51382,N,02334.22519,E,42.016,221.97,091209,,,A*55 +$GPVTG,221.97,T,,M,42.016,N,77.855,K,A*3B +$GPGGA,143346.50,5546.51382,N,02334.22519,E,1,10,1.26,122.2,M,27.0,M,,*58 +{"class":"TPV","tag":"GGA","time":1260369226.500,"ept":0.005,"lat":55.775230333,"lon":23.570419833,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.9700,"speed":21.615,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,30,09,12,037,28,19,58,203,39,11,36,285,33*70 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,30,22,47,070,40*70 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":30,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":30,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.51382,N,02334.22519,E,143346.50,A,A*6F +{"class":"TPV","tag":"GLL","time":1260369226.500,"ept":0.005,"lat":55.775230333,"lon":23.570419833,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.9700,"speed":21.615,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143346.50,09,12,2009,00,00*65 +$GPRMC,143347.00,A,5546.50947,N,02334.21831,E,41.750,221.78,091209,,,A*50 +$GPVTG,221.78,T,,M,41.750,N,77.363,K,A*32 +$GPGGA,143347.00,5546.50947,N,02334.21831,E,1,10,1.26,122.2,M,27.0,M,,*5A +{"class":"TPV","tag":"GGA","time":1260369227.000,"ept":0.005,"lat":55.775157833,"lon":23.570305167,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7800,"speed":21.478,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,39,11,36,285,33*71 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,30,22,47,070,41*71 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":30,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.50947,N,02334.21831,E,143347.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1260369227.000,"ept":0.005,"lat":55.775157833,"lon":23.570305167,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7800,"speed":21.478,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143347.00,09,12,2009,00,00*61 +$GPRMC,143347.50,A,5546.50515,N,02334.21149,E,41.450,221.70,091209,,,A*53 +$GPVTG,221.70,T,,M,41.450,N,76.806,K,A*30 +$GPGGA,143347.50,5546.50515,N,02334.21149,E,1,10,1.90,122.2,M,27.0,M,,*5F +{"class":"TPV","tag":"GGA","time":1260369227.500,"ept":0.005,"lat":55.775085833,"lon":23.570191500,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7000,"speed":21.324,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.58,1.90,3.04*0D +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,39,11,36,285,33*71 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,30,22,47,070,40*70 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":30,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.50515,N,02334.21149,E,143347.50,A,A*65 +{"class":"TPV","tag":"GLL","time":1260369227.500,"ept":0.005,"lat":55.775085833,"lon":23.570191500,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.7000,"speed":21.324,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143347.50,09,12,2009,00,00*64 +$GPRMC,143348.00,A,5546.50086,N,02334.20472,E,41.139,221.46,091209,,,A*55 +$GPVTG,221.46,T,,M,41.139,N,76.231,K,A*31 +$GPGGA,143348.00,5546.50086,N,02334.20472,E,1,10,1.26,122.2,M,27.0,M,,*5B +{"class":"TPV","tag":"GGA","time":1260369228.000,"ept":0.005,"lat":55.775014333,"lon":23.570078667,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.4600,"speed":21.164,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,30,09,12,037,27,19,58,203,38,11,36,285,33*7E +$GPGSV,3,2,10,14,45,118,33,03,31,183,27,28,19,317,30,22,47,070,41*7E +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":30,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":19,"az":317,"ss":30,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.50086,N,02334.20472,E,143348.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1260369228.000,"ept":0.005,"lat":55.775014333,"lon":23.570078667,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.4600,"speed":21.164,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143348.00,09,12,2009,00,00*6E +$GPRMC,143348.50,A,5546.49657,N,02334.19806,E,40.840,221.86,091209,,,A*5D +$GPVTG,221.86,T,,M,40.840,N,75.676,K,A*3F +$GPGGA,143348.50,5546.49657,N,02334.19806,E,1,10,1.26,122.2,M,27.0,M,,*59 +{"class":"TPV","tag":"GGA","time":1260369228.500,"ept":0.005,"lat":55.774942833,"lon":23.569967667,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8600,"speed":21.010,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,38,11,36,285,33*70 +$GPGSV,3,2,10,14,45,118,33,03,31,183,27,28,19,317,30,22,47,070,40*7F +$GPGSV,3,3,10,06,26,174,32,26,44,080,37*71 +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":19,"az":317,"ss":30,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":37,"used":true}]} +$GPGLL,5546.49657,N,02334.19806,E,143348.50,A,A*6E +{"class":"TPV","tag":"GLL","time":1260369228.500,"ept":0.005,"lat":55.774942833,"lon":23.569967667,"alt":122.200,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.8600,"speed":21.010,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143348.50,09,12,2009,00,00*6B +$GPRMC,143349.00,A,5546.49236,N,02334.19138,E,40.570,221.54,091209,,,A*5F +$GPVTG,221.54,T,,M,40.570,N,75.176,K,A*39 +$GPGGA,143349.00,5546.49236,N,02334.19138,E,1,10,1.26,122.3,M,27.0,M,,*5B +{"class":"TPV","tag":"GGA","time":1260369229.000,"ept":0.005,"lat":55.774872667,"lon":23.569856333,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.5400,"speed":20.871,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,39,11,36,285,34*76 +$GPGSV,3,2,10,14,45,118,32,03,31,183,28,28,19,317,30,22,47,070,41*70 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":30,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.49236,N,02334.19138,E,143349.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1260369229.000,"ept":0.005,"lat":55.774872667,"lon":23.569856333,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.5400,"speed":20.871,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143349.00,09,12,2009,00,00*6F +$GPRMC,143349.50,A,5546.48814,N,02334.18482,E,40.283,221.44,091209,,,A*5E +$GPVTG,221.44,T,,M,40.283,N,74.645,K,A*35 +$GPGGA,143349.50,5546.48814,N,02334.18482,E,1,10,1.26,122.3,M,27.0,M,,*50 +{"class":"TPV","tag":"GGA","time":1260369229.500,"ept":0.005,"lat":55.774802333,"lon":23.569747000,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.4400,"speed":20.723,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,27,19,58,203,39,11,36,285,34*79 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,30,22,47,070,41*71 +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":30,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.48814,N,02334.18482,E,143349.50,A,A*66 +{"class":"TPV","tag":"GLL","time":1260369229.500,"ept":0.005,"lat":55.774802333,"lon":23.569747000,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.4400,"speed":20.723,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143349.50,09,12,2009,00,00*6A +$GPRMC,143350.00,A,5546.48395,N,02334.17830,E,39.946,221.60,091209,,,A*51 +$GPVTG,221.60,T,,M,39.946,N,74.020,K,A*3A +$GPGGA,143350.00,5546.48395,N,02334.17830,E,1,10,1.26,122.3,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369230.000,"ept":0.005,"lat":55.774732500,"lon":23.569638333,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6000,"speed":20.550,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,27,19,58,203,39,11,36,285,34*79 +$GPGSV,3,2,10,14,45,118,32,03,31,183,27,28,19,317,30,22,47,070,41*7F +$GPGSV,3,3,10,06,26,174,32,26,44,080,38*7E +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.78,"tdop":0.99,"hdop":0.83,"gdop":2.20,"pdop":1.96,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":39,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":19,"az":317,"ss":30,"used":true},{"PRN":22,"el":47,"az":70,"ss":41,"used":true},{"PRN":6,"el":26,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.48395,N,02334.17830,E,143350.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1260369230.000,"ept":0.005,"lat":55.774732500,"lon":23.569638333,"alt":122.300,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.6000,"speed":20.550,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143350.00,09,12,2009,00,00*67 +$GPRMC,143350.50,A,5546.47981,N,02334.17183,E,39.607,221.50,091209,,,A*5C +$GPVTG,221.50,T,,M,39.607,N,73.391,K,A*3D +$GPGGA,143350.50,5546.47981,N,02334.17183,E,1,10,1.26,122.4,M,27.0,M,,*56 +{"class":"TPV","tag":"GGA","time":1260369230.500,"ept":0.005,"lat":55.774663500,"lon":23.569530500,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.5000,"speed":20.376,"eps":35.52,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,27,19,58,203,38,11,36,285,33*7F +$GPGSV,3,2,10,14,45,118,32,03,31,183,28,28,19,317,29,22,47,070,40*79 +$GPGSV,3,3,10,06,25,174,32,26,44,080,38*7D +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.76,"tdop":0.98,"hdop":0.83,"gdop":2.18,"pdop":1.94,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":29,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":25,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.47981,N,02334.17183,E,143350.50,A,A*67 +{"class":"TPV","tag":"GLL","time":1260369230.500,"ept":0.005,"lat":55.774663500,"lon":23.569530500,"alt":122.400,"epx":8.881,"epy":8.766,"epv":40.887,"track":221.5000,"speed":20.376,"climb":0.000,"eps":35.52,"mode":3} +$GPZDA,143350.50,09,12,2009,00,00*62 +$GPRMC,143351.00,A,5546.47570,N,02334.16543,E,39.198,221.80,091209,,,A*5F +$GPVTG,221.80,T,,M,39.198,N,72.634,K,A*3A +$GPGGA,143351.00,5546.47570,N,02334.16543,E,1,10,1.26,122.5,M,27.0,M,,*58 +{"class":"TPV","tag":"GGA","time":1260369231.000,"ept":0.005,"lat":55.774595000,"lon":23.569423833,"alt":122.500,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.8000,"speed":20.165,"eps":35.49,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,32,09,12,037,27,19,58,203,38,11,36,285,33*7C +$GPGSV,3,2,10,14,45,118,32,03,31,183,27,28,19,317,29,22,47,070,40*76 +$GPGSV,3,3,10,06,25,174,33,26,44,080,38*7C +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.76,"tdop":0.98,"hdop":0.83,"gdop":2.18,"pdop":1.94,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":27,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":27,"used":true},{"PRN":28,"el":19,"az":317,"ss":29,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":25,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.47570,N,02334.16543,E,143351.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1260369231.000,"ept":0.005,"lat":55.774595000,"lon":23.569423833,"alt":122.500,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.8000,"speed":20.165,"climb":0.000,"eps":35.49,"mode":3} +$GPZDA,143351.00,09,12,2009,00,00*66 +$GPRMC,143351.50,A,5546.47167,N,02334.15908,E,38.658,221.91,091209,,,A*52 +$GPVTG,221.91,T,,M,38.658,N,71.633,K,A*34 +$GPGGA,143351.50,5546.47167,N,02334.15908,E,1,10,1.26,122.6,M,27.0,M,,*5C +{"class":"TPV","tag":"GGA","time":1260369231.500,"ept":0.005,"lat":55.774527833,"lon":23.569318000,"alt":122.600,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.9100,"speed":19.887,"eps":35.46,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,38,11,36,285,33*73 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,29,22,47,070,40*78 +$GPGSV,3,3,10,06,25,174,33,26,44,080,38*7C +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.76,"tdop":0.98,"hdop":0.83,"gdop":2.18,"pdop":1.94,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":29,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":25,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.47167,N,02334.15908,E,143351.50,A,A*6F +{"class":"TPV","tag":"GLL","time":1260369231.500,"ept":0.005,"lat":55.774527833,"lon":23.569318000,"alt":122.600,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.9100,"speed":19.887,"climb":0.000,"eps":35.46,"mode":3} +$GPZDA,143351.50,09,12,2009,00,00*63 +$GPRMC,143352.00,A,5546.46768,N,02334.15280,E,38.178,222.25,091209,,,A*5E +$GPVTG,222.25,T,,M,38.178,N,70.744,K,A*3D +$GPGGA,143352.00,5546.46768,N,02334.15280,E,1,10,1.25,122.7,M,27.0,M,,*5B +{"class":"TPV","tag":"GGA","time":1260369232.000,"ept":0.005,"lat":55.774461333,"lon":23.569213333,"alt":122.700,"epx":8.864,"epy":8.704,"epv":40.461,"track":222.2500,"speed":19.640,"eps":35.46,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.25,3.01*0F +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,38,11,36,285,34*74 +$GPGSV,3,2,10,14,45,118,32,03,31,183,28,28,19,317,29,22,47,070,40*79 +$GPGSV,3,3,10,06,25,174,33,26,44,080,38*7C +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.76,"tdop":0.98,"hdop":0.83,"gdop":2.18,"pdop":1.94,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":29,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":25,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.46768,N,02334.15280,E,143352.00,A,A*6A +{"class":"TPV","tag":"GLL","time":1260369232.000,"ept":0.005,"lat":55.774461333,"lon":23.569213333,"alt":122.700,"epx":8.864,"epy":8.704,"epv":40.461,"track":222.2500,"speed":19.640,"climb":0.000,"eps":35.46,"mode":3} +$GPZDA,143352.00,09,12,2009,00,00*65 +$GPRMC,143352.50,A,5546.46376,N,02334.14654,E,37.932,221.95,091209,,,A*5D +$GPVTG,221.95,T,,M,37.932,N,70.288,K,A*39 +$GPGGA,143352.50,5546.46376,N,02334.14654,E,1,10,1.26,122.8,M,27.0,M,,*55 +{"class":"TPV","tag":"GGA","time":1260369232.500,"ept":0.005,"lat":55.774396000,"lon":23.569109000,"alt":122.800,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.9500,"speed":19.514,"eps":35.46,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,30,09,12,037,28,19,58,203,38,11,36,285,34*76 +$GPGSV,3,2,10,14,45,118,32,03,31,183,28,28,19,317,29,22,47,070,40*79 +$GPGSV,3,3,10,06,25,174,33,26,44,080,38*7C +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.76,"tdop":0.98,"hdop":0.83,"gdop":2.18,"pdop":1.94,"satellites":[{"PRN":32,"el":22,"az":228,"ss":30,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":29,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":25,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.46376,N,02334.14654,E,143352.50,A,A*68 +{"class":"TPV","tag":"GLL","time":1260369232.500,"ept":0.005,"lat":55.774396000,"lon":23.569109000,"alt":122.800,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.9500,"speed":19.514,"climb":0.000,"eps":35.46,"mode":3} +$GPZDA,143352.50,09,12,2009,00,00*60 +$GPRMC,143353.00,A,5546.45986,N,02334.14036,E,37.561,221.99,091209,,,A*5B +$GPVTG,221.99,T,,M,37.561,N,69.601,K,A*32 +$GPGGA,143353.00,5546.45986,N,02334.14036,E,1,10,1.26,123.0,M,27.0,M,,*5C +{"class":"TPV","tag":"GGA","time":1260369233.000,"ept":0.005,"lat":55.774331000,"lon":23.569006000,"alt":123.000,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.9900,"speed":19.323,"eps":35.46,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,38,11,36,285,33*70 +$GPGSV,3,2,10,14,45,118,32,03,31,183,29,28,19,317,29,22,47,070,40*78 +$GPGSV,3,3,10,06,25,174,33,26,44,080,38*7C +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.76,"tdop":0.98,"hdop":0.83,"gdop":2.18,"pdop":1.94,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":29,"used":true},{"PRN":28,"el":19,"az":317,"ss":29,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":25,"az":174,"ss":33,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.45986,N,02334.14036,E,143353.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1260369233.000,"ept":0.005,"lat":55.774331000,"lon":23.569006000,"alt":123.000,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.9900,"speed":19.323,"climb":0.000,"eps":35.46,"mode":3} +$GPZDA,143353.00,09,12,2009,00,00*64 +$GPRMC,143353.50,A,5546.45601,N,02334.13425,E,36.999,221.72,091209,,,A*50 +$GPVTG,221.72,T,,M,36.999,N,68.559,K,A*32 +$GPGGA,143353.50,5546.45601,N,02334.13425,E,1,10,1.26,123.1,M,27.0,M,,*59 +{"class":"TPV","tag":"GGA","time":1260369233.500,"ept":0.005,"lat":55.774266833,"lon":23.568904167,"alt":123.100,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.7200,"speed":19.034,"eps":35.46,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,38,11,36,285,33*73 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,29,22,47,070,40*78 +$GPGSV,3,3,10,06,25,174,32,26,44,080,38*7D +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.76,"tdop":0.98,"hdop":0.83,"gdop":2.18,"pdop":1.94,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":29,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":25,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.45601,N,02334.13425,E,143353.50,A,A*6C +{"class":"TPV","tag":"GLL","time":1260369233.500,"ept":0.005,"lat":55.774266833,"lon":23.568904167,"alt":123.100,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.7200,"speed":19.034,"climb":0.000,"eps":35.46,"mode":3} +$GPZDA,143353.50,09,12,2009,00,00*61 +$GPRMC,143354.00,A,5546.45220,N,02334.12827,E,36.320,221.89,091209,,,A*56 +$GPVTG,221.89,T,,M,36.320,N,67.300,K,A*3B +$GPGGA,143354.00,5546.45220,N,02334.12827,E,1,10,1.26,123.3,M,27.0,M,,*51 +{"class":"TPV","tag":"GGA","time":1260369234.000,"ept":0.005,"lat":55.774203333,"lon":23.568804500,"alt":123.300,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.8900,"speed":18.685,"eps":35.46,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,38,11,36,285,33*70 +$GPGSV,3,2,10,14,45,118,32,03,31,183,28,28,19,317,29,22,47,070,40*79 +$GPGSV,3,3,10,06,25,174,32,26,44,080,38*7D +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.76,"tdop":0.98,"hdop":0.83,"gdop":2.18,"pdop":1.94,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":33,"used":true},{"PRN":14,"el":45,"az":118,"ss":32,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":29,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":25,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.45220,N,02334.12827,E,143354.00,A,A*66 +{"class":"TPV","tag":"GLL","time":1260369234.000,"ept":0.005,"lat":55.774203333,"lon":23.568804500,"alt":123.300,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.8900,"speed":18.685,"climb":0.000,"eps":35.46,"mode":3} +$GPZDA,143354.00,09,12,2009,00,00*63 +$GPRMC,143354.50,A,5546.44845,N,02334.12240,E,35.710,221.48,091209,,,A*59 +$GPVTG,221.48,T,,M,35.710,N,66.170,K,A*36 +$GPGGA,143354.50,5546.44845,N,02334.12240,E,1,10,1.26,123.5,M,27.0,M,,*51 +{"class":"TPV","tag":"GGA","time":1260369234.500,"ept":0.005,"lat":55.774140833,"lon":23.568706667,"alt":123.500,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.4800,"speed":18.371,"eps":35.46,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.26,3.01*0C +$GPGSV,3,1,10,32,22,228,31,09,12,037,28,19,58,203,38,11,36,285,34*77 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,29,22,47,070,40*78 +$GPGSV,3,3,10,06,25,174,32,26,44,080,37*72 +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.76,"tdop":0.98,"hdop":0.83,"gdop":2.18,"pdop":1.94,"satellites":[{"PRN":32,"el":22,"az":228,"ss":31,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":29,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":25,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":37,"used":true}]} +$GPGLL,5546.44845,N,02334.12240,E,143354.50,A,A*60 +{"class":"TPV","tag":"GLL","time":1260369234.500,"ept":0.005,"lat":55.774140833,"lon":23.568706667,"alt":123.500,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.4800,"speed":18.371,"climb":0.000,"eps":35.46,"mode":3} +$GPZDA,143354.50,09,12,2009,00,00*66 +$GPRMC,143355.00,A,5546.44478,N,02334.11667,E,34.871,221.47,091209,,,A*5B +$GPVTG,221.47,T,,M,34.871,N,64.615,K,A*36 +$GPGGA,143355.00,5546.44478,N,02334.11667,E,1,10,1.25,123.5,M,27.0,M,,*56 +{"class":"TPV","tag":"GGA","time":1260369235.000,"ept":0.005,"lat":55.774079667,"lon":23.568611167,"alt":123.500,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.4700,"speed":17.939,"eps":35.46,"mode":3} +$GPGSA,A,3,32,09,19,11,14,03,28,22,06,26,,,3.26,1.25,3.01*0F +$GPGSV,3,1,10,32,22,228,32,09,12,037,28,19,58,203,38,11,36,285,34*74 +$GPGSV,3,2,10,14,45,118,33,03,31,183,28,28,19,317,29,22,47,070,40*78 +$GPGSV,3,3,10,06,25,174,32,26,44,080,38*7D +{"class":"SKY","tag":"GSV","xdop":0.59,"ydop":0.58,"vdop":1.76,"tdop":0.98,"hdop":0.83,"gdop":2.18,"pdop":1.94,"satellites":[{"PRN":32,"el":22,"az":228,"ss":32,"used":true},{"PRN":9,"el":12,"az":37,"ss":28,"used":true},{"PRN":19,"el":58,"az":203,"ss":38,"used":true},{"PRN":11,"el":36,"az":285,"ss":34,"used":true},{"PRN":14,"el":45,"az":118,"ss":33,"used":true},{"PRN":3,"el":31,"az":183,"ss":28,"used":true},{"PRN":28,"el":19,"az":317,"ss":29,"used":true},{"PRN":22,"el":47,"az":70,"ss":40,"used":true},{"PRN":6,"el":25,"az":174,"ss":32,"used":true},{"PRN":26,"el":44,"az":80,"ss":38,"used":true}]} +$GPGLL,5546.44478,N,02334.11667,E,143355.00,A,A*64 +{"class":"TPV","tag":"GLL","time":1260369235.000,"ept":0.005,"lat":55.774079667,"lon":23.568611167,"alt":123.500,"epx":8.864,"epy":8.704,"epv":40.461,"track":221.4700,"speed":17.939,"climb":0.000,"eps":35.46,"mode":3} +$GPZDA,143355.00,09,12,2009,00,00*62 diff --git a/test/daemon/bu303-climbing.log b/test/daemon/bu303-climbing.log new file mode 100644 index 0000000000000000000000000000000000000000..83ca2fdcdf51e2753a8b32b55fd4859542c3badd GIT binary patch literal 12942 zcmciJ3vgUj83*vYA+56hvoL|20eCM1?NbO1wWjfTgSD0tDpQUPD8&|cjGOy5mA+>XBcH3Ac*P(W2 zFI#7>UynoGFX$b?s<+yl?AZHmIJTPWD6_)bZPg6>bB95>oa{h+_e^a zxy863PuX9ryEr%l`*vrpkg)1lhd>RqqgtW>S+QL1Y0 z70)TI8r<@(bf|RaIFTPQk!fRb)e+3&~8BnIoglQ&|Nki8>u^#N2rjam`W<1nn1aNUQ8i{FIRBiSj zSs{M8dGlgr-P&8&CDYT@wN?BFTh!9r=xMU$z@$Jm;W@=y)()!_9<2PM^T#br%EySmHC70>r^QTI#@8iYpM9*Fm8i! zKa9I!yjMJ@xZE)Qi*%@DXR_}G_x1D<+<1wL8(SAPH|86qK8sOaBL?D3I0z=~nR^ez%;% zYqEaa+b19`H91ls5DZ`oRsad{6N^S!7*Tk|G;~~g+%R|!G)Muv90`$Sz!1AUypSz% zXEYXb2(NFIBHhdy!w#>driA4FeC3fG!t206Q3rDWfLsUUkQ{5q#dGD!?H=(SCp=2c3#(OUmB&>JS;}l+ajnKl?8p(yxb!qJ8sDs>zPm#03 zYw12oZqXwPF89!WQ3rDGK<>+sTMfBk@myJQ%DWr98%4PjTn=R6a3qA(D8J?0_9!t% z(fA0vyc{zV<RX3A@^s<-2piRas%Qyh1IvNW7470oj;9x#s#_B9xfM- zMDQ;fZvJv0gB;6x6m!Uh2rIT(6(a(URg^sD*b63?;MtPC0&-=vI9nFU`Ty!9SKA}W zEgGg9Y`KlDrF39Eas{MEw}=f5q(1`baUkhH>J!hE7hb-rJzp1*Uf@V*9fpJulizY~ zdlX)bhiz6_ZyKy1*AC&t;nHsZm3a`7J?%+9MyFu<4V(wYUbwZA2 z2<-Ee7@g$$20XR&Ls)XVt;84(Q#}%zf2~hwq8!=fV-89LWeuev$l?=!ksNX=>kF~X z-lh4EJId{rx5aa1#oXi_uzGt05~@Mj}t5 zN6W_?i#UXxEyu!*`ZUUxNF{+2!gsIm#WE zege5+$URm#gI5%DN2NohJ3U$Vmjt;pHd%5sGr~r1rMHxS#LkvHU-Dvvu~EXLY)Np0 z$ID1kgR&*ZvL$k*lbrv7QaLLDS>x+7Hc4`e1{PfIxevvLv*xsZ1G(EE_o8^NtO{jv z;0E7$qTJJkn8P3d!*2O4=eB3dQPAaQMrZ&4zI;DN-JUh*W`zuuocWl`=URuDQyt}= zmgQcSg-1-V_@Ta%UpuK7rf;$h|I}<1yzn0C+g%^$Bvz{X)z!xcSQw2F7mr z3dO2V64sP4OPo|}3NdGAOYX)75VOnq_c+Nd_seoAS*{YPn`IHC&r0(inzeWkU z65U$O2jaQ%kbXGgc~wN(kw-$87K(&|l}L=NJHsD7Ghzi3`YtQH*su*V$fk`%0{|Xg zREp5u4oJLPw&(RXU;yw{-WXP5T)sm_`ex;k9K!3DkBT~wy8&`oaa;L@Qsu4{&nd2I zbZbs!_@{PjpU#PL@gTS z<7+GnL_%yPg^#bX783~t!dkd^POEr)eLxN`F30-x{FL$Xqq5w87F_P-yG0$y?SiMkq2SUuPSi|M?a8&2ZDKp+x=0V=2MJcE-p-;t#-V$H| zsOx;ton&L|gnr1AhK6{-x?M0ip82kVV2mi+GdT!qt;k__CTx?0#W2d614)+@0B?< zne#H2pAJM8yIWl6DxJ;BpmJU#o_ILRryN#HkJ6zSO-iRy>vx%ouX;IMTu^yqU6IO* zP`O{JYOI0E1>(8#N|HU@?#D!xAxni#Hc@*?Z#l=EmfzuV5?bn{zXTP=WT~+1h`}50 z*q9kMTyCjgn1*gna~frTpMHj-AQL+_|B$S57u{e_9ADvTpaYeeIDR`RHWWhV$3S`z zNGpNVEuJe6X}s6{w21VYoe8nZ%znkCx18e+A*JliMk0qi5)GkIfKVS+5G5q?p`vs4 z(5Y`NAhBnDcqWvPUXzhNl94Ks31?rIIaVjO9^{^Y+;jJE;NkNw03T zEXSAN?C@Fux%Wa6xqXnk1aiB@bLGkXGwnS`l)JA;ZhqYrON0n*o0R45ljWXY@R<9XRKi1UALO<}ZWMA) z%w6t*>pcAFLOxcjJ6Xtf969>+}M$3S`*NNtb_PtjC7lRG9}KEvzHz24PA%r)%ga@4KhQSEqqhI`6BL~?8%gpHPs vyj;>uB@@ViBu5X5AUPV=B$iH(X`w!$E-hi=e-6MC7W8OM8;#hW`hklS1Ly*vB9-Mu|e@PUYm#|be~Xavi5g@apQ^Z(I)g z*t?zXnVs(W?f?6}{GqsLu^3&U=Yb^`rPivo+zb4ZV*XFD!4h$7aGqr`q ztLNq~zZ_KyhnMsgOQk}0e#z>YTI|xk?!iLWkk&ESHN131Pcf#=>S|k}AIvWF6nYDN zr7oP()>kN9jO#nQO1Rer+V_Y1v}x__=b~zU|I)5fvA=Joc4>E^XGwo|p|4fzC=BBF z!d1o6n!;dDS6_FlcFuVV&cBTIs=t?h>d;JWZgHelySA(6)?(lChB%rQttbv@%Zfb( z4S(nK53C+6E?-g7T9#&Tv$NZ^C9Ad4ih?%ps)e1}z+nF^g{382)q$f@VX${d>lzs7 z!LWu31$G|$q&Zh!b^YZF=4r(~R@Yq|Dh(Ew4AUNKgZ=#_ZCU@I)?Fxd6?=x-(2Iv2 zAsGkhxcf_@{?kL|cHDF97(sDPawu(%AC{h-s5Uqq0a}Gp_u8)C;ez^lcC?3dDs`;l zoPfe=zT2-LyS8!Kh|*+SxSv(tn4vXFn`h6qPmMN00=r$0IXC_GAaO)4B#ueLVjEE! zaLKz;mBqnywUgaqpOX%7*gMHHqtW8Da#irwDdo5HueyFS8O^umTWQJVL(i2T4Lhmf zm1Sf!5DbSy5xj!VJ0fH>nM@{FNs6CS{oe6#CmGGixy!fC4yPFk2+7C#}0O=vIjVPzvkym@&b0VZeH9%^G0GI|WA$fiNK)@dk26TBP z67fVV9*-rY&Q={Td1bSi3&g znk%piD%SFQ%IU1)L~t6A9{H&V0+5P;^eaGG2}rxdHhYi`%~L-TAw5|GB#MU@D@dVm zB!J=%h8d((DwW17m9k?PDIRVcx#l21#?9=~nsWxE&vnCiujJBJJ}EiE(a&wjX6DDWKYsXTtdw?_wNLv7D z6Cmvq+c>0mq^jzJ#W$(DMMwj+L89t94x~UR$_uxF)C5vH7>`$XMy%0Y8WR`7j|wDi z6itwt`4^4ZKx=ue8jvAvlOc_dyw-@Z{wTYHLGI}*#NmP5dmwi^$l+xsXDilss{xVR z>$Q<%zAJATj6hg`7YPOYy7yxK3+TjwRKMr3em2vBl4;2>ax5^R&MRjoH-n9Vk^4+H zjN2r`xaxJ8+-EYm@tLK4E4gQ;i-Qd8c25AgH6XVh5w$tzNcs*`!AW+d9ouOVd?9!8GLki*DD zGP#Qtg;ktL+|fAAf}9jaI*6a$#So%As|C(DaP|TxUXz}Xa4|nO7S7oV>Xx%x@Gx@Z z{u*$$m5ZgHqxLfr4r$RS6C$&ofN2XS4No}2vI*5IOgNh_WMilZ(T%B_EX0xfWg-57 zU2u}Z$UPH85P&onkZuN~YXRwAvCUo>`RdZTw*^S6Nez(lZEg5Ri&ZcZi6AW!Mli`C z(b+Yk5wMavTXn#!CBhDfE(2B^5)Uacu`oe$JzzjO3Ts&nX*H1{#bijQz|ZafKpZ2; z-2`%1g4`^STPe2LBX{6N^-hsocMaq?HEJ-e$VD~8kjQIA_@o;%?pQPyjoS(%DJe|o zb6M`^c%p>r%}nltG0Any=nldaz6&S1jso-?jo^`D5{-cWL90HKyFQIZRGNK zW*e>K1vSBYg@Zml@yK$nZn& z&#%EO9*e^`maDD*@(BPSQ9Gy`M#_vA6S=0ZWpd3z+`%=sW~;2Z9qfV%xr-EX!sHBj z{q=5fOn~%+bJMP4fb=|Zoc=$tjmP?9B|)@~`pqJwBQ-&Swy0gSf+Tc_L5fj8l#v}s z$am<$K9d&!QE^qz(waubgmgrLq)wJ0jfeNLjP(t2e;X7Y1=iBsPl4R$AonQ9y(PBU zo24B%yMB*AZtZookwfS~gGLK^30>03(VzqPY?7msYfP~@IVLsw%OtOfK<+PM8#jz&Y3@LK{c4fizM9DClC!Bf zP>aQFWkzUPgqO1BbkUi}HJ!)Cz{q_Hmqy8zQ^wpduH7e-J1CPo1;NN09U>i&dmQBc z19EqR+@HiYdzyRos`^y|xpi7CBdX>ol3%OqtwxXwEQp}F-urNZ+a>o(T{iMcbo zE)96-x|ywIGYW;J9=TzpCXv=;GbTt)JW~G_d9B+lLwZn#bkfpS2D!I|ts``MhsjipqP*U(nH<%ag-aX7w<#Eo(%_y)jL3puAq~HzuUXXrlUF*OrUFATLuL&mtKDK~ug_EX2XfhS- zT}Rntl5z3}rSH?aZN7wa;*Vq@j>igs0qOmBOptznS=t0ZdKt4cDJjY4*V5_YrTY83 zma5#5>yUQU1c_S8R>YB(kZ5{16bkE`45*zr!auAGX_pM?A2Ouzm;e}%KK!#V5Na4N0HmpabQF-z65EI}6;o*`B`G!Y zgV`6WZq{E8X?=4IklON@WE{^vk+Omm){wvQxm_;4mWJeg)bI28y*`WH2vro)&X!av z=J(QCJz~tnqsS{KQYM!+^%WTs%??w;i0z9`9x<+OmR;I8GNkdCN?RI6gWSi@2%`hJ z<|80?u65#(lKV(J-QxY? zN!{b8oZOM^;y^);rmyIV%oWhw9by|%Cfgu)=$863MRIS}Kn`j5T&5)zPsXjt#bRk} zgYHN_u^dc#=NmO5K?zzk!8erO_%7bBNPV1h&$!X6Vj*WV3tbmsvlrx3@n zZ_4D}l*p;vWmkfcQ=qvoHi=^dxkVsX0y&F)b5lT0+LSC_s=q&cTm3YF+=kgTkn?EC zc+3~^`}|hqu+oW~aWEL<>(|&rhZC`R)o;-op^A~iOdL^*h9Hz{4qp*ks=~;odkk`w zeRHstN`>5p*%G}q`c!1sd_Sz@C_Z6Fw()sb_TnPVM4#YMHn(Q zp=SaowjxA+0wKO2wh;yHML8-}RUIfKqi^u!&TqqGHQ@C7Ln#)!r!8>q)S_Cz?Q!GQ z)P&kD3}=$<#>47OQg?n?d~xFOXxb#iGhRO)&SS3G%!F=uY=UZ7P@+zdabBW0SVgu` z4UqX{o=WzUjs~TjOm~n^NX$uIBvV3&CME~T!=%nb7Ln5?ZkN&QC0C1s!>;gyK(hg8 zULuZ0`F{~8F`)Ucc)G>=ySnQ>X1CyIHmWtCNhWFh;L}1-T2QIr~ea!?h5BSR2AJuZd7HZozE_) zC~Z74Srz^4b-3{or<4ThDEMGqTwYyAw=% z@zS$@gFg=T;2}`ZA_cF4KknWHQR<I)2{15b>NeCI zkhHZ@E^nX#a9NYHHE|6ZumDZ0ky~UF;wvP6Lc?UPOJJsCg1D-lC$5y0(=f8k1Q^qy zk+pPa4uK@JNt?Nk@CvjI&D4j$=!Nvf>ohB?Ku2{FAZ>vqR1OUi=gmBFh%g`^zvEVM z*+zHs7({atnPyl8*=2z95KPTyCP2})?!g=;QAwgOvvOM%fb071)-A!IEVI9byd`j!d$6^hD_G6{x)udWCnDb>bL39blgQHD_4t z;dog%Ru9}{&f606to3hvnXLEu^G|%srr7Kf*2Kjb(AUoody1D~UiR?vC@+J&>>~1N zRFcS-+F8E$I4?zdvrH`}%ZhS@?=AE4K$)#UqCsx^9j-2n^NSByz%IFv@SZt*C)XVc zA0jiKW24tGev`R$d=TPGHbo8NYP&HKeyw9v6orwLy)b@aYiNdXmD?)uGYibXVW3+0K7OIh8tXcDF>`8iJ+~PJTIMpGH^#c6L||@p*^H?NNX~zjEpLAc8B67%T0@DAnpO+7d>U z+Az613h<;S#tOGp!7z`pldr>o+`sYb1DB2uLfo!l49MbQ>O{LSvPz85a%{00RYfJw z(&iYue>B5bT^P4jft`OC4+`}2OnAc_ojBD{j5{y5bbJuv$3~3hzI_epI-E9-tsYLv lGnE`{$mPQ5ilyhw*NVc*QB@UJulsO{Ju&hT;+@KR=r8tTYK#B? literal 0 HcmV?d00001 diff --git a/test/daemon/bu303-nofix.log.chk b/test/daemon/bu303-nofix.log.chk new file mode 100644 index 0000000..d3e86a2 --- /dev/null +++ b/test/daemon/bu303-nofix.log.chk @@ -0,0 +1,28 @@ +{"class":"SKY","tag":"MID4","time":1037284378.280} +$GPRMC,143258,V,18000.0000,N,00000.0000,W,0.0000,0.000,141102,,*1F +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1037284378.280,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1037284379.280} +$GPRMC,143259,V,18000.0000,N,00000.0000,W,0.0000,0.000,141102,,*1E +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1037284379.280,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1037284380.280} +$GPRMC,143300,V,18000.0000,N,00000.0000,W,0.0000,0.000,141102,,*13 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1037284380.280,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1037284381.280} +$GPRMC,143301,V,18000.0000,N,00000.0000,W,0.0000,0.000,141102,,*12 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1037284381.280,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1037284382.280} +$GPRMC,143302,V,18000.0000,N,00000.0000,W,0.0000,0.000,141102,,*11 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1037284382.280,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1118327583.280} +$GPRMC,143303,V,18000.0000,N,00000.0000,W,0.0000,0.000,090605,,*1D +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1118327583.280,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1118327584.280} +$GPRMC,143304,V,18000.0000,N,00000.0000,W,0.0000,0.000,090605,,*1A +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1118327584.280,"ept":0.005,"mode":1} diff --git a/test/daemon/bu303-stillfix.log b/test/daemon/bu303-stillfix.log new file mode 100644 index 0000000000000000000000000000000000000000..54e540469d7aa315d8b016ab949d1100bf988b90 GIT binary patch literal 5198 zcmciGUu;uV7y$5duWh+h#wMWCv}0#$ySC%DY=faJVx${ehGP&mVvLEdThHj-x^}jA zIEa6UN&-sagJPDD7{M2OAX!{=3o66}!-FQin81T3M&qAEAJD`%;{47zZSOg|7q@i4 z*;abax%c*-{`!6AD*@b}oFE-IaVWN}WgCw4_qDaO#STTi0o<83CJV&uzyrp??pSXx z3=K>TPZ*|2QnBHq9k_9KHkBvI0#4+UQzPk&(TE>U#)pfYCrO4(kgS=6L*iLtJ^|-< zB~5s(op|q57Pqyuw8KzeZX{_MxoijCog$gxT#96MoFI949C*<%kCA*PnN8_<`;Puc z_t3k_P0*_rI&il!t>ZiyA;uAs$Jv~TCvr!O>|t*J4jW7x1w3kG2!?+fC?encn^$ zY-HJ3$|#t5V|a?*JQ215xJVCjtyB5J+?v;=mTu4UG&^DKT6UdF zs7LX#f$cs;zVeECes*qE+qAO5I{phb*j%Og&_2|oq04BuS7}9UD*78Wy3jRLQ>Q$D zs{H62T2qS#k;i?Oo$+jxUPFo3UV88!>uL!3=GXt>dTs7Aq&6gxy8f&06}YTY$7foI}d} zfFzkp)4X#$s6|AiTNNMy5xkT1&k2dfBX0}|zyg6r>f~@Y!Vp8EK%ftw0EW~|8+;;~ zo0kOSrpp$RtAxZaRtm^l5|X=4M(R{Nt44ARNK3BnD`9mIUe&um?njV&AE{M0#5tsB zAor&#72K&v3BP_fk;ijf=I2?&YczA(UGyFv(OOZC% zkxt4;S7oH1WTd;c-&t~@Gve|k{X9Vq8uRwRsi=xv@wEa{887Jiav! z%~1}D6ev}~O<^X7aXoIJiE$;B3XnyjEE_U8=&+tGF>d_Ql2eP}b&|dri;Km?I2MuR zx@Ea8Wepox&F-~KVvN2l>VVuCkh_l5`Wql8R5)-HON_sWhdVsKFsfxlxziQM0a+|g zGo!N{Bu3cBAUT%n4k$69>u@*1P`Sor6%F6gs2h*Er7^eHl2b}@Qp}B=mgPQ@<@PAr z-Ij|HVRdv%n+3URAUBWHb$^L-Jm!9th8#MYwpo=8{jxV+pb2lY9H!l#&72}7xdJ^`fjfb_jM z$HQwmq@hFFy8_bqU?oVDh&AWL2t@}l6~DrjYW!eGx>;L?g%^t^rc^}YJEt9~Mn>|% zS2&g!%U|Kf2PGs|ft^rBx(5|wd%L(skh=+TP%YNK0dkkcIbMt`ml)GS8WH6dDv)D| z5ptvRmc~MhRrtKt=UEa`qja;j4wr-4gX%?_nH+OtkV_Ne3zi&$#K`2N#5len$$7q$ zcL`Wtyw$i7ND%Vqqs+|GM0x63WA5#+i+?j?{r2y&;z Pxs}Bn+V6R1cFy}B+&|M8 literal 0 HcmV?d00001 diff --git a/test/daemon/bu303-stillfix.log.chk b/test/daemon/bu303-stillfix.log.chk new file mode 100644 index 0000000..9616658 --- /dev/null +++ b/test/daemon/bu303-stillfix.log.chk @@ -0,0 +1,77 @@ +$GPGSV,2,1,08,23,07,084,00,28,07,160,00,08,65,189,45,29,13,273,00*77 +$GPGSV,2,2,08,10,50,304,37,04,16,199,36,02,34,241,43,27,71,076,43*71 +{"class":"SKY","tag":"MID4","time":1118327655.280,"satellites":[{"PRN":23,"el":7,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":45,"used":false},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":37,"used":false},{"PRN":4,"el":16,"az":199,"ss":36,"used":false},{"PRN":2,"el":34,"az":241,"ss":43,"used":false},{"PRN":27,"el":71,"az":76,"ss":43,"used":false}]} +$GPGGA,143415,4629.8901,N,00734.0471,E,1,05,2.40,1349.51,M,48.183,M,,*71 +$GPRMC,143415,A,4629.8901,N,00734.0471,E,0.1776,10.379,090605,,*11 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,0.0,2.4,0.0*3E +{"class":"TPV","tag":"MID2","time":1118327655.280,"ept":0.005,"lat":46.498167579,"lon":7.567452213,"alt":1349.507,"track":10.3789,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,65,189,43,29,13,273,00*70 +$GPGSV,2,2,08,10,50,304,36,04,16,199,36,02,34,241,44,27,71,076,43*77 +{"class":"SKY","tag":"MID4","time":1118327656.280,"xdop":0.73,"ydop":1.03,"vdop":1.42,"tdop":0.78,"hdop":1.26,"gdop":2.06,"pdop":1.90,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":43,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":36,"used":true},{"PRN":4,"el":16,"az":199,"ss":36,"used":true},{"PRN":2,"el":34,"az":241,"ss":44,"used":true},{"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} +$GPGGA,143416,4629.8905,N,00734.0473,E,1,05,2.40,1347.42,M,48.183,M,,*78 +$GPRMC,143416,A,4629.8905,N,00734.0473,E,0.1776,10.379,090605,,*14 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327656.280,"ept":0.005,"lat":46.498174322,"lon":7.567455643,"alt":1347.417,"epx":10.980,"epy":15.454,"epv":32.724,"track":10.3789,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,65,189,44,29,13,273,00*77 +$GPGSV,2,2,08,10,50,304,38,04,16,199,35,02,34,241,44,27,71,076,42*7B +{"class":"SKY","tag":"MID4","time":1118327657.280,"xdop":0.73,"ydop":1.03,"vdop":1.42,"tdop":0.78,"hdop":1.26,"gdop":2.06,"pdop":1.90,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":44,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":38,"used":true},{"PRN":4,"el":16,"az":199,"ss":35,"used":true},{"PRN":2,"el":34,"az":241,"ss":44,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143417,4629.8908,N,00734.0474,E,1,05,2.40,1346.73,M,48.183,M,,*70 +$GPRMC,143417,A,4629.8908,N,00734.0474,E,0.0000,0.000,090605,,*24 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327657.280,"ept":0.005,"lat":46.498180789,"lon":7.567457358,"alt":1346.734,"epx":10.980,"epy":15.454,"epv":32.724,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,65,189,45,29,13,273,00*76 +$GPGSV,2,2,08,10,50,304,38,04,16,199,35,02,34,241,43,27,71,076,43*7D +{"class":"SKY","tag":"MID4","time":1118327658.280,"xdop":0.73,"ydop":1.03,"vdop":1.42,"tdop":0.78,"hdop":1.26,"gdop":2.06,"pdop":1.90,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":38,"used":true},{"PRN":4,"el":16,"az":199,"ss":35,"used":true},{"PRN":2,"el":34,"az":241,"ss":43,"used":true},{"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} +$GPGGA,143418,4629.8912,N,00734.0475,E,1,05,2.40,1346.05,M,48.183,M,,*74 +$GPRMC,143418,A,4629.8912,N,00734.0475,E,0.1776,10.379,090605,,*1A +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327658.280,"ept":0.005,"lat":46.498187256,"lon":7.567459073,"alt":1346.052,"epx":10.980,"epy":15.454,"epv":32.724,"track":10.3789,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,65,189,44,29,13,273,00*77 +$GPGSV,2,2,08,10,50,304,36,04,16,199,32,02,34,241,39,27,71,076,41*7B +{"class":"SKY","tag":"MID4","time":1118327659.280,"xdop":0.73,"ydop":1.03,"vdop":1.42,"tdop":0.78,"hdop":1.26,"gdop":2.06,"pdop":1.90,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":44,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":36,"used":true},{"PRN":4,"el":16,"az":199,"ss":32,"used":true},{"PRN":2,"el":34,"az":241,"ss":39,"used":true},{"PRN":27,"el":71,"az":76,"ss":41,"used":true}]} +$GPGGA,143419,4629.8909,N,00734.0475,E,1,05,2.40,1345.33,M,48.183,M,,*79 +$GPRMC,143419,A,4629.8909,N,00734.0475,E,0.1776,10.379,090605,,*11 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327659.280,"ept":0.005,"lat":46.498181065,"lon":7.567459073,"alt":1345.327,"epx":10.980,"epy":15.454,"epv":32.724,"track":10.3789,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,65,189,46,29,13,273,00*75 +$GPGSV,2,2,08,10,50,304,38,04,16,199,34,02,34,241,41,27,71,076,41*7C +{"class":"SKY","tag":"MID4","time":1118327660.280,"xdop":0.73,"ydop":1.03,"vdop":1.42,"tdop":0.78,"hdop":1.26,"gdop":2.06,"pdop":1.90,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":46,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":38,"used":true},{"PRN":4,"el":16,"az":199,"ss":34,"used":true},{"PRN":2,"el":34,"az":241,"ss":41,"used":true},{"PRN":27,"el":71,"az":76,"ss":41,"used":true}]} +$GPGGA,143420,4629.8913,N,00734.0476,E,1,05,2.40,1344.64,M,48.183,M,,*78 +$GPRMC,143420,A,4629.8913,N,00734.0476,E,0.1673,180.000,090605,,*22 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327660.280,"ept":0.005,"lat":46.498187532,"lon":7.567460788,"alt":1344.644,"epx":10.980,"epy":15.454,"epv":32.724,"track":180.0000,"speed":0.086,"climb":-0.091,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,65,189,46,29,13,273,00*75 +$GPGSV,2,2,08,10,50,304,37,04,16,199,36,02,34,241,43,27,71,076,41*73 +{"class":"SKY","tag":"MID4","time":1118327661.280,"xdop":0.73,"ydop":1.03,"vdop":1.42,"tdop":0.78,"hdop":1.26,"gdop":2.06,"pdop":1.90,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":46,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":37,"used":true},{"PRN":4,"el":16,"az":199,"ss":36,"used":true},{"PRN":2,"el":34,"az":241,"ss":43,"used":true},{"PRN":27,"el":71,"az":76,"ss":41,"used":true}]} +$GPGGA,143421,4629.8916,N,00734.0478,E,1,05,2.40,1343.96,M,48.183,M,,*78 +$GPRMC,143421,A,4629.8916,N,00734.0478,E,0.1776,10.379,090605,,*19 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327661.280,"ept":0.005,"lat":46.498193999,"lon":7.567462504,"alt":1343.962,"epx":10.980,"epy":15.454,"epv":32.724,"track":10.3789,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,65,189,45,29,13,273,00*76 +$GPGSV,2,2,08,10,50,304,38,04,16,199,36,02,34,241,42,27,71,076,42*7E +{"class":"SKY","tag":"MID4","time":1118327662.280,"xdop":0.73,"ydop":1.03,"vdop":1.42,"tdop":0.78,"hdop":1.26,"gdop":2.06,"pdop":1.90,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":38,"used":true},{"PRN":4,"el":16,"az":199,"ss":36,"used":true},{"PRN":2,"el":34,"az":241,"ss":42,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143422,4629.8916,N,00734.0478,E,1,05,2.40,1343.96,M,48.183,M,,*7B +$GPRMC,143422,A,4629.8916,N,00734.0478,E,0.0000,0.000,090605,,*21 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327662.280,"ept":0.005,"lat":46.498193999,"lon":7.567462504,"alt":1343.962,"epx":10.980,"epy":15.454,"epv":32.724,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,65,189,45,29,13,273,00*76 +$GPGSV,2,2,08,10,50,304,37,04,16,199,36,02,34,241,42,27,71,076,43*70 +{"class":"SKY","tag":"MID4","time":1118327663.280,"xdop":0.73,"ydop":1.03,"vdop":1.42,"tdop":0.78,"hdop":1.26,"gdop":2.06,"pdop":1.90,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":37,"used":true},{"PRN":4,"el":16,"az":199,"ss":36,"used":true},{"PRN":2,"el":34,"az":241,"ss":42,"used":true},{"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} +$GPGGA,143423,4629.8917,N,00734.0470,E,1,05,2.40,1343.87,M,48.183,M,,*73 +$GPRMC,143423,A,4629.8917,N,00734.0470,E,0.0000,0.000,090605,,*29 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327663.280,"ept":0.005,"lat":46.498194858,"lon":7.567449593,"alt":1343.871,"epx":10.980,"epy":15.454,"epv":32.724,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,65,189,46,29,13,273,00*75 +$GPGSV,2,2,08,10,50,304,36,04,16,199,36,02,34,241,42,27,71,076,42*70 +{"class":"SKY","tag":"MID4","time":1118327664.280,"xdop":0.73,"ydop":1.03,"vdop":1.42,"tdop":0.78,"hdop":1.26,"gdop":2.06,"pdop":1.90,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":46,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":36,"used":true},{"PRN":4,"el":16,"az":199,"ss":36,"used":true},{"PRN":2,"el":34,"az":241,"ss":42,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143424,4629.8921,N,00734.0471,E,1,05,2.40,1343.19,M,48.183,M,,*77 +$GPRMC,143424,A,4629.8921,N,00734.0471,E,0.1776,10.379,090605,,*11 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327664.280,"ept":0.005,"lat":46.498201325,"lon":7.567451308,"alt":1343.189,"epx":10.980,"epy":15.454,"epv":32.724,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,65,189,46,29,13,273,00*75 +$GPGSV,2,2,08,10,50,304,36,04,16,199,37,02,34,241,42,27,71,076,42*71 +{"class":"SKY","tag":"MID4","time":1118327665.280,"xdop":0.73,"ydop":1.03,"vdop":1.42,"tdop":0.78,"hdop":1.26,"gdop":2.06,"pdop":1.90,"satellites":[{"PRN":23,"el":6,"az":84,"ss":0,"used":false},{"PRN":28,"el":7,"az":160,"ss":0,"used":false},{"PRN":8,"el":65,"az":189,"ss":46,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":50,"az":304,"ss":36,"used":true},{"PRN":4,"el":16,"az":199,"ss":37,"used":true},{"PRN":2,"el":34,"az":241,"ss":42,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143425,4629.8921,N,00734.0471,E,1,05,2.40,1343.19,M,48.183,M,,*76 +$GPRMC,143425,A,4629.8921,N,00734.0471,E,0.1776,10.379,090605,,*10 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327665.280,"ept":0.005,"lat":46.498201325,"lon":7.567451308,"alt":1343.189,"epx":10.980,"epy":15.454,"epv":32.724,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} diff --git a/test/daemon/bu303b-nofix.log b/test/daemon/bu303b-nofix.log new file mode 100644 index 0000000000000000000000000000000000000000..361d34ce3dbb393235fee1e88d45ba8b50b070e5 GIT binary patch literal 3205 zcmY#Z@Jq~1wNh{jH8wDIQpn6x2+j<0Q%K6pODw8X$jwhl)lmp`atu~T%}Y$mNlnpF z$jetq%dFs1R&dV9EGSMbu>$MR_4EV^1(zn}W|owsrsyVBS}C{|WhN^GC06F<=cOpv zq!t%Blw?#E6_*z4CFkeb0hPNXmH@4`Q1B|vQ!p|xFy&GP3Wj8476Wa_NmT&S&iMtE zMVaXtB?=nJnm{#%1`0`)3MCn-3hn{HE(!%j`B|ySB|u$HKwe2|QEst9VnIO;(DLHc zRIoa*NzVQOk)D3;An$?nreqeE6lErrmSpDVDHP@Bmnfv=7b&EqmLz886zc(9v0xE{ zi8Lbv=|E<~W}sePBL)T`gk~48AS;&uH&9F!%!$?nORr#HJyL;Ch|2o^|Hlth5#o4k z3}7qvurRD(V3@p=2W0C|1B}1He$ZrM5L!|HfBOLj20PcqP*404fOrhWPwWT58aO$@ zqPrNF7>T9j#345tS>GT<;}p)J8I1{qqHzi&!eHUWt~RjIc*XHWxMkWn{(RdLls2CX7 z-wkXuUXeg?4ibm#Xxsqy5hNO?nhwcmWb7prjZ;mLf(jUo!2=PE@Gur-U_fh14Sp`; rVsMZlnrSysLKK-pc2b;!oD^sB0E21B0m99+sWVYL#l9U&Qse>vDDO-l literal 0 HcmV?d00001 diff --git a/test/daemon/bu303b-nofix.log.chk b/test/daemon/bu303b-nofix.log.chk new file mode 100644 index 0000000..7c9bc84 --- /dev/null +++ b/test/daemon/bu303b-nofix.log.chk @@ -0,0 +1,25 @@ +{"class":"SKY","tag":"MID4","time":1036886762.970} +$GPRMC,000602,V,4002.1027,N,07531.2013,W,0.0000,0.000,101102,,*2D +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1036886762.970,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1036886763.970} +$GPRMC,000603,V,4002.1027,N,07531.2013,W,0.0000,0.000,101102,,*2C +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1036886763.970,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1036886764.970} +$GPRMC,000604,V,4002.1027,N,07531.2013,W,0.0000,0.000,101102,,*2B +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1036886764.970,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1036886765.970} +$GPRMC,000605,V,4002.1027,N,07531.2013,W,0.0000,0.000,101102,,*2A +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1036886765.970,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1036886766.970} +$GPRMC,000606,V,4002.1027,N,07531.2013,W,0.0000,0.000,101102,,*29 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1036886766.970,"ept":0.005,"mode":1} +{"class":"SKY","tag":"MID4","time":1036886766.970} +{"class":"SKY","tag":"MID4","time":1036886767.970} +$GPRMC,000607,V,4002.1027,N,07531.2013,W,0.0000,0.000,101102,,*28 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +{"class":"TPV","tag":"MID2","time":1036886767.970,"ept":0.005,"mode":1} diff --git a/test/daemon/ch-4701.log b/test/daemon/ch-4701.log new file mode 100644 index 0000000..51c62e8 --- /dev/null +++ b/test/daemon/ch-4701.log @@ -0,0 +1,1101 @@ +# Name: NAVIOR-24 +# Chipset: CH-4701 +# Description: single board 24-channel OEM receiver, GLONASS/GPS systems. +# Submitted-by: Viktar Palstsiuk +# Date: 29 May 2008 +# Location: Minsk, Belarus, 53N 27E +$GPGGA,123433.000,5356.21442,N,02734.85952,E,1,04,07.2,251.9,M,26.0,M,,*67 +$GPRMC,123434.000,A,5356.21440,N,02734.85946,E,00.00,252.7,290508,,,A*6B +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123434.000,5356.21444,N,02734.85947,E,1,04,07.2,251.9,M,26.0,M,,*62 +$GPRMC,123435.000,A,5356.21440,N,02734.85945,E,00.00,252.7,290508,,,A*69 +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123435.000,5356.21444,N,02734.85946,E,1,04,07.2,251.9,M,26.0,M,,*62 +$GPRMC,123436.000,A,5356.21439,N,02734.85943,E,00.00,252.7,290508,,,A*62 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123436.000,5356.21444,N,02734.85946,E,1,04,07.2,251.9,M,26.0,M,,*61 +$GPRMC,123437.000,A,5356.21443,N,02734.85944,E,00.00,252.7,290508,,,A*69 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123437.000,5356.21447,N,02734.85947,E,1,04,07.2,251.8,M,26.0,M,,*63 +$GPRMC,123438.000,A,5356.21444,N,02734.85943,E,00.00,252.7,290508,,,A*66 +$PORZD,A,022.9*35 +$GPGSV,3,1,11,02,13,248,,03,11,066,,07,76,087,36,13,48,101,50*71 +$GPGSV,3,2,11,23,12,106,46,25,56,069,39,27,84,110,31,33,17,229,*7A +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123438.000,5356.21448,N,02734.85946,E,1,04,07.2,251.8,M,26.0,M,,*62 +$GPRMC,123439.000,A,5356.21445,N,02734.85942,E,00.00,252.7,290508,,,A*67 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123439.000,5356.21450,N,02734.85946,E,1,04,07.2,251.8,M,26.0,M,,*6A +$GPRMC,123440.000,A,5356.21447,N,02734.85944,E,00.00,252.7,290508,,,A*6D +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123440.000,5356.21449,N,02734.85945,E,1,04,07.2,251.8,M,26.0,M,,*6F +$GPRMC,123441.000,A,5356.21446,N,02734.85940,E,00.00,252.7,290508,,,A*69 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123441.000,5356.21449,N,02734.85942,E,1,04,07.2,251.8,M,26.0,M,,*69 +$GPRMC,123442.000,A,5356.21445,N,02734.85940,E,00.00,252.7,290508,,,A*69 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123442.000,5356.21447,N,02734.85942,E,1,04,07.2,251.8,M,26.0,M,,*64 +$GPRMC,123443.000,A,5356.21444,N,02734.85939,E,00.00,252.7,290508,,,A*67 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123443.000,5356.21448,N,02734.85942,E,1,04,07.2,251.8,M,26.0,M,,*6A +$GPRMC,123444.000,A,5356.21446,N,02734.85940,E,00.00,252.7,290508,,,A*6C +$PORZD,A,022.8*34 +$GPGSV,3,1,11,02,13,248,,03,11,066,,07,76,087,35,13,48,101,50*72 +$GPGSV,3,2,11,23,12,106,47,25,56,069,38,27,84,110,31,33,17,229,*7A +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123444.000,5356.21450,N,02734.85942,E,1,04,07.2,251.8,M,26.0,M,,*64 +$GPRMC,123445.000,A,5356.21446,N,02734.85938,E,00.00,252.7,290508,,,A*62 +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123445.000,5356.21450,N,02734.85941,E,1,04,07.2,251.8,M,26.0,M,,*66 +$GPRMC,123446.000,A,5356.21447,N,02734.85936,E,00.00,252.7,290508,,,A*6E +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123446.000,5356.21451,N,02734.85943,E,1,04,07.2,251.9,M,26.0,M,,*67 +$GPRMC,123447.000,A,5356.21448,N,02734.85938,E,00.00,252.7,290508,,,A*6E +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123447.000,5356.21452,N,02734.85942,E,1,04,07.2,251.9,M,26.0,M,,*64 +$GPRMC,123448.000,A,5356.21449,N,02734.85942,E,00.00,252.7,290508,,,A*6D +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.7*0E +$GPGGA,123448.000,5356.21453,N,02734.85943,E,1,04,07.2,251.9,M,26.0,M,,*6B +$GPRMC,123449.000,A,5356.21448,N,02734.85937,E,00.00,252.7,290508,,,A*6F +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.7*0E +$GPGGA,123449.000,5356.21453,N,02734.85941,E,1,04,07.2,251.9,M,26.0,M,,*68 +$GPRMC,123450.000,A,5356.21449,N,02734.85935,E,00.00,252.7,290508,,,A*64 +$PORZD,A,022.9*35 +$GPGSV,3,1,11,02,13,248,,03,11,066,,07,76,087,35,13,48,101,51*73 +$GPGSV,3,2,11,23,12,106,45,25,56,069,38,27,84,110,31,33,17,229,*78 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.7*0E +$GPGGA,123450.000,5356.21454,N,02734.85939,E,1,04,07.2,251.9,M,26.0,M,,*68 +$GPRMC,123451.000,A,5356.21452,N,02734.85936,E,00.00,252.7,290508,,,A*6C +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123451.000,5356.21456,N,02734.85939,E,1,04,07.2,251.9,M,26.0,M,,*6B +$GPRMC,123452.000,A,5356.21451,N,02734.85935,E,00.00,252.7,290508,,,A*6F +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123452.000,5356.21456,N,02734.85938,E,1,04,07.2,251.9,M,26.0,M,,*69 +$GPRMC,123453.000,A,5356.21453,N,02734.85933,E,00.00,252.7,290508,,,A*6A +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123453.000,5356.21458,N,02734.85934,E,1,04,07.2,251.8,M,26.0,M,,*6B +$GPRMC,123454.000,A,5356.21455,N,02734.85930,E,00.00,252.7,290508,,,A*68 +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123454.000,5356.21459,N,02734.85931,E,1,04,07.2,251.7,M,26.0,M,,*67 +$GPRMC,123455.000,A,5356.21455,N,02734.85927,E,00.00,252.7,290508,,,A*6F +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123455.000,5356.21461,N,02734.85930,E,1,04,07.2,251.6,M,26.0,M,,*6D +$GPRMC,123456.000,A,5356.21458,N,02734.85926,E,00.00,252.7,290508,,,A*60 +$PORZD,A,022.8*34 +$GPGSV,3,1,11,02,13,247,,03,11,065,18,07,76,087,37,13,48,101,51*74 +$GPGSV,3,2,11,23,12,106,45,25,55,069,38,27,83,108,32,33,17,229,*76 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123456.000,5356.21463,N,02734.85930,E,1,04,07.2,251.6,M,26.0,M,,*6C +$GPRMC,123457.000,A,5356.21458,N,02734.85925,E,00.00,252.7,290508,,,A*62 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123457.000,5356.21464,N,02734.85931,E,1,04,07.2,251.5,M,26.0,M,,*68 +$GPRMC,123458.000,A,5356.21463,N,02734.85930,E,00.00,252.7,290508,,,A*61 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123458.000,5356.21469,N,02734.85938,E,1,04,07.2,251.5,M,26.0,M,,*63 +$GPRMC,123459.000,A,5356.21465,N,02734.85933,E,00.00,252.7,290508,,,A*65 +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123459.000,5356.21596,N,02734.86645,E,1,05,06.0,255.7,M,26.0,M,,*61 +$GPRMC,123500.000,A,5356.21592,N,02734.86643,E,00.00,252.7,290508,,,A*6A +$PORZD,A,021.5*3A +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123500.000,5356.21592,N,02734.86641,E,1,05,06.0,255.7,M,26.0,M,,*6C +$GPRMC,123501.000,A,5356.21589,N,02734.86639,E,00.00,252.7,290508,,,A*6C +$PORZD,A,021.5*3A +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123501.000,5356.21589,N,02734.86638,E,1,05,06.0,255.8,M,26.0,M,,*66 +$GPRMC,123502.000,A,5356.21587,N,02734.86636,E,00.00,252.7,290508,,,A*6E +$PORZD,A,021.4*3B +$GPGSV,3,1,11,02,13,247,,03,11,065,18,07,76,087,36,13,48,101,50*74 +$GPGSV,3,2,11,23,12,106,46,25,55,069,38,27,83,108,31,33,17,229,*76 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123502.000,5356.21588,N,02734.86634,E,1,05,06.0,255.8,M,26.0,M,,*68 +$GPRMC,123503.000,A,5356.21585,N,02734.86631,E,00.00,252.7,290508,,,A*6A +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123503.000,5356.21577,N,02734.86569,E,1,05,06.0,255.4,M,26.0,M,,*6E +$GPRMC,123504.000,A,5356.21573,N,02734.86567,E,00.00,252.7,290508,,,A*64 +$PORZD,A,022.2*3E +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123504.000,5356.21576,N,02734.86571,E,1,05,06.0,255.4,M,26.0,M,,*61 +$GPRMC,123505.000,A,5356.21575,N,02734.86568,E,00.00,252.7,290508,,,A*6C +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123505.000,5356.21576,N,02734.86569,E,1,05,06.0,255.5,M,26.0,M,,*68 +$GPRMC,123506.000,A,5356.21571,N,02734.86567,E,00.00,252.7,290508,,,A*64 +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123506.000,5356.21566,N,02734.86512,E,1,05,06.0,255.1,M,26.0,M,,*62 +$GPRMC,123507.000,A,5356.21562,N,02734.86508,E,00.00,252.7,290508,,,A*6E +$PORZD,A,022.2*3E +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123507.000,5356.21566,N,02734.86514,E,1,05,06.0,255.1,M,26.0,M,,*65 +$GPRMC,123508.000,A,5356.21564,N,02734.86514,E,00.00,252.7,290508,,,A*6A +$PORZD,A,021.4*3B +$GPGSV,3,1,11,02,13,247,,03,11,065,,07,76,087,36,13,48,101,51*7C +$GPGSV,3,2,11,23,12,106,45,25,55,069,38,27,83,108,31,33,17,229,*75 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123508.000,5356.21568,N,02734.86517,E,1,05,06.0,255.2,M,26.0,M,,*64 +$GPRMC,123509.000,A,5356.21565,N,02734.86514,E,00.00,252.7,290508,,,A*6A +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123509.000,5356.21569,N,02734.86517,E,1,05,06.0,255.1,M,26.0,M,,*67 +$GPRMC,123510.000,A,5356.21566,N,02734.86516,E,00.00,252.7,290508,,,A*63 +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123510.000,5356.21569,N,02734.86520,E,1,05,06.0,255.2,M,26.0,M,,*68 +$GPRMC,123511.000,A,5356.21565,N,02734.86519,E,00.00,252.7,290508,,,A*6E +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123511.000,5356.21561,N,02734.86474,E,1,05,06.0,254.9,M,26.0,M,,*6B +$GPRMC,123512.000,A,5356.21558,N,02734.86470,E,00.00,252.7,290508,,,A*6D +$PORZD,A,022.2*3E +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123512.000,5356.21561,N,02734.86478,E,1,05,06.0,254.9,M,26.0,M,,*64 +$GPRMC,123513.000,A,5356.21557,N,02734.86477,E,00.00,252.7,290508,,,A*64 +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123513.000,5356.21553,N,02734.86441,E,1,05,06.0,254.7,M,26.0,M,,*60 +$GPRMC,123514.000,A,5356.21551,N,02734.86438,E,00.00,252.7,290508,,,A*6E +$PORZD,A,022.3*3F +$GPGSV,3,1,11,02,13,247,,03,11,065,,07,76,087,37,13,48,101,51*7D +$GPGSV,3,2,11,23,12,106,46,25,55,069,38,27,83,108,30,33,17,229,*77 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123514.000,5356.21548,N,02734.86407,E,1,05,06.0,254.4,M,26.0,M,,*6C +$GPRMC,123515.000,A,5356.21544,N,02734.86403,E,00.00,252.7,290508,,,A*63 +$PORZD,A,022.4*38 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123515.000,5356.21549,N,02734.86418,E,1,05,06.0,254.5,M,26.0,M,,*63 +$GPRMC,123516.000,A,5356.21546,N,02734.86416,E,00.00,252.7,290508,,,A*66 +$PORZD,A,021.6*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123516.000,5356.21543,N,02734.86390,E,1,05,06.0,254.3,M,26.0,M,,*6B +$GPRMC,123517.000,A,5356.21540,N,02734.86387,E,00.00,252.7,290508,,,A*6E +$PORZD,A,022.5*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123517.000,5356.21539,N,02734.86365,E,1,05,06.0,254.2,M,26.0,M,,*6C +$GPRMC,123518.000,A,5356.21536,N,02734.86362,E,00.00,252.7,290508,,,A*6B +$PORZD,A,022.5*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123518.000,5356.21540,N,02734.86384,E,1,05,06.0,254.3,M,26.0,M,,*63 +$GPRMC,123519.000,A,5356.21536,N,02734.86384,E,00.00,252.7,290508,,,A*62 +$PORZD,A,021.6*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123519.000,5356.21534,N,02734.86366,E,1,05,06.0,254.2,M,26.0,M,,*6C +$GPRMC,123520.000,A,5356.21532,N,02734.86362,E,00.00,252.7,290508,,,A*64 +$PORZD,A,022.5*39 +$GPGSV,3,1,11,02,13,247,,03,11,065,,07,76,087,36,13,48,101,50*7D +$GPGSV,3,2,11,23,12,106,47,25,55,069,39,27,83,108,31,33,17,229,*76 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123520.000,5356.21536,N,02734.86384,E,1,05,06.0,254.3,M,26.0,M,,*69 +$GPRMC,123521.000,A,5356.21532,N,02734.86385,E,00.00,252.7,290508,,,A*6C +$PORZD,A,021.6*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123521.000,5356.21534,N,02734.86399,E,1,05,05.9,254.5,M,26.0,M,,*6A +$GPRMC,123522.000,A,5356.21532,N,02734.86395,E,00.00,252.7,290508,,,A*6E +$PORZD,A,021.6*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.2*01 +$GPGGA,123522.000,5356.21532,N,02734.86407,E,1,05,05.9,254.6,M,26.0,M,,*6C +$GPRMC,123523.000,A,5356.21529,N,02734.86407,E,00.00,252.7,290508,,,A*69 +$PORZD,A,021.5*3A +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.2*01 +$GPGGA,123523.000,5356.21524,N,02734.86380,E,1,05,05.9,254.4,M,26.0,M,,*60 +$GPRMC,123524.000,A,5356.21521,N,02734.86378,E,00.00,252.7,290508,,,A*69 +$PORZD,A,022.5*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.1*02 +$GPGGA,123524.000,5356.21520,N,02734.86384,E,1,05,05.9,254.4,M,26.0,M,,*67 +$GPRMC,123525.000,A,5356.21516,N,02734.86382,E,00.00,252.7,290508,,,A*69 +$PORZD,A,021.6*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.1*02 +$GPGGA,123525.000,5356.21516,N,02734.86385,E,1,05,05.9,254.4,M,26.0,M,,*62 +$GPRMC,123526.000,A,5356.21514,N,02734.86386,E,00.00,252.7,290508,,,A*6C +$PORZD,A,021.6*39 +$GPGSV,3,1,12,02,12,247,,03,11,065,,07,76,086,37,13,48,101,51*7E +$GPGSV,3,2,12,23,12,106,45,25,55,069,38,27,83,107,30,28,05,181,40*74 +$GPGSV,3,3,12,33,17,229,,37,28,187,,39,28,183,,44,20,137,*78 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.1*02 +$GPGGA,123526.000,5356.21510,N,02734.86359,E,1,05,05.9,254.3,M,26.0,M,,*61 +$GPRMC,123527.000,A,5356.21507,N,02734.86356,E,00.00,252.7,290508,,,A*62 +$PORZD,A,022.5*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.1*02 +$GPGGA,123527.000,5356.21503,N,02734.86331,E,1,05,05.9,254.1,M,26.0,M,,*6E +$GPRMC,123528.000,A,5356.21500,N,02734.86330,E,00.00,252.7,290508,,,A*6A +$PORZD,A,022.5*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.1*02 +$GPGGA,123528.000,5356.21500,N,02734.86332,E,1,06,04.9,254.2,M,26.0,M,,*60 +$GPRMC,123529.000,A,5356.21497,N,02734.86332,E,00.00,252.7,290508,,,A*66 +$PORZD,A,018.0*35 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123529.000,5356.21498,N,02734.86331,E,1,06,04.9,254.2,M,26.0,M,,*62 +$GPRMC,123530.000,A,5356.21496,N,02734.86329,E,00.00,252.7,290508,,,A*65 +$PORZD,A,017.4*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123530.000,5356.21496,N,02734.86329,E,1,06,04.9,254.2,M,26.0,M,,*6D +$GPRMC,123531.000,A,5356.21494,N,02734.86327,E,00.00,252.7,290508,,,A*68 +$PORZD,A,017.0*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123531.000,5356.21498,N,02734.86346,E,1,06,04.9,254.2,M,26.0,M,,*6B +$GPRMC,123532.000,A,5356.21496,N,02734.86347,E,00.00,252.7,290508,,,A*6F +$PORZD,A,016.6*3D +$GPGSV,3,1,12,02,12,247,,03,11,065,,07,76,086,36,13,48,101,51*7F +$GPGSV,3,2,12,23,12,106,45,25,55,069,38,27,83,107,29,28,05,181,44*78 +$GPGSV,3,3,12,33,17,229,,37,28,187,,39,28,183,,44,20,137,*78 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123532.000,5356.21499,N,02734.86359,E,1,06,04.9,254.2,M,26.0,M,,*67 +$GPRMC,123533.000,A,5356.21497,N,02734.86358,E,00.00,252.7,290508,,,A*61 +$PORZD,A,016.5*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123533.000,5356.21499,N,02734.86368,E,1,06,04.9,254.2,M,26.0,M,,*64 +$GPRMC,123534.000,A,5356.21497,N,02734.86369,E,00.00,252.7,290508,,,A*64 +$PORZD,A,016.5*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123534.000,5356.21499,N,02734.86376,E,1,06,04.9,254.2,M,26.0,M,,*6C +$GPRMC,123535.000,A,5356.21497,N,02734.86375,E,00.00,252.7,290508,,,A*68 +$PORZD,A,016.4*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123535.000,5356.21499,N,02734.86381,E,1,06,04.9,254.2,M,26.0,M,,*65 +$GPRMC,123536.000,A,5356.21495,N,02734.86381,E,00.00,252.7,290508,,,A*62 +$PORZD,A,016.3*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123536.000,5356.21498,N,02734.86385,E,1,06,04.9,254.3,M,26.0,M,,*62 +$GPRMC,123537.000,A,5356.21496,N,02734.86386,E,00.00,252.7,290508,,,A*67 +$PORZD,A,016.3*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123537.000,5356.21498,N,02734.86387,E,1,06,04.9,254.3,M,26.0,M,,*61 +$GPRMC,123538.000,A,5356.21497,N,02734.86386,E,00.00,252.7,290508,,,A*69 +$PORZD,A,016.2*39 +$GPGSV,3,1,12,02,12,247,,03,11,065,,07,76,086,36,13,48,101,50*7E +$GPGSV,3,2,12,23,12,106,46,25,55,069,38,27,83,107,29,28,05,181,45*7A +$GPGSV,3,3,12,33,17,229,,37,28,187,,39,28,183,,44,20,137,*78 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123538.000,5356.21499,N,02734.86387,E,1,06,04.9,254.3,M,26.0,M,,*6F +$GPRMC,123539.000,A,5356.21496,N,02734.86387,E,00.00,252.7,290508,,,A*68 +$PORZD,A,016.2*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123539.000,5356.21499,N,02734.86387,E,1,06,04.9,254.3,M,26.0,M,,*6E +$GPRMC,123540.000,A,5356.21497,N,02734.86387,E,00.00,252.7,290508,,,A*67 +$PORZD,A,016.1*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123540.000,5356.21500,N,02734.86385,E,1,06,04.9,254.3,M,26.0,M,,*63 +$GPRMC,123541.000,A,5356.21498,N,02734.86385,E,00.00,252.7,290508,,,A*6B +$PORZD,A,016.1*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123541.000,5356.21499,N,02734.86371,E,1,06,04.9,254.4,M,26.0,M,,*6F +$GPRMC,123542.000,A,5356.21496,N,02734.86371,E,00.00,252.7,290508,,,A*6D +$PORZD,A,016.3*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123542.000,5356.21499,N,02734.86359,E,1,06,04.9,254.4,M,26.0,M,,*66 +$GPRMC,123543.000,A,5356.21495,N,02734.86360,E,00.00,252.7,290508,,,A*6F +$PORZD,A,016.2*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123543.000,5356.21499,N,02734.86349,E,1,06,04.9,254.4,M,26.0,M,,*66 +$GPRMC,123544.000,A,5356.21498,N,02734.86347,E,00.00,252.7,290508,,,A*60 +$PORZD,A,016.2*39 +$GPGSV,3,1,12,02,12,247,,03,11,065,,07,76,086,35,13,48,101,50*7D +$GPGSV,3,2,12,23,12,106,46,25,55,069,38,27,83,107,29,28,05,181,45*7A +$GPGSV,3,3,12,33,17,229,,37,28,187,,39,28,183,,44,20,137,*78 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.9,04.1*03 +$GPGGA,123544.000,5356.21501,N,02734.86338,E,1,06,04.9,254.4,M,26.0,M,,*67 +$GPRMC,123545.000,A,5356.21498,N,02734.86336,E,00.00,252.7,290508,,,A*67 +$PORZD,A,016.1*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.9,04.1*03 +$GPGGA,123545.000,5356.21502,N,02734.86328,E,1,06,04.8,254.4,M,26.0,M,,*65 +$GPRMC,123546.000,A,5356.21499,N,02734.86329,E,00.00,252.7,290508,,,A*6B +$PORZD,A,016.1*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123546.000,5356.21502,N,02734.86322,E,1,06,04.8,254.4,M,26.0,M,,*6C +$GPRMC,123547.000,A,5356.21499,N,02734.86322,E,00.00,252.7,290508,,,A*61 +$PORZD,A,016.1*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123547.000,5356.21503,N,02734.86315,E,1,06,04.8,254.3,M,26.0,M,,*6F +$GPRMC,123548.000,A,5356.21500,N,02734.86314,E,00.00,252.7,290508,,,A*6A +$PORZD,A,016.0*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123548.000,5356.21502,N,02734.86310,E,1,06,04.8,254.4,M,26.0,M,,*63 +$GPRMC,123549.000,A,5356.21498,N,02734.86310,E,00.00,252.7,290508,,,A*6F +$PORZD,A,016.0*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123549.000,5356.21503,N,02734.86304,E,1,06,04.8,254.4,M,26.0,M,,*66 +$GPRMC,123550.000,A,5356.21500,N,02734.86304,E,00.00,252.7,290508,,,A*62 +$PORZD,A,016.0*3B +$GPGSV,3,1,12,02,12,247,,03,11,065,,07,76,086,35,13,48,101,50*7D +$GPGSV,3,2,12,23,12,106,46,25,55,069,38,27,83,107,28,28,05,181,45*7B +$GPGSV,3,3,12,33,17,229,,37,28,187,,39,28,183,,44,20,137,*78 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123550.000,5356.21503,N,02734.86299,E,1,06,04.8,254.4,M,26.0,M,,*6B +$GPRMC,123551.000,A,5356.21500,N,02734.86299,E,00.00,252.7,290508,,,A*66 +$PORZD,A,016.0*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123551.000,5356.21504,N,02734.86294,E,1,06,04.8,254.3,M,26.0,M,,*67 +$GPRMC,123552.000,A,5356.21501,N,02734.86294,E,00.00,252.7,290508,,,A*69 +$PORZD,A,016.0*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123552.000,5356.21504,N,02734.86291,E,1,06,04.8,254.4,M,26.0,M,,*66 +$GPRMC,123553.000,A,5356.21500,N,02734.86291,E,00.00,252.7,290508,,,A*6C +$PORZD,A,016.0*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123553.000,5356.21505,N,02734.86296,E,1,06,04.8,254.4,M,26.0,M,,*61 +$GPRMC,123554.000,A,5356.21503,N,02734.86296,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.9*31 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123554.000,5356.21506,N,02734.86301,E,1,06,04.8,254.4,M,26.0,M,,*6A +$GPRMC,123555.000,A,5356.21504,N,02734.86300,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.9*31 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123555.000,5356.21507,N,02734.86304,E,1,06,04.8,254.5,M,26.0,M,,*6E +$GPRMC,123556.000,A,5356.21504,N,02734.86303,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.9*31 +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,086,36*75 +$GPGSV,4,2,13,13,47,102,50,23,12,106,46,25,55,069,38,27,83,105,30*77 +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123556.000,5356.21507,N,02734.86306,E,1,06,04.8,254.5,M,26.0,M,,*6F +$GPRMC,123557.000,A,5356.21505,N,02734.86306,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.9*31 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123557.000,5356.21508,N,02734.86307,E,1,06,04.8,254.5,M,26.0,M,,*60 +$GPRMC,123558.000,A,5356.21505,N,02734.86306,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123558.000,5356.21508,N,02734.86308,E,1,06,04.8,254.5,M,26.0,M,,*60 +$GPRMC,123559.000,A,5356.21505,N,02734.86309,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123559.000,5356.21508,N,02734.86309,E,1,06,04.8,254.5,M,26.0,M,,*60 +$GPRMC,123600.000,A,5356.21505,N,02734.86309,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123600.000,5356.21508,N,02734.86309,E,1,06,04.8,254.5,M,26.0,M,,*6F +$GPRMC,123601.000,A,5356.21506,N,02734.86309,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123601.000,5356.21509,N,02734.86307,E,1,06,04.8,254.5,M,26.0,M,,*61 +$GPRMC,123602.000,A,5356.21506,N,02734.86307,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.8*30 +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,086,34*77 +$GPGSV,4,2,13,13,47,102,51,23,12,106,45,25,55,069,38,27,83,105,30*75 +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123602.000,5356.21508,N,02734.86308,E,1,06,04.8,254.5,M,26.0,M,,*6C +$GPRMC,123603.000,A,5356.21503,N,02734.86309,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123603.000,5356.21507,N,02734.86308,E,1,06,04.8,254.6,M,26.0,M,,*61 +$GPRMC,123604.000,A,5356.21504,N,02734.86308,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123604.000,5356.21508,N,02734.86306,E,1,06,04.8,254.5,M,26.0,M,,*64 +$GPRMC,123605.000,A,5356.21506,N,02734.86306,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123605.000,5356.21508,N,02734.86304,E,1,06,04.8,254.5,M,26.0,M,,*67 +$GPRMC,123606.000,A,5356.21505,N,02734.86304,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123606.000,5356.21509,N,02734.86302,E,1,06,04.8,254.5,M,26.0,M,,*63 +$GPRMC,123607.000,A,5356.21506,N,02734.86302,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123607.000,5356.21508,N,02734.86301,E,1,06,04.8,254.5,M,26.0,M,,*60 +$GPRMC,123608.000,A,5356.21504,N,02734.86302,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.8*30 +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,086,34*77 +$GPGSV,4,2,13,13,47,102,51,23,12,106,45,25,55,069,38,27,83,105,30*75 +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123608.000,5356.21508,N,02734.86299,E,1,06,04.8,254.5,M,26.0,M,,*6F +$GPRMC,123609.000,A,5356.21507,N,02734.86299,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123609.000,5356.21510,N,02734.86297,E,1,06,04.8,254.5,M,26.0,M,,*69 +$GPRMC,123610.000,A,5356.21507,N,02734.86298,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123610.000,5356.21512,N,02734.86295,E,1,06,04.8,254.5,M,26.0,M,,*61 +$GPRMC,123611.000,A,5356.21510,N,02734.86295,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123611.000,5356.21512,N,02734.86293,E,1,06,04.8,254.4,M,26.0,M,,*67 +$GPRMC,123612.000,A,5356.21508,N,02734.86295,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123612.000,5356.21512,N,02734.86291,E,1,06,04.8,254.4,M,26.0,M,,*66 +$GPRMC,123613.000,A,5356.21510,N,02734.86290,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123613.000,5356.21514,N,02734.86287,E,1,06,04.8,254.4,M,26.0,M,,*66 +$GPRMC,123614.000,A,5356.21512,N,02734.86287,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.7*3F +$GPGSV,4,1,13,02,12,247,20,03,11,065,,06,10,045,,07,76,086,34*75 +$GPGSV,4,2,13,13,47,102,51,23,12,106,46,25,55,069,38,27,83,105,29*7E +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123614.000,5356.21515,N,02734.86283,E,1,06,04.8,254.4,M,26.0,M,,*64 +$GPRMC,123615.000,A,5356.21512,N,02734.86284,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123615.000,5356.21516,N,02734.86281,E,1,06,04.8,254.4,M,26.0,M,,*64 +$GPRMC,123616.000,A,5356.21513,N,02734.86280,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123616.000,5356.21517,N,02734.86276,E,1,06,04.8,254.4,M,26.0,M,,*6E +$GPRMC,123617.000,A,5356.21515,N,02734.86276,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123617.000,5356.21518,N,02734.86271,E,1,06,04.8,254.4,M,26.0,M,,*67 +$GPRMC,123618.000,A,5356.21515,N,02734.86272,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123618.000,5356.21519,N,02734.86266,E,1,06,04.8,254.4,M,26.0,M,,*6F +$GPRMC,123619.000,A,5356.21516,N,02734.86267,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123619.000,5356.21520,N,02734.86260,E,1,06,04.8,254.4,M,26.0,M,,*62 +$GPRMC,123620.000,A,5356.21518,N,02734.86259,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.7*3F +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,086,34*77 +$GPGSV,4,2,13,13,47,102,50,23,12,106,45,25,55,069,38,27,83,105,29*7C +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123620.000,5356.21521,N,02734.86254,E,1,06,04.8,254.4,M,26.0,M,,*6E +$GPRMC,123621.000,A,5356.21519,N,02734.86254,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123621.000,5356.21523,N,02734.86248,E,1,06,04.8,254.4,M,26.0,M,,*60 +$GPRMC,123622.000,A,5356.21520,N,02734.86249,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123622.000,5356.21523,N,02734.86244,E,1,06,04.8,254.4,M,26.0,M,,*6F +$GPRMC,123623.000,A,5356.21521,N,02734.86244,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123623.000,5356.21525,N,02734.86241,E,1,06,04.8,254.5,M,26.0,M,,*6C +$GPRMC,123624.000,A,5356.21522,N,02734.86242,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123624.000,5356.21526,N,02734.86245,E,1,06,04.8,254.5,M,26.0,M,,*6C +$GPRMC,123625.000,A,5356.21523,N,02734.86246,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123625.000,5356.21527,N,02734.86242,E,1,06,04.8,254.6,M,26.0,M,,*68 +$GPRMC,123626.000,A,5356.21526,N,02734.86241,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.6*3E +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,085,35*75 +$GPGSV,4,2,13,13,47,102,50,23,12,106,45,25,55,069,38,27,83,104,30*75 +$GPGSV,4,3,13,28,05,181,46,33,17,229,,37,28,187,,39,28,183,*7C +$GPGSV,4,4,13,44,20,137,*4C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123626.000,5356.21529,N,02734.86243,E,1,06,04.8,254.6,M,26.0,M,,*64 +$GPRMC,123627.000,A,5356.21526,N,02734.86243,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123627.000,5356.21529,N,02734.86247,E,1,06,04.8,254.6,M,26.0,M,,*61 +$GPRMC,123628.000,A,5356.21525,N,02734.86250,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123628.000,5356.21526,N,02734.86245,E,1,06,04.8,254.7,M,26.0,M,,*62 +$GPRMC,123629.000,A,5356.21524,N,02734.86244,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123629.000,5356.21527,N,02734.86247,E,1,06,04.8,254.7,M,26.0,M,,*60 +$GPRMC,123630.000,A,5356.21524,N,02734.86249,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123630.000,5356.21525,N,02734.86244,E,1,06,04.8,254.8,M,26.0,M,,*66 +$GPRMC,123631.000,A,5356.21522,N,02734.86244,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123631.000,5356.21524,N,02734.86240,E,1,06,04.8,254.8,M,26.0,M,,*62 +$GPRMC,123632.000,A,5356.21521,N,02734.86240,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.5*3D +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,085,34*74 +$GPGSV,4,2,13,13,47,102,51,23,12,106,46,25,55,069,39,27,83,104,31*77 +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123632.000,5356.21522,N,02734.86236,E,1,06,04.8,254.8,M,26.0,M,,*66 +$GPRMC,123633.000,A,5356.21519,N,02734.86238,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123633.000,5356.21519,N,02734.86234,E,1,06,04.8,254.9,M,26.0,M,,*6C +$GPRMC,123634.000,A,5356.21517,N,02734.86234,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123634.000,5356.21516,N,02734.86231,E,1,06,04.8,255.0,M,26.0,M,,*69 +$GPRMC,123635.000,A,5356.21512,N,02734.86232,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123635.000,5356.21513,N,02734.86229,E,1,06,04.8,255.0,M,26.0,M,,*64 +$GPRMC,123636.000,A,5356.21510,N,02734.86229,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123636.000,5356.21511,N,02734.86226,E,1,06,04.8,255.1,M,26.0,M,,*6B +$GPRMC,123637.000,A,5356.21508,N,02734.86227,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123637.000,5356.21509,N,02734.86224,E,1,06,04.8,255.1,M,26.0,M,,*61 +$GPRMC,123638.000,A,5356.21507,N,02734.86225,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.5*3D +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,085,35*75 +$GPGSV,4,2,13,13,47,102,50,23,12,106,46,25,55,069,38,27,83,104,31*77 +$GPGSV,4,3,13,28,05,181,46,33,17,229,,37,28,187,,39,28,183,*7C +$GPGSV,4,4,13,44,20,137,*4C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123638.000,5356.21507,N,02734.86222,E,1,06,04.8,255.1,M,26.0,M,,*66 +$GPRMC,123639.000,A,5356.21504,N,02734.86223,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123639.000,5356.21505,N,02734.86221,E,1,06,04.8,255.2,M,26.0,M,,*65 +$GPRMC,123640.000,A,5356.21502,N,02734.86221,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123640.000,5356.21504,N,02734.86219,E,1,06,04.8,255.2,M,26.0,M,,*61 +$GPRMC,123641.000,A,5356.21501,N,02734.86220,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123641.000,5356.21503,N,02734.86218,E,1,06,04.8,255.2,M,26.0,M,,*66 +$GPRMC,123642.000,A,5356.21500,N,02734.86219,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123642.000,5356.21502,N,02734.86217,E,1,06,04.8,255.2,M,26.0,M,,*6B +$GPRMC,123643.000,A,5356.21499,N,02734.86217,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123643.000,5356.21501,N,02734.86216,E,1,06,04.8,255.3,M,26.0,M,,*69 +$GPRMC,123644.000,A,5356.21498,N,02734.86216,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.4*3C +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,085,35*75 +$GPGSV,4,2,13,13,47,102,51,23,12,106,46,25,55,069,37,27,83,104,32*7A +$GPGSV,4,3,13,28,05,181,46,33,17,229,,37,28,187,,39,28,183,*7C +$GPGSV,4,4,13,44,20,137,*4C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123644.000,5356.21502,N,02734.86215,E,1,06,04.8,255.2,M,26.0,M,,*6F +$GPRMC,123645.000,A,5356.21500,N,02734.86213,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123645.000,5356.21503,N,02734.86213,E,1,06,04.8,255.2,M,26.0,M,,*69 +$GPRMC,123646.000,A,5356.21500,N,02734.86214,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123646.000,5356.21503,N,02734.86212,E,1,06,04.8,255.2,M,26.0,M,,*6B +$GPRMC,123647.000,A,5356.21501,N,02734.86213,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123647.000,5356.21504,N,02734.86212,E,1,06,04.8,255.2,M,26.0,M,,*6D +$GPRMC,123648.000,A,5356.21501,N,02734.86212,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123648.000,5356.21505,N,02734.86212,E,1,06,04.8,255.1,M,26.0,M,,*60 +$GPRMC,123649.000,A,5356.21503,N,02734.86212,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123649.000,5356.21505,N,02734.86212,E,1,06,04.8,255.1,M,26.0,M,,*61 +$GPRMC,123650.000,A,5356.21502,N,02734.86214,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.4*3C +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,085,35*75 +$GPGSV,4,2,13,13,47,102,50,23,12,106,45,25,55,069,37,27,83,104,31*7B +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123650.000,5356.21505,N,02734.86213,E,1,06,04.8,255.1,M,26.0,M,,*68 +$GPRMC,123651.000,A,5356.21503,N,02734.86213,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123651.000,5356.21507,N,02734.86211,E,1,06,04.8,255.1,M,26.0,M,,*69 +$GPRMC,123652.000,A,5356.21504,N,02734.86211,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123652.000,5356.21508,N,02734.86209,E,1,06,04.8,255.0,M,26.0,M,,*6D +$GPRMC,123653.000,A,5356.21506,N,02734.86208,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123653.000,5356.21511,N,02734.86215,E,1,06,04.8,255.0,M,26.0,M,,*69 +$GPRMC,123654.000,A,5356.21508,N,02734.86216,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123654.000,5356.21514,N,02734.86221,E,1,06,04.8,255.1,M,26.0,M,,*6D +$GPRMC,123655.000,A,5356.21510,N,02734.86222,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123655.000,5356.21516,N,02734.86225,E,1,06,04.8,255.1,M,26.0,M,,*6A +$GPRMC,123656.000,A,5356.21514,N,02734.86225,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.3*3B +$GPGSV,4,1,14,02,12,247,,03,11,065,,06,10,045,,07,75,084,35*70 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,12,106,47,25,54,069,37*76 +$GPGSV,4,3,14,27,83,102,32,28,05,181,45,33,17,229,,37,28,187,*7E +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123656.000,5356.21518,N,02734.86229,E,1,06,04.8,255.1,M,26.0,M,,*6B +$GPRMC,123657.000,A,5356.21515,N,02734.86230,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123657.000,5356.21519,N,02734.86231,E,1,06,04.8,255.1,M,26.0,M,,*62 +$GPRMC,123658.000,A,5356.21517,N,02734.86231,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123658.000,5356.21521,N,02734.86233,E,1,06,04.8,255.1,M,26.0,M,,*64 +$GPRMC,123659.000,A,5356.21519,N,02734.86233,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123659.000,5356.21524,N,02734.86232,E,1,06,04.8,255.1,M,26.0,M,,*61 +$GPRMC,123700.000,A,5356.21522,N,02734.86232,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123700.000,5356.21526,N,02734.86232,E,1,06,04.8,255.0,M,26.0,M,,*6F +$GPRMC,123701.000,A,5356.21522,N,02734.86233,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123701.000,5356.21526,N,02734.86232,E,1,06,04.8,255.1,M,26.0,M,,*6F +$GPRMC,123702.000,A,5356.21524,N,02734.86232,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.3*3B +$GPGSV,4,1,14,02,12,247,,03,11,065,,06,10,045,,07,75,084,34*71 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,12,106,46,25,54,069,38*78 +$GPGSV,4,3,14,27,83,102,31,28,05,181,45,33,17,229,,37,28,187,*7D +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123702.000,5356.21528,N,02734.86231,E,1,06,04.8,255.0,M,26.0,M,,*60 +$GPRMC,123703.000,A,5356.21526,N,02734.86231,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123703.000,5356.21529,N,02734.86230,E,1,06,04.8,255.0,M,26.0,M,,*61 +$GPRMC,123704.000,A,5356.21526,N,02734.86230,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123704.000,5356.21530,N,02734.86228,E,1,06,04.8,255.0,M,26.0,M,,*67 +$GPRMC,123705.000,A,5356.21528,N,02734.86228,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123705.000,5356.21533,N,02734.86226,E,1,06,04.8,255.0,M,26.0,M,,*6B +$GPRMC,123706.000,A,5356.21530,N,02734.86226,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123706.000,5356.21534,N,02734.86224,E,1,06,04.8,255.0,M,26.0,M,,*6D +$GPRMC,123707.000,A,5356.21531,N,02734.86225,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123707.000,5356.21536,N,02734.86223,E,1,06,04.7,254.9,M,26.0,M,,*6E +$GPRMC,123708.000,A,5356.21534,N,02734.86222,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.2*3A +$GPGSV,4,1,14,02,12,247,,03,11,065,,06,10,045,,07,75,084,36*73 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,12,106,45,25,54,069,38*7B +$GPGSV,4,3,14,27,83,102,31,28,05,181,46,33,17,229,,37,28,187,*7E +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123708.000,5356.21539,N,02734.86220,E,1,06,04.7,254.9,M,26.0,M,,*6D +$GPRMC,123709.000,A,5356.21536,N,02734.86219,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123709.000,5356.21541,N,02734.86218,E,1,06,04.7,254.8,M,26.0,M,,*69 +$GPRMC,123710.000,A,5356.21538,N,02734.86220,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123710.000,5356.21542,N,02734.86219,E,1,06,04.7,254.8,M,26.0,M,,*63 +$GPRMC,123711.000,A,5356.21539,N,02734.86219,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123711.000,5356.21543,N,02734.86218,E,1,06,04.7,254.8,M,26.0,M,,*62 +$GPRMC,123712.000,A,5356.21541,N,02734.86218,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123712.000,5356.21544,N,02734.86218,E,1,06,04.7,254.7,M,26.0,M,,*69 +$GPRMC,123713.000,A,5356.21541,N,02734.86219,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123713.000,5356.21544,N,02734.86218,E,1,06,04.7,254.7,M,26.0,M,,*68 +$GPRMC,123714.000,A,5356.21541,N,02734.86219,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.2*3A +$GPGSV,4,1,14,02,12,247,,03,11,065,,06,10,045,,07,75,084,35*70 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,12,106,46,25,54,069,38*78 +$GPGSV,4,3,14,27,83,102,31,28,05,181,45,33,17,229,,37,28,187,*7D +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123714.000,5356.21544,N,02734.86217,E,1,06,04.7,254.7,M,26.0,M,,*60 +$GPRMC,123715.000,A,5356.21542,N,02734.86218,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123715.000,5356.21544,N,02734.86216,E,1,06,04.7,254.7,M,26.0,M,,*60 +$GPRMC,123716.000,A,5356.21542,N,02734.86216,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123716.000,5356.21544,N,02734.86215,E,1,06,04.7,254.7,M,26.0,M,,*60 +$GPRMC,123717.000,A,5356.21542,N,02734.86215,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123717.000,5356.21543,N,02734.86213,E,1,06,04.7,254.7,M,26.0,M,,*60 +$GPRMC,123718.000,A,5356.21540,N,02734.86214,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123718.000,5356.21542,N,02734.86211,E,1,06,04.7,254.7,M,26.0,M,,*6C +$GPRMC,123719.000,A,5356.21540,N,02734.86211,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123719.000,5356.21542,N,02734.86209,E,1,06,04.7,254.7,M,26.0,M,,*64 +$GPRMC,123720.000,A,5356.21539,N,02734.86210,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.2*3A +$GPGSV,4,1,14,02,12,247,,03,11,065,,06,10,045,,07,75,084,34*71 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,12,106,46,25,54,069,38*78 +$GPGSV,4,3,14,27,83,102,31,28,05,181,46,33,17,229,,37,28,187,*7E +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123720.000,5356.21542,N,02734.86206,E,1,06,04.7,254.7,M,26.0,M,,*61 +$GPRMC,123721.000,A,5356.21540,N,02734.86205,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123721.000,5356.21543,N,02734.86202,E,1,06,04.7,254.7,M,26.0,M,,*65 +$GPRMC,123722.000,A,5356.21541,N,02734.86202,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123722.000,5356.21543,N,02734.86198,E,1,06,04.7,254.7,M,26.0,M,,*66 +$GPRMC,123723.000,A,5356.21541,N,02734.86198,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123723.000,5356.21546,N,02734.86203,E,1,06,04.7,254.7,M,26.0,M,,*63 +$GPRMC,123724.000,A,5356.21543,N,02734.86203,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123724.000,5356.21548,N,02734.86207,E,1,06,04.7,254.8,M,26.0,M,,*61 +$GPRMC,123725.000,A,5356.21544,N,02734.86208,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123725.000,5356.21549,N,02734.86210,E,1,06,04.7,254.8,M,26.0,M,,*67 +$GPRMC,123726.000,A,5356.21547,N,02734.86211,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.2*3A +$GPGSV,4,1,14,02,12,247,,03,11,064,,06,10,044,,07,75,084,34*71 +$GPGSV,4,2,14,08,59,224,,13,47,102,51,23,11,106,45,25,54,068,38*78 +$GPGSV,4,3,14,27,83,101,31,28,05,181,46,33,17,229,,37,28,187,*7D +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123726.000,5356.21550,N,02734.86213,E,1,06,04.7,254.8,M,26.0,M,,*6F +$GPRMC,123727.000,A,5356.21547,N,02734.86213,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123727.000,5356.21552,N,02734.86214,E,1,06,04.7,254.9,M,26.0,M,,*6A +$GPRMC,123728.000,A,5356.21550,N,02734.86214,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123728.000,5356.21553,N,02734.86215,E,1,06,04.7,254.9,M,26.0,M,,*65 +$GPRMC,123729.000,A,5356.21551,N,02734.86214,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123729.000,5356.21555,N,02734.86214,E,1,06,04.7,254.8,M,26.0,M,,*62 +$GPRMC,123730.000,A,5356.21553,N,02734.86214,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123730.000,5356.21557,N,02734.86213,E,1,06,04.7,254.8,M,26.0,M,,*6F +$GPRMC,123731.000,A,5356.21554,N,02734.86214,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123731.000,5356.21557,N,02734.86212,E,1,06,04.7,254.8,M,26.0,M,,*6F +$GPRMC,123732.000,A,5356.21555,N,02734.86212,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.1*39 +$GPGSV,4,1,14,02,12,247,,03,11,064,,06,10,044,,07,75,084,34*71 +$GPGSV,4,2,14,08,59,224,,13,47,102,51,23,11,106,46,25,54,068,38*7B +$GPGSV,4,3,14,27,83,101,32,28,05,181,45,33,17,229,,37,28,187,*7D +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123732.000,5356.21558,N,02734.86210,E,1,06,04.7,254.8,M,26.0,M,,*61 +$GPRMC,123733.000,A,5356.21556,N,02734.86211,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123733.000,5356.21559,N,02734.86209,E,1,06,04.7,254.8,M,26.0,M,,*69 +$GPRMC,123734.000,A,5356.21555,N,02734.86209,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123734.000,5356.21559,N,02734.86207,E,1,06,04.7,254.8,M,26.0,M,,*60 +$GPRMC,123735.000,A,5356.21557,N,02734.86207,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123735.000,5356.21559,N,02734.86206,E,1,06,04.7,254.8,M,26.0,M,,*60 +$GPRMC,123736.000,A,5356.21556,N,02734.86206,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123736.000,5356.21560,N,02734.86204,E,1,06,04.7,254.8,M,26.0,M,,*6B +$GPRMC,123737.000,A,5356.21558,N,02734.86205,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123737.000,5356.21560,N,02734.86202,E,1,06,04.7,254.8,M,26.0,M,,*6C +$GPRMC,123738.000,A,5356.21558,N,02734.86202,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.1*39 +$GPGSV,4,1,14,02,12,247,,03,11,064,18,06,10,044,,07,75,084,34*78 +$GPGSV,4,2,14,08,59,224,,13,47,102,51,23,11,106,47,25,54,068,38*7A +$GPGSV,4,3,14,27,83,101,32,28,05,181,45,33,17,229,,37,28,187,*7D +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123738.000,5356.21562,N,02734.86199,E,1,06,04.7,254.8,M,26.0,M,,*60 +$GPRMC,123739.000,A,5356.21559,N,02734.86199,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123739.000,5356.21564,N,02734.86196,E,1,06,04.7,254.8,M,26.0,M,,*68 +$GPRMC,123740.000,A,5356.21563,N,02734.86196,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123740.000,5356.21567,N,02734.86194,E,1,06,04.7,254.7,M,26.0,M,,*68 +$GPRMC,123741.000,A,5356.21564,N,02734.86194,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123741.000,5356.21568,N,02734.86192,E,1,06,04.7,254.7,M,26.0,M,,*60 +$GPRMC,123742.000,A,5356.21566,N,02734.86192,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123742.000,5356.21570,N,02734.86190,E,1,06,04.7,254.7,M,26.0,M,,*68 +$GPRMC,123743.000,A,5356.21567,N,02734.86191,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123743.000,5356.21571,N,02734.86189,E,1,06,04.7,254.6,M,26.0,M,,*61 +$GPRMC,123744.000,A,5356.21568,N,02734.86189,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.3*3B +$GPGSV,4,1,14,02,12,247,,03,11,064,,06,10,044,,07,75,084,35*70 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,11,106,46,25,54,068,38*7A +$GPGSV,4,3,14,27,83,101,32,28,05,181,46,33,17,229,,37,28,187,*7E +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123744.000,5356.21572,N,02734.86187,E,1,06,04.7,254.6,M,26.0,M,,*6B +$GPRMC,123745.000,A,5356.21570,N,02734.86186,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123745.000,5356.21573,N,02734.86184,E,1,06,04.7,254.6,M,26.0,M,,*68 +$GPRMC,123746.000,A,5356.21571,N,02734.86184,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123746.000,5356.21574,N,02734.86181,E,1,06,04.7,254.6,M,26.0,M,,*69 +$GPRMC,123747.000,A,5356.21571,N,02734.86182,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123747.000,5356.21573,N,02734.86179,E,1,06,04.7,254.6,M,26.0,M,,*68 +$GPRMC,123748.000,A,5356.21570,N,02734.86179,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123748.000,5356.21573,N,02734.86175,E,1,06,04.7,254.6,M,26.0,M,,*6B +$GPRMC,123749.000,A,5356.21572,N,02734.86175,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123749.000,5356.21573,N,02734.86173,E,1,06,04.7,254.6,M,26.0,M,,*6C +$GPRMC,123750.000,A,5356.21569,N,02734.86174,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.3*3B +$GPGSV,4,1,14,02,12,247,,03,11,064,,06,10,044,,07,75,084,35*70 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,11,106,46,25,54,068,38*7A +$GPGSV,4,3,14,27,83,101,32,28,05,181,47,33,17,229,,37,28,187,*7F +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123750.000,5356.21570,N,02734.86172,E,1,06,04.7,254.6,M,26.0,M,,*66 +$GPRMC,123751.000,A,5356.21568,N,02734.86171,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123751.000,5356.21570,N,02734.86168,E,1,06,04.7,254.6,M,26.0,M,,*6C +$GPRMC,123752.000,A,5356.21567,N,02734.86169,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123752.000,5356.21569,N,02734.86167,E,1,06,04.7,254.7,M,26.0,M,,*69 +$GPRMC,123753.000,A,5356.21567,N,02734.86166,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123753.000,5356.21570,N,02734.86172,E,1,06,04.7,254.7,M,26.0,M,,*64 +$GPRMC,123754.000,A,5356.21567,N,02734.86172,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123754.000,5356.21570,N,02734.86177,E,1,06,04.7,254.8,M,26.0,M,,*69 +$GPRMC,123755.000,A,5356.21567,N,02734.86178,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123755.000,5356.21570,N,02734.86182,E,1,06,04.7,254.8,M,26.0,M,,*62 +$GPRMC,123756.000,A,5356.21567,N,02734.86183,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.3*3B +$GPGSV,4,1,15,02,12,246,,03,11,064,,06,10,044,,07,75,083,36*74 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,106,46*7F +$GPGSV,4,3,15,25,54,068,38,27,83,099,32,28,06,181,46,33,17,229,*7F +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123756.000,5356.21570,N,02734.86187,E,1,06,04.7,254.8,M,26.0,M,,*64 +$GPRMC,123757.000,A,5356.21567,N,02734.86186,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123757.000,5356.21568,N,02734.86191,E,1,06,04.7,254.9,M,26.0,M,,*6A +$GPRMC,123758.000,A,5356.21565,N,02734.86193,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123758.000,5356.21567,N,02734.86196,E,1,06,04.7,254.9,M,26.0,M,,*6D +$GPRMC,123759.000,A,5356.21565,N,02734.86197,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123759.000,5356.21566,N,02734.86198,E,1,06,04.7,254.9,M,26.0,M,,*63 +$GPRMC,123800.000,A,5356.21563,N,02734.86198,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123800.000,5356.21565,N,02734.86199,E,1,06,04.7,255.0,M,26.0,M,,*6A +$GPRMC,123801.000,A,5356.21563,N,02734.86200,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123801.000,5356.21564,N,02734.86202,E,1,06,04.7,255.0,M,26.0,M,,*6B +$GPRMC,123802.000,A,5356.21562,N,02734.86202,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.3*3B +$GPGSV,4,1,15,02,12,246,,03,11,064,,06,10,044,,07,75,083,35*77 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,106,46*7F +$GPGSV,4,3,15,25,54,068,38,27,83,099,32,28,06,181,46,33,17,229,*7F +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123802.000,5356.21563,N,02734.86203,E,1,06,04.7,255.0,M,26.0,M,,*6E +$GPRMC,123803.000,A,5356.21561,N,02734.86203,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123803.000,5356.21562,N,02734.86205,E,1,06,04.7,255.0,M,26.0,M,,*68 +$GPRMC,123804.000,A,5356.21558,N,02734.86206,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123804.000,5356.21559,N,02734.86207,E,1,06,04.7,255.1,M,26.0,M,,*64 +$GPRMC,123805.000,A,5356.21557,N,02734.86206,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123805.000,5356.21558,N,02734.86207,E,1,06,04.7,255.1,M,26.0,M,,*64 +$GPRMC,123806.000,A,5356.21555,N,02734.86207,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123806.000,5356.21555,N,02734.86208,E,1,06,04.7,255.1,M,26.0,M,,*65 +$GPRMC,123807.000,A,5356.21552,N,02734.86210,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123807.000,5356.21553,N,02734.86210,E,1,06,04.7,255.1,M,26.0,M,,*6B +$GPRMC,123808.000,A,5356.21551,N,02734.86210,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.3*3B +$GPGSV,4,1,15,02,12,246,,03,11,064,,06,10,044,,07,75,083,35*77 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,106,46*7F +$GPGSV,4,3,15,25,54,068,37,27,83,099,32,28,06,181,46,33,17,229,*70 +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123808.000,5356.21552,N,02734.86211,E,1,06,04.7,255.1,M,26.0,M,,*64 +$GPRMC,123809.000,A,5356.21549,N,02734.86212,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123809.000,5356.21550,N,02734.86212,E,1,06,04.7,255.1,M,26.0,M,,*64 +$GPRMC,123810.000,A,5356.21548,N,02734.86212,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123810.000,5356.21550,N,02734.86211,E,1,06,04.7,255.1,M,26.0,M,,*6F +$GPRMC,123811.000,A,5356.21548,N,02734.86211,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123811.000,5356.21549,N,02734.86210,E,1,06,04.7,255.1,M,26.0,M,,*67 +$GPRMC,123812.000,A,5356.21545,N,02734.86211,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123812.000,5356.21548,N,02734.86209,E,1,06,04.7,255.1,M,26.0,M,,*6D +$GPRMC,123813.000,A,5356.21545,N,02734.86210,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123813.000,5356.21548,N,02734.86207,E,1,06,04.7,255.1,M,26.0,M,,*62 +$GPRMC,123814.000,A,5356.21546,N,02734.86207,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.2*3A +$GPGSV,4,1,15,02,12,246,,03,11,064,,06,10,044,,07,75,083,36*74 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,106,45*7C +$GPGSV,4,3,15,25,54,068,38,27,83,099,32,28,06,181,45,33,17,229,*7C +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123814.000,5356.21548,N,02734.86206,E,1,06,04.7,255.1,M,26.0,M,,*64 +$GPRMC,123815.000,A,5356.21544,N,02734.86207,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123815.000,5356.21547,N,02734.86205,E,1,06,04.7,255.1,M,26.0,M,,*69 +$GPRMC,123816.000,A,5356.21545,N,02734.86206,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123816.000,5356.21548,N,02734.86204,E,1,06,04.7,255.1,M,26.0,M,,*64 +$GPRMC,123817.000,A,5356.21545,N,02734.86204,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123817.000,5356.21549,N,02734.86202,E,1,06,04.7,255.1,M,26.0,M,,*62 +$GPRMC,123818.000,A,5356.21546,N,02734.86202,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123818.000,5356.21550,N,02734.86200,E,1,06,04.7,255.0,M,26.0,M,,*66 +$GPRMC,123819.000,A,5356.21547,N,02734.86201,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123819.000,5356.21551,N,02734.86199,E,1,06,04.7,255.0,M,26.0,M,,*65 +$GPRMC,123820.000,A,5356.21548,N,02734.86201,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.1*39 +$GPGSV,4,1,15,02,12,246,,03,11,064,,06,10,044,,07,75,083,36*74 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,106,46*7F +$GPGSV,4,3,15,25,54,068,37,27,83,099,32,28,06,181,45,33,17,229,*73 +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123820.000,5356.21552,N,02734.86199,E,1,06,04.7,255.0,M,26.0,M,,*6C +$GPRMC,123821.000,A,5356.21550,N,02734.86198,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123821.000,5356.21554,N,02734.86196,E,1,06,04.7,254.9,M,26.0,M,,*6C +$GPRMC,123822.000,A,5356.21551,N,02734.86196,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123822.000,5356.21555,N,02734.86193,E,1,06,04.7,254.9,M,26.0,M,,*6B +$GPRMC,123823.000,A,5356.21552,N,02734.86194,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123823.000,5356.21543,N,02734.86204,E,1,07,03.2,255.2,M,26.0,M,,*69 +$GPRMC,123824.000,A,5356.21543,N,02734.86203,E,00.00,252.7,290508,,,A*6D +$PORZD,A,014.2*3B +$GPGSA,A,3,19,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,03.8,03.2,02.2*0C +$GPGGA,123824.000,5356.21547,N,02734.86205,E,1,06,04.7,255.2,M,26.0,M,,*68 +$GPRMC,123825.000,A,5356.21544,N,02734.86207,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123825.000,5356.21551,N,02734.86207,E,1,06,04.7,255.1,M,26.0,M,,*6F +$GPRMC,123826.000,A,5356.21549,N,02734.86206,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.1*39 +$GPGSV,4,1,15,02,11,246,,03,11,064,,06,10,044,,07,75,083,36*77 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,107,47*7F +$GPGSV,4,3,15,25,54,068,37,27,82,098,32,28,06,181,46,33,17,229,*70 +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123826.000,5356.21556,N,02734.86205,E,1,06,04.7,255.1,M,26.0,M,,*69 +$GPRMC,123827.000,A,5356.21553,N,02734.86207,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123827.000,5356.21558,N,02734.86205,E,1,06,04.7,255.0,M,26.0,M,,*67 +$GPRMC,123828.000,A,5356.21555,N,02734.86206,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.0*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123828.000,5356.21561,N,02734.86204,E,1,06,04.7,255.0,M,26.0,M,,*63 +$GPRMC,123829.000,A,5356.21559,N,02734.86204,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.0*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123829.000,5356.21565,N,02734.86202,E,1,06,04.7,254.9,M,26.0,M,,*68 +$GPRMC,123830.000,A,5356.21562,N,02734.86204,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.0*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123830.000,5356.21567,N,02734.86202,E,1,06,04.7,254.9,M,26.0,M,,*62 +$GPRMC,123831.000,A,5356.21566,N,02734.86201,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.0*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E diff --git a/test/daemon/ch-4701.log.chk b/test/daemon/ch-4701.log.chk new file mode 100644 index 0000000..be8d5d0 --- /dev/null +++ b/test/daemon/ch-4701.log.chk @@ -0,0 +1,1372 @@ +$GPGGA,123433.000,5356.21442,N,02734.85952,E,1,04,07.2,251.9,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","lat":53.936907000,"lon":27.580992000,"alt":251.900,"mode":3} +$GPRMC,123434.000,A,5356.21440,N,02734.85946,E,00.00,252.7,290508,,,A*6B +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123434.000,5356.21444,N,02734.85947,E,1,04,07.2,251.9,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064474.000,"ept":0.005,"lat":53.936907333,"lon":27.580991167,"alt":251.900,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"mode":3} +$GPRMC,123435.000,A,5356.21440,N,02734.85945,E,00.00,252.7,290508,,,A*69 +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123435.000,5356.21444,N,02734.85946,E,1,04,07.2,251.9,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064475.000,"ept":0.005,"lat":53.936907333,"lon":27.580991000,"alt":251.900,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"mode":3} +$GPRMC,123436.000,A,5356.21439,N,02734.85943,E,00.00,252.7,290508,,,A*62 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123436.000,5356.21444,N,02734.85946,E,1,04,07.2,251.9,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064476.000,"ept":0.005,"lat":53.936907333,"lon":27.580991000,"alt":251.900,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"mode":3} +$GPRMC,123437.000,A,5356.21443,N,02734.85944,E,00.00,252.7,290508,,,A*69 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123437.000,5356.21447,N,02734.85947,E,1,04,07.2,251.8,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064477.000,"ept":0.005,"lat":53.936907833,"lon":27.580991167,"alt":251.800,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"mode":3} +$GPRMC,123438.000,A,5356.21444,N,02734.85943,E,00.00,252.7,290508,,,A*66 +$PORZD,A,022.9*35 +$GPGSV,3,1,11,02,13,248,,03,11,066,,07,76,087,36,13,48,101,50*71 +$GPGSV,3,2,11,23,12,106,46,25,56,069,39,27,84,110,31,33,17,229,*7A +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +{"class":"SKY","tag":"GSV","xdop":1.53,"ydop":3.75,"vdop":1.85,"tdop":0.96,"hdop":4.05,"gdop":4.55,"pdop":4.45,"satellites":[{"PRN":2,"el":13,"az":248,"ss":0,"used":false},{"PRN":3,"el":11,"az":66,"ss":0,"used":false},{"PRN":7,"el":76,"az":87,"ss":36,"used":true},{"PRN":13,"el":48,"az":101,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":56,"az":69,"ss":39,"used":true},{"PRN":27,"el":84,"az":110,"ss":31,"used":false},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123438.000,5356.21448,N,02734.85946,E,1,04,07.2,251.8,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064478.000,"ept":0.005,"lat":53.936908000,"lon":27.580991000,"alt":251.800,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"mode":3} +$GPRMC,123439.000,A,5356.21445,N,02734.85942,E,00.00,252.7,290508,,,A*67 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123439.000,5356.21450,N,02734.85946,E,1,04,07.2,251.8,M,26.0,M,,*6A +{"class":"TPV","tag":"GGA","time":1212064479.000,"ept":0.005,"lat":53.936908333,"lon":27.580991000,"alt":251.800,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123440.000,A,5356.21447,N,02734.85944,E,00.00,252.7,290508,,,A*6D +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123440.000,5356.21449,N,02734.85945,E,1,04,07.2,251.8,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064480.000,"ept":0.005,"lat":53.936908167,"lon":27.580990833,"alt":251.800,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123441.000,A,5356.21446,N,02734.85940,E,00.00,252.7,290508,,,A*69 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123441.000,5356.21449,N,02734.85942,E,1,04,07.2,251.8,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064481.000,"ept":0.005,"lat":53.936908167,"lon":27.580990333,"alt":251.800,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123442.000,A,5356.21445,N,02734.85940,E,00.00,252.7,290508,,,A*69 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123442.000,5356.21447,N,02734.85942,E,1,04,07.2,251.8,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064482.000,"ept":0.005,"lat":53.936907833,"lon":27.580990333,"alt":251.800,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123443.000,A,5356.21444,N,02734.85939,E,00.00,252.7,290508,,,A*67 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123443.000,5356.21448,N,02734.85942,E,1,04,07.2,251.8,M,26.0,M,,*6A +{"class":"TPV","tag":"GGA","time":1212064483.000,"ept":0.005,"lat":53.936908000,"lon":27.580990333,"alt":251.800,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123444.000,A,5356.21446,N,02734.85940,E,00.00,252.7,290508,,,A*6C +$PORZD,A,022.8*34 +$GPGSV,3,1,11,02,13,248,,03,11,066,,07,76,087,35,13,48,101,50*72 +$GPGSV,3,2,11,23,12,106,47,25,56,069,38,27,84,110,31,33,17,229,*7A +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +{"class":"SKY","tag":"GSV","xdop":1.53,"ydop":3.75,"vdop":1.85,"tdop":0.96,"hdop":4.05,"gdop":4.55,"pdop":4.45,"satellites":[{"PRN":2,"el":13,"az":248,"ss":0,"used":false},{"PRN":3,"el":11,"az":66,"ss":0,"used":false},{"PRN":7,"el":76,"az":87,"ss":35,"used":true},{"PRN":13,"el":48,"az":101,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":47,"used":true},{"PRN":25,"el":56,"az":69,"ss":38,"used":true},{"PRN":27,"el":84,"az":110,"ss":31,"used":false},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123444.000,5356.21450,N,02734.85942,E,1,04,07.2,251.8,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064484.000,"ept":0.005,"lat":53.936908333,"lon":27.580990333,"alt":251.800,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123445.000,A,5356.21446,N,02734.85938,E,00.00,252.7,290508,,,A*62 +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123445.000,5356.21450,N,02734.85941,E,1,04,07.2,251.8,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064485.000,"ept":0.005,"lat":53.936908333,"lon":27.580990167,"alt":251.800,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123446.000,A,5356.21447,N,02734.85936,E,00.00,252.7,290508,,,A*6E +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123446.000,5356.21451,N,02734.85943,E,1,04,07.2,251.9,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064486.000,"ept":0.005,"lat":53.936908500,"lon":27.580990500,"alt":251.900,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123447.000,A,5356.21448,N,02734.85938,E,00.00,252.7,290508,,,A*6E +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.2,07.2,05.7*0D +$GPGGA,123447.000,5356.21452,N,02734.85942,E,1,04,07.2,251.9,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064487.000,"ept":0.005,"lat":53.936908667,"lon":27.580990333,"alt":251.900,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123448.000,A,5356.21449,N,02734.85942,E,00.00,252.7,290508,,,A*6D +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.7*0E +$GPGGA,123448.000,5356.21453,N,02734.85943,E,1,04,07.2,251.9,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064488.000,"ept":0.005,"lat":53.936908833,"lon":27.580990500,"alt":251.900,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123449.000,A,5356.21448,N,02734.85937,E,00.00,252.7,290508,,,A*6F +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.7*0E +$GPGGA,123449.000,5356.21453,N,02734.85941,E,1,04,07.2,251.9,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064489.000,"ept":0.005,"lat":53.936908833,"lon":27.580990167,"alt":251.900,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123450.000,A,5356.21449,N,02734.85935,E,00.00,252.7,290508,,,A*64 +$PORZD,A,022.9*35 +$GPGSV,3,1,11,02,13,248,,03,11,066,,07,76,087,35,13,48,101,51*73 +$GPGSV,3,2,11,23,12,106,45,25,56,069,38,27,84,110,31,33,17,229,*78 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +{"class":"SKY","tag":"GSV","xdop":1.53,"ydop":3.75,"vdop":1.85,"tdop":0.96,"hdop":4.05,"gdop":4.55,"pdop":4.45,"satellites":[{"PRN":2,"el":13,"az":248,"ss":0,"used":false},{"PRN":3,"el":11,"az":66,"ss":0,"used":false},{"PRN":7,"el":76,"az":87,"ss":35,"used":true},{"PRN":13,"el":48,"az":101,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":56,"az":69,"ss":38,"used":true},{"PRN":27,"el":84,"az":110,"ss":31,"used":false},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.7*0E +$GPGGA,123450.000,5356.21454,N,02734.85939,E,1,04,07.2,251.9,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064490.000,"ept":0.005,"lat":53.936909000,"lon":27.580989833,"alt":251.900,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123451.000,A,5356.21452,N,02734.85936,E,00.00,252.7,290508,,,A*6C +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123451.000,5356.21456,N,02734.85939,E,1,04,07.2,251.9,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064491.000,"ept":0.005,"lat":53.936909333,"lon":27.580989833,"alt":251.900,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123452.000,A,5356.21451,N,02734.85935,E,00.00,252.7,290508,,,A*6F +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123452.000,5356.21456,N,02734.85938,E,1,04,07.2,251.9,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064492.000,"ept":0.005,"lat":53.936909333,"lon":27.580989667,"alt":251.900,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123453.000,A,5356.21453,N,02734.85933,E,00.00,252.7,290508,,,A*6A +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123453.000,5356.21458,N,02734.85934,E,1,04,07.2,251.8,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064493.000,"ept":0.005,"lat":53.936909667,"lon":27.580989000,"alt":251.800,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123454.000,A,5356.21455,N,02734.85930,E,00.00,252.7,290508,,,A*68 +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123454.000,5356.21459,N,02734.85931,E,1,04,07.2,251.7,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064494.000,"ept":0.005,"lat":53.936909833,"lon":27.580988500,"alt":251.700,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123455.000,A,5356.21455,N,02734.85927,E,00.00,252.7,290508,,,A*6F +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123455.000,5356.21461,N,02734.85930,E,1,04,07.2,251.6,M,26.0,M,,*6D +{"class":"TPV","tag":"GGA","time":1212064495.000,"ept":0.005,"lat":53.936910167,"lon":27.580988333,"alt":251.600,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123456.000,A,5356.21458,N,02734.85926,E,00.00,252.7,290508,,,A*60 +$PORZD,A,022.8*34 +$GPGSV,3,1,11,02,13,247,,03,11,065,18,07,76,087,37,13,48,101,51*74 +$GPGSV,3,2,11,23,12,106,45,25,55,069,38,27,83,108,32,33,17,229,*76 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":3.64,"vdop":1.85,"tdop":0.96,"hdop":3.96,"gdop":4.48,"pdop":4.38,"satellites":[{"PRN":2,"el":13,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":18,"used":false},{"PRN":7,"el":76,"az":87,"ss":37,"used":true},{"PRN":13,"el":48,"az":101,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":108,"ss":32,"used":false},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123456.000,5356.21463,N,02734.85930,E,1,04,07.2,251.6,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064496.000,"ept":0.005,"lat":53.936910500,"lon":27.580988333,"alt":251.600,"epx":23.004,"epy":56.196,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":112.39,"mode":3} +$GPRMC,123457.000,A,5356.21458,N,02734.85925,E,00.00,252.7,290508,,,A*62 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123457.000,5356.21464,N,02734.85931,E,1,04,07.2,251.5,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064497.000,"ept":0.005,"lat":53.936910667,"lon":27.580988500,"alt":251.500,"epx":23.411,"epy":54.650,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":110.85,"mode":3} +$GPRMC,123458.000,A,5356.21463,N,02734.85930,E,00.00,252.7,290508,,,A*61 +$PORZD,A,022.9*35 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123458.000,5356.21469,N,02734.85938,E,1,04,07.2,251.5,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064498.000,"ept":0.005,"lat":53.936911500,"lon":27.580989667,"alt":251.500,"epx":23.411,"epy":54.650,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":109.30,"mode":3} +$GPRMC,123459.000,A,5356.21465,N,02734.85933,E,00.00,252.7,290508,,,A*65 +$PORZD,A,022.8*34 +$GPGSA,A,3,23,13,07,25,,,,,,,,,,,,,,,,,,,,,09.1,07.2,05.6*0F +$GPGGA,123459.000,5356.21596,N,02734.86645,E,1,05,06.0,255.7,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064499.000,"ept":0.005,"lat":53.936932667,"lon":27.581107500,"alt":255.700,"epx":23.411,"epy":54.650,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":109.30,"mode":3} +$GPRMC,123500.000,A,5356.21592,N,02734.86643,E,00.00,252.7,290508,,,A*6A +$PORZD,A,021.5*3A +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123500.000,5356.21592,N,02734.86641,E,1,05,06.0,255.7,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064500.000,"ept":0.005,"lat":53.936932000,"lon":27.581106833,"alt":255.700,"epx":23.411,"epy":54.650,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":109.30,"mode":3} +$GPRMC,123501.000,A,5356.21589,N,02734.86639,E,00.00,252.7,290508,,,A*6C +$PORZD,A,021.5*3A +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123501.000,5356.21589,N,02734.86638,E,1,05,06.0,255.8,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064501.000,"ept":0.005,"lat":53.936931500,"lon":27.581106333,"alt":255.800,"epx":23.411,"epy":54.650,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":109.30,"mode":3} +$GPRMC,123502.000,A,5356.21587,N,02734.86636,E,00.00,252.7,290508,,,A*6E +$PORZD,A,021.4*3B +$GPGSV,3,1,11,02,13,247,,03,11,065,18,07,76,087,36,13,48,101,50*74 +$GPGSV,3,2,11,23,12,106,46,25,55,069,38,27,83,108,31,33,17,229,*76 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":1.92,"vdop":1.37,"tdop":0.87,"hdop":2.08,"gdop":2.64,"pdop":2.49,"satellites":[{"PRN":2,"el":13,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":18,"used":false},{"PRN":7,"el":76,"az":87,"ss":36,"used":true},{"PRN":13,"el":48,"az":101,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":108,"ss":31,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123502.000,5356.21588,N,02734.86634,E,1,05,06.0,255.8,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064502.000,"ept":0.005,"lat":53.936931333,"lon":27.581105667,"alt":255.800,"epx":23.411,"epy":54.650,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":109.30,"mode":3} +$GPRMC,123503.000,A,5356.21585,N,02734.86631,E,00.00,252.7,290508,,,A*6A +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123503.000,5356.21577,N,02734.86569,E,1,05,06.0,255.4,M,26.0,M,,*6E +{"class":"TPV","tag":"GGA","time":1212064503.000,"ept":0.005,"lat":53.936929500,"lon":27.581094833,"alt":255.400,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":83.49,"mode":3} +$GPRMC,123504.000,A,5356.21573,N,02734.86567,E,00.00,252.7,290508,,,A*64 +$PORZD,A,022.2*3E +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123504.000,5356.21576,N,02734.86571,E,1,05,06.0,255.4,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064504.000,"ept":0.005,"lat":53.936929333,"lon":27.581095167,"alt":255.400,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123505.000,A,5356.21575,N,02734.86568,E,00.00,252.7,290508,,,A*6C +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123505.000,5356.21576,N,02734.86569,E,1,05,06.0,255.5,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064505.000,"ept":0.005,"lat":53.936929333,"lon":27.581094833,"alt":255.500,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123506.000,A,5356.21571,N,02734.86567,E,00.00,252.7,290508,,,A*64 +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123506.000,5356.21566,N,02734.86512,E,1,05,06.0,255.1,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064506.000,"ept":0.005,"lat":53.936927667,"lon":27.581085333,"alt":255.100,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123507.000,A,5356.21562,N,02734.86508,E,00.00,252.7,290508,,,A*6E +$PORZD,A,022.2*3E +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123507.000,5356.21566,N,02734.86514,E,1,05,06.0,255.1,M,26.0,M,,*65 +{"class":"TPV","tag":"GGA","time":1212064507.000,"ept":0.005,"lat":53.936927667,"lon":27.581085667,"alt":255.100,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123508.000,A,5356.21564,N,02734.86514,E,00.00,252.7,290508,,,A*6A +$PORZD,A,021.4*3B +$GPGSV,3,1,11,02,13,247,,03,11,065,,07,76,087,36,13,48,101,51*7C +$GPGSV,3,2,11,23,12,106,45,25,55,069,38,27,83,108,31,33,17,229,*75 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":1.92,"vdop":1.37,"tdop":0.87,"hdop":2.08,"gdop":2.64,"pdop":2.49,"satellites":[{"PRN":2,"el":13,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":7,"el":76,"az":87,"ss":36,"used":true},{"PRN":13,"el":48,"az":101,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":108,"ss":31,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123508.000,5356.21568,N,02734.86517,E,1,05,06.0,255.2,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064508.000,"ept":0.005,"lat":53.936928000,"lon":27.581086167,"alt":255.200,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123509.000,A,5356.21565,N,02734.86514,E,00.00,252.7,290508,,,A*6A +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123509.000,5356.21569,N,02734.86517,E,1,05,06.0,255.1,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064509.000,"ept":0.005,"lat":53.936928167,"lon":27.581086167,"alt":255.100,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123510.000,A,5356.21566,N,02734.86516,E,00.00,252.7,290508,,,A*63 +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123510.000,5356.21569,N,02734.86520,E,1,05,06.0,255.2,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064510.000,"ept":0.005,"lat":53.936928167,"lon":27.581086667,"alt":255.200,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123511.000,A,5356.21565,N,02734.86519,E,00.00,252.7,290508,,,A*6E +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123511.000,5356.21561,N,02734.86474,E,1,05,06.0,254.9,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064511.000,"ept":0.005,"lat":53.936926833,"lon":27.581079000,"alt":254.900,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123512.000,A,5356.21558,N,02734.86470,E,00.00,252.7,290508,,,A*6D +$PORZD,A,022.2*3E +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123512.000,5356.21561,N,02734.86478,E,1,05,06.0,254.9,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064512.000,"ept":0.005,"lat":53.936926833,"lon":27.581079667,"alt":254.900,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123513.000,A,5356.21557,N,02734.86477,E,00.00,252.7,290508,,,A*64 +$PORZD,A,021.4*3B +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123513.000,5356.21553,N,02734.86441,E,1,05,06.0,254.7,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064513.000,"ept":0.005,"lat":53.936925500,"lon":27.581073500,"alt":254.700,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123514.000,A,5356.21551,N,02734.86438,E,00.00,252.7,290508,,,A*6E +$PORZD,A,022.3*3F +$GPGSV,3,1,11,02,13,247,,03,11,065,,07,76,087,37,13,48,101,51*7D +$GPGSV,3,2,11,23,12,106,46,25,55,069,38,27,83,108,30,33,17,229,*77 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":1.92,"vdop":1.37,"tdop":0.87,"hdop":2.08,"gdop":2.64,"pdop":2.49,"satellites":[{"PRN":2,"el":13,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":7,"el":76,"az":87,"ss":37,"used":true},{"PRN":13,"el":48,"az":101,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":108,"ss":30,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123514.000,5356.21548,N,02734.86407,E,1,05,06.0,254.4,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064514.000,"ept":0.005,"lat":53.936924667,"lon":27.581067833,"alt":254.400,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123515.000,A,5356.21544,N,02734.86403,E,00.00,252.7,290508,,,A*63 +$PORZD,A,022.4*38 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123515.000,5356.21549,N,02734.86418,E,1,05,06.0,254.5,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064515.000,"ept":0.005,"lat":53.936924833,"lon":27.581069667,"alt":254.500,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123516.000,A,5356.21546,N,02734.86416,E,00.00,252.7,290508,,,A*66 +$PORZD,A,021.6*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123516.000,5356.21543,N,02734.86390,E,1,05,06.0,254.3,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064516.000,"ept":0.005,"lat":53.936923833,"lon":27.581065000,"alt":254.300,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123517.000,A,5356.21540,N,02734.86387,E,00.00,252.7,290508,,,A*6E +$PORZD,A,022.5*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123517.000,5356.21539,N,02734.86365,E,1,05,06.0,254.2,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064517.000,"ept":0.005,"lat":53.936923167,"lon":27.581060833,"alt":254.200,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123518.000,A,5356.21536,N,02734.86362,E,00.00,252.7,290508,,,A*6B +$PORZD,A,022.5*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123518.000,5356.21540,N,02734.86384,E,1,05,06.0,254.3,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064518.000,"ept":0.005,"lat":53.936923333,"lon":27.581064000,"alt":254.300,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123519.000,A,5356.21536,N,02734.86384,E,00.00,252.7,290508,,,A*62 +$PORZD,A,021.6*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123519.000,5356.21534,N,02734.86366,E,1,05,06.0,254.2,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064519.000,"ept":0.005,"lat":53.936922333,"lon":27.581061000,"alt":254.200,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123520.000,A,5356.21532,N,02734.86362,E,00.00,252.7,290508,,,A*64 +$PORZD,A,022.5*39 +$GPGSV,3,1,11,02,13,247,,03,11,065,,07,76,087,36,13,48,101,50*7D +$GPGSV,3,2,11,23,12,106,47,25,55,069,39,27,83,108,31,33,17,229,*76 +$GPGSV,3,3,11,37,28,187,,39,28,183,,44,20,137,*44 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":1.92,"vdop":1.37,"tdop":0.87,"hdop":2.08,"gdop":2.64,"pdop":2.49,"satellites":[{"PRN":2,"el":13,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":7,"el":76,"az":87,"ss":36,"used":true},{"PRN":13,"el":48,"az":101,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":47,"used":true},{"PRN":25,"el":55,"az":69,"ss":39,"used":true},{"PRN":27,"el":83,"az":108,"ss":31,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123520.000,5356.21536,N,02734.86384,E,1,05,06.0,254.3,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064520.000,"ept":0.005,"lat":53.936922667,"lon":27.581064000,"alt":254.300,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123521.000,A,5356.21532,N,02734.86385,E,00.00,252.7,290508,,,A*6C +$PORZD,A,021.6*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,06.0,05.2*0B +$GPGGA,123521.000,5356.21534,N,02734.86399,E,1,05,05.9,254.5,M,26.0,M,,*6A +{"class":"TPV","tag":"GGA","time":1212064521.000,"ept":0.005,"lat":53.936922333,"lon":27.581066500,"alt":254.500,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123522.000,A,5356.21532,N,02734.86395,E,00.00,252.7,290508,,,A*6E +$PORZD,A,021.6*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.2*01 +$GPGGA,123522.000,5356.21532,N,02734.86407,E,1,05,05.9,254.6,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064522.000,"ept":0.005,"lat":53.936922000,"lon":27.581067833,"alt":254.600,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123523.000,A,5356.21529,N,02734.86407,E,00.00,252.7,290508,,,A*69 +$PORZD,A,021.5*3A +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.2*01 +$GPGGA,123523.000,5356.21524,N,02734.86380,E,1,05,05.9,254.4,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064523.000,"ept":0.005,"lat":53.936920667,"lon":27.581063333,"alt":254.400,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123524.000,A,5356.21521,N,02734.86378,E,00.00,252.7,290508,,,A*69 +$PORZD,A,022.5*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.1*02 +$GPGGA,123524.000,5356.21520,N,02734.86384,E,1,05,05.9,254.4,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064524.000,"ept":0.005,"lat":53.936920000,"lon":27.581064000,"alt":254.400,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123525.000,A,5356.21516,N,02734.86382,E,00.00,252.7,290508,,,A*69 +$PORZD,A,021.6*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.1*02 +$GPGGA,123525.000,5356.21516,N,02734.86385,E,1,05,05.9,254.4,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064525.000,"ept":0.005,"lat":53.936919333,"lon":27.581064167,"alt":254.400,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123526.000,A,5356.21514,N,02734.86386,E,00.00,252.7,290508,,,A*6C +$PORZD,A,021.6*39 +$GPGSV,3,1,12,02,12,247,,03,11,065,,07,76,086,37,13,48,101,51*7E +$GPGSV,3,2,12,23,12,106,45,25,55,069,38,27,83,107,30,28,05,181,40*74 +$GPGSV,3,3,12,33,17,229,,37,28,187,,39,28,183,,44,20,137,*78 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":1.92,"vdop":1.36,"tdop":0.86,"hdop":2.07,"gdop":2.63,"pdop":2.48,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":7,"el":76,"az":86,"ss":37,"used":true},{"PRN":13,"el":48,"az":101,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":107,"ss":30,"used":true},{"PRN":28,"el":5,"az":181,"ss":40,"used":false},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.1*02 +$GPGGA,123526.000,5356.21510,N,02734.86359,E,1,05,05.9,254.3,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064526.000,"ept":0.005,"lat":53.936918333,"lon":27.581059833,"alt":254.300,"epx":11.743,"epy":28.836,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.67,"mode":3} +$GPRMC,123527.000,A,5356.21507,N,02734.86356,E,00.00,252.7,290508,,,A*62 +$PORZD,A,022.5*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.1*02 +$GPGGA,123527.000,5356.21503,N,02734.86331,E,1,05,05.9,254.1,M,26.0,M,,*6E +{"class":"TPV","tag":"GGA","time":1212064527.000,"ept":0.005,"lat":53.936917167,"lon":27.581055167,"alt":254.100,"epx":11.725,"epy":28.790,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.63,"mode":3} +$GPRMC,123528.000,A,5356.21500,N,02734.86330,E,00.00,252.7,290508,,,A*6A +$PORZD,A,022.5*39 +$GPGSA,A,3,27,23,13,07,25,,,,,,,,,,,,,,,,,,,,07.9,05.9,05.1*02 +$GPGGA,123528.000,5356.21500,N,02734.86332,E,1,06,04.9,254.2,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064528.000,"ept":0.005,"lat":53.936916667,"lon":27.581055333,"alt":254.200,"epx":11.725,"epy":28.790,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.58,"mode":3} +$GPRMC,123529.000,A,5356.21497,N,02734.86332,E,00.00,252.7,290508,,,A*66 +$PORZD,A,018.0*35 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123529.000,5356.21498,N,02734.86331,E,1,06,04.9,254.2,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064529.000,"ept":0.005,"lat":53.936916333,"lon":27.581055167,"alt":254.200,"epx":11.725,"epy":28.790,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.58,"mode":3} +$GPRMC,123530.000,A,5356.21496,N,02734.86329,E,00.00,252.7,290508,,,A*65 +$PORZD,A,017.4*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123530.000,5356.21496,N,02734.86329,E,1,06,04.9,254.2,M,26.0,M,,*6D +{"class":"TPV","tag":"GGA","time":1212064530.000,"ept":0.005,"lat":53.936916000,"lon":27.581054833,"alt":254.200,"epx":11.725,"epy":28.790,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.58,"mode":3} +$GPRMC,123531.000,A,5356.21494,N,02734.86327,E,00.00,252.7,290508,,,A*68 +$PORZD,A,017.0*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123531.000,5356.21498,N,02734.86346,E,1,06,04.9,254.2,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064531.000,"ept":0.005,"lat":53.936916333,"lon":27.581057667,"alt":254.200,"epx":11.725,"epy":28.790,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.58,"mode":3} +$GPRMC,123532.000,A,5356.21496,N,02734.86347,E,00.00,252.7,290508,,,A*6F +$PORZD,A,016.6*3D +$GPGSV,3,1,12,02,12,247,,03,11,065,,07,76,086,36,13,48,101,51*7F +$GPGSV,3,2,12,23,12,106,45,25,55,069,38,27,83,107,29,28,05,181,44*78 +$GPGSV,3,3,12,33,17,229,,37,28,187,,39,28,183,,44,20,137,*78 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":1.80,"vdop":1.27,"tdop":0.86,"hdop":1.96,"gdop":2.49,"pdop":2.34,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":7,"el":76,"az":86,"ss":36,"used":true},{"PRN":13,"el":48,"az":101,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":107,"ss":29,"used":true},{"PRN":28,"el":5,"az":181,"ss":44,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123532.000,5356.21499,N,02734.86359,E,1,06,04.9,254.2,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064532.000,"ept":0.005,"lat":53.936916500,"lon":27.581059833,"alt":254.200,"epx":11.725,"epy":28.790,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":57.58,"mode":3} +$GPRMC,123533.000,A,5356.21497,N,02734.86358,E,00.00,252.7,290508,,,A*61 +$PORZD,A,016.5*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123533.000,5356.21499,N,02734.86368,E,1,06,04.9,254.2,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064533.000,"ept":0.005,"lat":53.936916500,"lon":27.581061333,"alt":254.200,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":55.84,"mode":3} +$GPRMC,123534.000,A,5356.21497,N,02734.86369,E,00.00,252.7,290508,,,A*64 +$PORZD,A,016.5*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123534.000,5356.21499,N,02734.86376,E,1,06,04.9,254.2,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064534.000,"ept":0.005,"lat":53.936916500,"lon":27.581062667,"alt":254.200,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123535.000,A,5356.21497,N,02734.86375,E,00.00,252.7,290508,,,A*68 +$PORZD,A,016.4*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123535.000,5356.21499,N,02734.86381,E,1,06,04.9,254.2,M,26.0,M,,*65 +{"class":"TPV","tag":"GGA","time":1212064535.000,"ept":0.005,"lat":53.936916500,"lon":27.581063500,"alt":254.200,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123536.000,A,5356.21495,N,02734.86381,E,00.00,252.7,290508,,,A*62 +$PORZD,A,016.3*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123536.000,5356.21498,N,02734.86385,E,1,06,04.9,254.3,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064536.000,"ept":0.005,"lat":53.936916333,"lon":27.581064167,"alt":254.300,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123537.000,A,5356.21496,N,02734.86386,E,00.00,252.7,290508,,,A*67 +$PORZD,A,016.3*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123537.000,5356.21498,N,02734.86387,E,1,06,04.9,254.3,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064537.000,"ept":0.005,"lat":53.936916333,"lon":27.581064500,"alt":254.300,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123538.000,A,5356.21497,N,02734.86386,E,00.00,252.7,290508,,,A*69 +$PORZD,A,016.2*39 +$GPGSV,3,1,12,02,12,247,,03,11,065,,07,76,086,36,13,48,101,50*7E +$GPGSV,3,2,12,23,12,106,46,25,55,069,38,27,83,107,29,28,05,181,45*7A +$GPGSV,3,3,12,33,17,229,,37,28,187,,39,28,183,,44,20,137,*78 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":1.80,"vdop":1.27,"tdop":0.86,"hdop":1.96,"gdop":2.49,"pdop":2.34,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":7,"el":76,"az":86,"ss":36,"used":true},{"PRN":13,"el":48,"az":101,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":107,"ss":29,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123538.000,5356.21499,N,02734.86387,E,1,06,04.9,254.3,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064538.000,"ept":0.005,"lat":53.936916500,"lon":27.581064500,"alt":254.300,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123539.000,A,5356.21496,N,02734.86387,E,00.00,252.7,290508,,,A*68 +$PORZD,A,016.2*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123539.000,5356.21499,N,02734.86387,E,1,06,04.9,254.3,M,26.0,M,,*6E +{"class":"TPV","tag":"GGA","time":1212064539.000,"ept":0.005,"lat":53.936916500,"lon":27.581064500,"alt":254.300,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123540.000,A,5356.21497,N,02734.86387,E,00.00,252.7,290508,,,A*67 +$PORZD,A,016.1*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123540.000,5356.21500,N,02734.86385,E,1,06,04.9,254.3,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064540.000,"ept":0.005,"lat":53.936916667,"lon":27.581064167,"alt":254.300,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123541.000,A,5356.21498,N,02734.86385,E,00.00,252.7,290508,,,A*6B +$PORZD,A,016.1*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123541.000,5356.21499,N,02734.86371,E,1,06,04.9,254.4,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064541.000,"ept":0.005,"lat":53.936916500,"lon":27.581061833,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123542.000,A,5356.21496,N,02734.86371,E,00.00,252.7,290508,,,A*6D +$PORZD,A,016.3*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123542.000,5356.21499,N,02734.86359,E,1,06,04.9,254.4,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064542.000,"ept":0.005,"lat":53.936916500,"lon":27.581059833,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123543.000,A,5356.21495,N,02734.86360,E,00.00,252.7,290508,,,A*6F +$PORZD,A,016.2*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.4,04.9,04.1*04 +$GPGGA,123543.000,5356.21499,N,02734.86349,E,1,06,04.9,254.4,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064543.000,"ept":0.005,"lat":53.936916500,"lon":27.581058167,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123544.000,A,5356.21498,N,02734.86347,E,00.00,252.7,290508,,,A*60 +$PORZD,A,016.2*39 +$GPGSV,3,1,12,02,12,247,,03,11,065,,07,76,086,35,13,48,101,50*7D +$GPGSV,3,2,12,23,12,106,46,25,55,069,38,27,83,107,29,28,05,181,45*7A +$GPGSV,3,3,12,33,17,229,,37,28,187,,39,28,183,,44,20,137,*78 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":1.80,"vdop":1.27,"tdop":0.86,"hdop":1.96,"gdop":2.49,"pdop":2.34,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":7,"el":76,"az":86,"ss":35,"used":true},{"PRN":13,"el":48,"az":101,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":107,"ss":29,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.9,04.1*03 +$GPGGA,123544.000,5356.21501,N,02734.86338,E,1,06,04.9,254.4,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064544.000,"ept":0.005,"lat":53.936916833,"lon":27.581056333,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123545.000,A,5356.21498,N,02734.86336,E,00.00,252.7,290508,,,A*67 +$PORZD,A,016.1*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.9,04.1*03 +$GPGGA,123545.000,5356.21502,N,02734.86328,E,1,06,04.8,254.4,M,26.0,M,,*65 +{"class":"TPV","tag":"GGA","time":1212064545.000,"ept":0.005,"lat":53.936917000,"lon":27.581054667,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123546.000,A,5356.21499,N,02734.86329,E,00.00,252.7,290508,,,A*6B +$PORZD,A,016.1*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123546.000,5356.21502,N,02734.86322,E,1,06,04.8,254.4,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064546.000,"ept":0.005,"lat":53.936917000,"lon":27.581053667,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123547.000,A,5356.21499,N,02734.86322,E,00.00,252.7,290508,,,A*61 +$PORZD,A,016.1*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123547.000,5356.21503,N,02734.86315,E,1,06,04.8,254.3,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064547.000,"ept":0.005,"lat":53.936917167,"lon":27.581052500,"alt":254.300,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123548.000,A,5356.21500,N,02734.86314,E,00.00,252.7,290508,,,A*6A +$PORZD,A,016.0*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123548.000,5356.21502,N,02734.86310,E,1,06,04.8,254.4,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064548.000,"ept":0.005,"lat":53.936917000,"lon":27.581051667,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123549.000,A,5356.21498,N,02734.86310,E,00.00,252.7,290508,,,A*6F +$PORZD,A,016.0*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123549.000,5356.21503,N,02734.86304,E,1,06,04.8,254.4,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064549.000,"ept":0.005,"lat":53.936917167,"lon":27.581050667,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123550.000,A,5356.21500,N,02734.86304,E,00.00,252.7,290508,,,A*62 +$PORZD,A,016.0*3B +$GPGSV,3,1,12,02,12,247,,03,11,065,,07,76,086,35,13,48,101,50*7D +$GPGSV,3,2,12,23,12,106,46,25,55,069,38,27,83,107,28,28,05,181,45*7B +$GPGSV,3,3,12,33,17,229,,37,28,187,,39,28,183,,44,20,137,*78 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":1.80,"vdop":1.27,"tdop":0.86,"hdop":1.96,"gdop":2.49,"pdop":2.34,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":7,"el":76,"az":86,"ss":35,"used":true},{"PRN":13,"el":48,"az":101,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":107,"ss":28,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123550.000,5356.21503,N,02734.86299,E,1,06,04.8,254.4,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064550.000,"ept":0.005,"lat":53.936917167,"lon":27.581049833,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123551.000,A,5356.21500,N,02734.86299,E,00.00,252.7,290508,,,A*66 +$PORZD,A,016.0*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123551.000,5356.21504,N,02734.86294,E,1,06,04.8,254.3,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064551.000,"ept":0.005,"lat":53.936917333,"lon":27.581049000,"alt":254.300,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123552.000,A,5356.21501,N,02734.86294,E,00.00,252.7,290508,,,A*69 +$PORZD,A,016.0*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123552.000,5356.21504,N,02734.86291,E,1,06,04.8,254.4,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064552.000,"ept":0.005,"lat":53.936917333,"lon":27.581048500,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123553.000,A,5356.21500,N,02734.86291,E,00.00,252.7,290508,,,A*6C +$PORZD,A,016.0*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123553.000,5356.21505,N,02734.86296,E,1,06,04.8,254.4,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064553.000,"ept":0.005,"lat":53.936917500,"lon":27.581049333,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123554.000,A,5356.21503,N,02734.86296,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.9*31 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123554.000,5356.21506,N,02734.86301,E,1,06,04.8,254.4,M,26.0,M,,*6A +{"class":"TPV","tag":"GGA","time":1212064554.000,"ept":0.005,"lat":53.936917667,"lon":27.581050167,"alt":254.400,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123555.000,A,5356.21504,N,02734.86300,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.9*31 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123555.000,5356.21507,N,02734.86304,E,1,06,04.8,254.5,M,26.0,M,,*6E +{"class":"TPV","tag":"GGA","time":1212064555.000,"ept":0.005,"lat":53.936917833,"lon":27.581050667,"alt":254.500,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123556.000,A,5356.21504,N,02734.86303,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.9*31 +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,086,36*75 +$GPGSV,4,2,13,13,47,102,50,23,12,106,46,25,55,069,38,27,83,105,30*77 +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +{"class":"SKY","tag":"GSV","xdop":0.74,"ydop":1.26,"vdop":1.33,"tdop":0.73,"hdop":1.47,"gdop":2.11,"pdop":1.98,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":76,"az":86,"ss":36,"used":true},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":105,"ss":30,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123556.000,5356.21507,N,02734.86306,E,1,06,04.8,254.5,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064556.000,"ept":0.005,"lat":53.936917833,"lon":27.581051000,"alt":254.500,"epx":11.633,"epy":27.049,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":54.10,"mode":3} +$GPRMC,123557.000,A,5356.21505,N,02734.86306,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.9*31 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123557.000,5356.21508,N,02734.86307,E,1,06,04.8,254.5,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064557.000,"ept":0.005,"lat":53.936918000,"lon":27.581051167,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":45.99,"mode":3} +$GPRMC,123558.000,A,5356.21505,N,02734.86306,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123558.000,5356.21508,N,02734.86308,E,1,06,04.8,254.5,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064558.000,"ept":0.005,"lat":53.936918000,"lon":27.581051333,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123559.000,A,5356.21505,N,02734.86309,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123559.000,5356.21508,N,02734.86309,E,1,06,04.8,254.5,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064559.000,"ept":0.005,"lat":53.936918000,"lon":27.581051500,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123600.000,A,5356.21505,N,02734.86309,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123600.000,5356.21508,N,02734.86309,E,1,06,04.8,254.5,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064560.000,"ept":0.005,"lat":53.936918000,"lon":27.581051500,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123601.000,A,5356.21506,N,02734.86309,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123601.000,5356.21509,N,02734.86307,E,1,06,04.8,254.5,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064561.000,"ept":0.005,"lat":53.936918167,"lon":27.581051167,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123602.000,A,5356.21506,N,02734.86307,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.8*30 +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,086,34*77 +$GPGSV,4,2,13,13,47,102,51,23,12,106,45,25,55,069,38,27,83,105,30*75 +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +{"class":"SKY","tag":"GSV","xdop":0.74,"ydop":1.26,"vdop":1.33,"tdop":0.73,"hdop":1.47,"gdop":2.11,"pdop":1.98,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":76,"az":86,"ss":34,"used":true},{"PRN":13,"el":47,"az":102,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":105,"ss":30,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123602.000,5356.21508,N,02734.86308,E,1,06,04.8,254.5,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064562.000,"ept":0.005,"lat":53.936918000,"lon":27.581051333,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123603.000,A,5356.21503,N,02734.86309,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123603.000,5356.21507,N,02734.86308,E,1,06,04.8,254.6,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064563.000,"ept":0.005,"lat":53.936917833,"lon":27.581051333,"alt":254.600,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123604.000,A,5356.21504,N,02734.86308,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.1*02 +$GPGGA,123604.000,5356.21508,N,02734.86306,E,1,06,04.8,254.5,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064564.000,"ept":0.005,"lat":53.936918000,"lon":27.581051000,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123605.000,A,5356.21506,N,02734.86306,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123605.000,5356.21508,N,02734.86304,E,1,06,04.8,254.5,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064565.000,"ept":0.005,"lat":53.936918000,"lon":27.581050667,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123606.000,A,5356.21505,N,02734.86304,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123606.000,5356.21509,N,02734.86302,E,1,06,04.8,254.5,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064566.000,"ept":0.005,"lat":53.936918167,"lon":27.581050333,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123607.000,A,5356.21506,N,02734.86302,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123607.000,5356.21508,N,02734.86301,E,1,06,04.8,254.5,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064567.000,"ept":0.005,"lat":53.936918000,"lon":27.581050167,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123608.000,A,5356.21504,N,02734.86302,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.8*30 +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,086,34*77 +$GPGSV,4,2,13,13,47,102,51,23,12,106,45,25,55,069,38,27,83,105,30*75 +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +{"class":"SKY","tag":"GSV","xdop":0.74,"ydop":1.26,"vdop":1.33,"tdop":0.73,"hdop":1.47,"gdop":2.11,"pdop":1.98,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":76,"az":86,"ss":34,"used":true},{"PRN":13,"el":47,"az":102,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":105,"ss":30,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123608.000,5356.21508,N,02734.86299,E,1,06,04.8,254.5,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064568.000,"ept":0.005,"lat":53.936918000,"lon":27.581049833,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123609.000,A,5356.21507,N,02734.86299,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123609.000,5356.21510,N,02734.86297,E,1,06,04.8,254.5,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064569.000,"ept":0.005,"lat":53.936918333,"lon":27.581049500,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123610.000,A,5356.21507,N,02734.86298,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123610.000,5356.21512,N,02734.86295,E,1,06,04.8,254.5,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064570.000,"ept":0.005,"lat":53.936918667,"lon":27.581049167,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123611.000,A,5356.21510,N,02734.86295,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.8*30 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123611.000,5356.21512,N,02734.86293,E,1,06,04.8,254.4,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064571.000,"ept":0.005,"lat":53.936918667,"lon":27.581048833,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123612.000,A,5356.21508,N,02734.86295,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123612.000,5356.21512,N,02734.86291,E,1,06,04.8,254.4,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064572.000,"ept":0.005,"lat":53.936918667,"lon":27.581048500,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123613.000,A,5356.21510,N,02734.86290,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123613.000,5356.21514,N,02734.86287,E,1,06,04.8,254.4,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064573.000,"ept":0.005,"lat":53.936919000,"lon":27.581047833,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123614.000,A,5356.21512,N,02734.86287,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.7*3F +$GPGSV,4,1,13,02,12,247,20,03,11,065,,06,10,045,,07,76,086,34*75 +$GPGSV,4,2,13,13,47,102,51,23,12,106,46,25,55,069,38,27,83,105,29*7E +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +{"class":"SKY","tag":"GSV","xdop":0.74,"ydop":1.26,"vdop":1.33,"tdop":0.73,"hdop":1.47,"gdop":2.11,"pdop":1.98,"satellites":[{"PRN":2,"el":12,"az":247,"ss":20,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":76,"az":86,"ss":34,"used":true},{"PRN":13,"el":47,"az":102,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":105,"ss":29,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123614.000,5356.21515,N,02734.86283,E,1,06,04.8,254.4,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064574.000,"ept":0.005,"lat":53.936919167,"lon":27.581047167,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123615.000,A,5356.21512,N,02734.86284,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123615.000,5356.21516,N,02734.86281,E,1,06,04.8,254.4,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064575.000,"ept":0.005,"lat":53.936919333,"lon":27.581046833,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123616.000,A,5356.21513,N,02734.86280,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123616.000,5356.21517,N,02734.86276,E,1,06,04.8,254.4,M,26.0,M,,*6E +{"class":"TPV","tag":"GGA","time":1212064576.000,"ept":0.005,"lat":53.936919500,"lon":27.581046000,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123617.000,A,5356.21515,N,02734.86276,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123617.000,5356.21518,N,02734.86271,E,1,06,04.8,254.4,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064577.000,"ept":0.005,"lat":53.936919667,"lon":27.581045167,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123618.000,A,5356.21515,N,02734.86272,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123618.000,5356.21519,N,02734.86266,E,1,06,04.8,254.4,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064578.000,"ept":0.005,"lat":53.936919833,"lon":27.581044333,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123619.000,A,5356.21516,N,02734.86267,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123619.000,5356.21520,N,02734.86260,E,1,06,04.8,254.4,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064579.000,"ept":0.005,"lat":53.936920000,"lon":27.581043333,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123620.000,A,5356.21518,N,02734.86259,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.7*3F +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,086,34*77 +$GPGSV,4,2,13,13,47,102,50,23,12,106,45,25,55,069,38,27,83,105,29*7C +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +{"class":"SKY","tag":"GSV","xdop":0.74,"ydop":1.26,"vdop":1.33,"tdop":0.73,"hdop":1.47,"gdop":2.11,"pdop":1.98,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":76,"az":86,"ss":34,"used":true},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":105,"ss":29,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123620.000,5356.21521,N,02734.86254,E,1,06,04.8,254.4,M,26.0,M,,*6E +{"class":"TPV","tag":"GGA","time":1212064580.000,"ept":0.005,"lat":53.936920167,"lon":27.581042333,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123621.000,A,5356.21519,N,02734.86254,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123621.000,5356.21523,N,02734.86248,E,1,06,04.8,254.4,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064581.000,"ept":0.005,"lat":53.936920500,"lon":27.581041333,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123622.000,A,5356.21520,N,02734.86249,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123622.000,5356.21523,N,02734.86244,E,1,06,04.8,254.4,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064582.000,"ept":0.005,"lat":53.936920500,"lon":27.581040667,"alt":254.400,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123623.000,A,5356.21521,N,02734.86244,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.7*3F +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123623.000,5356.21525,N,02734.86241,E,1,06,04.8,254.5,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064583.000,"ept":0.005,"lat":53.936920833,"lon":27.581040167,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123624.000,A,5356.21522,N,02734.86242,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123624.000,5356.21526,N,02734.86245,E,1,06,04.8,254.5,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064584.000,"ept":0.005,"lat":53.936921000,"lon":27.581040833,"alt":254.500,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123625.000,A,5356.21523,N,02734.86246,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123625.000,5356.21527,N,02734.86242,E,1,06,04.8,254.6,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064585.000,"ept":0.005,"lat":53.936921167,"lon":27.581040333,"alt":254.600,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123626.000,A,5356.21526,N,02734.86241,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.6*3E +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,085,35*75 +$GPGSV,4,2,13,13,47,102,50,23,12,106,45,25,55,069,38,27,83,104,30*75 +$GPGSV,4,3,13,28,05,181,46,33,17,229,,37,28,187,,39,28,183,*7C +$GPGSV,4,4,13,44,20,137,*4C +{"class":"SKY","tag":"GSV","xdop":0.74,"ydop":1.26,"vdop":1.33,"tdop":0.73,"hdop":1.46,"gdop":2.11,"pdop":1.98,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":76,"az":85,"ss":35,"used":true},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":104,"ss":30,"used":true},{"PRN":28,"el":5,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123626.000,5356.21529,N,02734.86243,E,1,06,04.8,254.6,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064586.000,"ept":0.005,"lat":53.936921500,"lon":27.581040500,"alt":254.600,"epx":11.161,"epy":18.939,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.88,"mode":3} +$GPRMC,123627.000,A,5356.21526,N,02734.86243,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123627.000,5356.21529,N,02734.86247,E,1,06,04.8,254.6,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064587.000,"ept":0.005,"lat":53.936921500,"lon":27.581041167,"alt":254.600,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.86,"mode":3} +$GPRMC,123628.000,A,5356.21525,N,02734.86250,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123628.000,5356.21526,N,02734.86245,E,1,06,04.8,254.7,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064588.000,"ept":0.005,"lat":53.936921000,"lon":27.581040833,"alt":254.700,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123629.000,A,5356.21524,N,02734.86244,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123629.000,5356.21527,N,02734.86247,E,1,06,04.8,254.7,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064589.000,"ept":0.005,"lat":53.936921167,"lon":27.581041167,"alt":254.700,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123630.000,A,5356.21524,N,02734.86249,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.6*3E +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123630.000,5356.21525,N,02734.86244,E,1,06,04.8,254.8,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064590.000,"ept":0.005,"lat":53.936920833,"lon":27.581040667,"alt":254.800,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123631.000,A,5356.21522,N,02734.86244,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123631.000,5356.21524,N,02734.86240,E,1,06,04.8,254.8,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064591.000,"ept":0.005,"lat":53.936920667,"lon":27.581040000,"alt":254.800,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123632.000,A,5356.21521,N,02734.86240,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.5*3D +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,085,34*74 +$GPGSV,4,2,13,13,47,102,51,23,12,106,46,25,55,069,39,27,83,104,31*77 +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +{"class":"SKY","tag":"GSV","xdop":0.74,"ydop":1.26,"vdop":1.33,"tdop":0.73,"hdop":1.46,"gdop":2.11,"pdop":1.98,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":76,"az":85,"ss":34,"used":true},{"PRN":13,"el":47,"az":102,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":55,"az":69,"ss":39,"used":true},{"PRN":27,"el":83,"az":104,"ss":31,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123632.000,5356.21522,N,02734.86236,E,1,06,04.8,254.8,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064592.000,"ept":0.005,"lat":53.936920333,"lon":27.581039333,"alt":254.800,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123633.000,A,5356.21519,N,02734.86238,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123633.000,5356.21519,N,02734.86234,E,1,06,04.8,254.9,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064593.000,"ept":0.005,"lat":53.936919833,"lon":27.581039000,"alt":254.900,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123634.000,A,5356.21517,N,02734.86234,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123634.000,5356.21516,N,02734.86231,E,1,06,04.8,255.0,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064594.000,"ept":0.005,"lat":53.936919333,"lon":27.581038500,"alt":255.000,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123635.000,A,5356.21512,N,02734.86232,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123635.000,5356.21513,N,02734.86229,E,1,06,04.8,255.0,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064595.000,"ept":0.005,"lat":53.936918833,"lon":27.581038167,"alt":255.000,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123636.000,A,5356.21510,N,02734.86229,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123636.000,5356.21511,N,02734.86226,E,1,06,04.8,255.1,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064596.000,"ept":0.005,"lat":53.936918500,"lon":27.581037667,"alt":255.100,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123637.000,A,5356.21508,N,02734.86227,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123637.000,5356.21509,N,02734.86224,E,1,06,04.8,255.1,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064597.000,"ept":0.005,"lat":53.936918167,"lon":27.581037333,"alt":255.100,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123638.000,A,5356.21507,N,02734.86225,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.5*3D +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,085,35*75 +$GPGSV,4,2,13,13,47,102,50,23,12,106,46,25,55,069,38,27,83,104,31*77 +$GPGSV,4,3,13,28,05,181,46,33,17,229,,37,28,187,,39,28,183,*7C +$GPGSV,4,4,13,44,20,137,*4C +{"class":"SKY","tag":"GSV","xdop":0.74,"ydop":1.26,"vdop":1.33,"tdop":0.73,"hdop":1.46,"gdop":2.11,"pdop":1.98,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":76,"az":85,"ss":35,"used":true},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":55,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":104,"ss":31,"used":true},{"PRN":28,"el":5,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123638.000,5356.21507,N,02734.86222,E,1,06,04.8,255.1,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064598.000,"ept":0.005,"lat":53.936917833,"lon":27.581037000,"alt":255.100,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123639.000,A,5356.21504,N,02734.86223,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123639.000,5356.21505,N,02734.86221,E,1,06,04.8,255.2,M,26.0,M,,*65 +{"class":"TPV","tag":"GGA","time":1212064599.000,"ept":0.005,"lat":53.936917500,"lon":27.581036833,"alt":255.200,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123640.000,A,5356.21502,N,02734.86221,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.5*3D +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123640.000,5356.21504,N,02734.86219,E,1,06,04.8,255.2,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064600.000,"ept":0.005,"lat":53.936917333,"lon":27.581036500,"alt":255.200,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123641.000,A,5356.21501,N,02734.86220,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123641.000,5356.21503,N,02734.86218,E,1,06,04.8,255.2,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064601.000,"ept":0.005,"lat":53.936917167,"lon":27.581036333,"alt":255.200,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123642.000,A,5356.21500,N,02734.86219,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123642.000,5356.21502,N,02734.86217,E,1,06,04.8,255.2,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064602.000,"ept":0.005,"lat":53.936917000,"lon":27.581036167,"alt":255.200,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123643.000,A,5356.21499,N,02734.86217,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123643.000,5356.21501,N,02734.86216,E,1,06,04.8,255.3,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064603.000,"ept":0.005,"lat":53.936916833,"lon":27.581036000,"alt":255.300,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123644.000,A,5356.21498,N,02734.86216,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.4*3C +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,085,35*75 +$GPGSV,4,2,13,13,47,102,51,23,12,106,46,25,55,069,37,27,83,104,32*7A +$GPGSV,4,3,13,28,05,181,46,33,17,229,,37,28,187,,39,28,183,*7C +$GPGSV,4,4,13,44,20,137,*4C +{"class":"SKY","tag":"GSV","xdop":0.74,"ydop":1.26,"vdop":1.33,"tdop":0.73,"hdop":1.46,"gdop":2.11,"pdop":1.98,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":76,"az":85,"ss":35,"used":true},{"PRN":13,"el":47,"az":102,"ss":51,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":55,"az":69,"ss":37,"used":true},{"PRN":27,"el":83,"az":104,"ss":32,"used":true},{"PRN":28,"el":5,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123644.000,5356.21502,N,02734.86215,E,1,06,04.8,255.2,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064604.000,"ept":0.005,"lat":53.936917000,"lon":27.581035833,"alt":255.200,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123645.000,A,5356.21500,N,02734.86213,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123645.000,5356.21503,N,02734.86213,E,1,06,04.8,255.2,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064605.000,"ept":0.005,"lat":53.936917167,"lon":27.581035500,"alt":255.200,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123646.000,A,5356.21500,N,02734.86214,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123646.000,5356.21503,N,02734.86212,E,1,06,04.8,255.2,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064606.000,"ept":0.005,"lat":53.936917167,"lon":27.581035333,"alt":255.200,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123647.000,A,5356.21501,N,02734.86213,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123647.000,5356.21504,N,02734.86212,E,1,06,04.8,255.2,M,26.0,M,,*6D +{"class":"TPV","tag":"GGA","time":1212064607.000,"ept":0.005,"lat":53.936917333,"lon":27.581035333,"alt":255.200,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123648.000,A,5356.21501,N,02734.86212,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123648.000,5356.21505,N,02734.86212,E,1,06,04.8,255.1,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064608.000,"ept":0.005,"lat":53.936917500,"lon":27.581035333,"alt":255.100,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123649.000,A,5356.21503,N,02734.86212,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123649.000,5356.21505,N,02734.86212,E,1,06,04.8,255.1,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064609.000,"ept":0.005,"lat":53.936917500,"lon":27.581035333,"alt":255.100,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123650.000,A,5356.21502,N,02734.86214,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.4*3C +$GPGSV,4,1,13,02,12,247,,03,11,065,,06,10,045,,07,76,085,35*75 +$GPGSV,4,2,13,13,47,102,50,23,12,106,45,25,55,069,37,27,83,104,31*7B +$GPGSV,4,3,13,28,05,181,45,33,17,229,,37,28,187,,39,28,183,*7F +$GPGSV,4,4,13,44,20,137,*4C +{"class":"SKY","tag":"GSV","xdop":0.74,"ydop":1.26,"vdop":1.33,"tdop":0.73,"hdop":1.46,"gdop":2.11,"pdop":1.98,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":76,"az":85,"ss":35,"used":true},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":55,"az":69,"ss":37,"used":true},{"PRN":27,"el":83,"az":104,"ss":31,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123650.000,5356.21505,N,02734.86213,E,1,06,04.8,255.1,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064610.000,"ept":0.005,"lat":53.936917500,"lon":27.581035500,"alt":255.100,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123651.000,A,5356.21503,N,02734.86213,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123651.000,5356.21507,N,02734.86211,E,1,06,04.8,255.1,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064611.000,"ept":0.005,"lat":53.936917833,"lon":27.581035167,"alt":255.100,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123652.000,A,5356.21504,N,02734.86211,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123652.000,5356.21508,N,02734.86209,E,1,06,04.8,255.0,M,26.0,M,,*6D +{"class":"TPV","tag":"GGA","time":1212064612.000,"ept":0.005,"lat":53.936918000,"lon":27.581034833,"alt":255.000,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123653.000,A,5356.21506,N,02734.86208,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123653.000,5356.21511,N,02734.86215,E,1,06,04.8,255.0,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064613.000,"ept":0.005,"lat":53.936918500,"lon":27.581035833,"alt":255.000,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123654.000,A,5356.21508,N,02734.86216,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123654.000,5356.21514,N,02734.86221,E,1,06,04.8,255.1,M,26.0,M,,*6D +{"class":"TPV","tag":"GGA","time":1212064614.000,"ept":0.005,"lat":53.936919000,"lon":27.581036833,"alt":255.100,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123655.000,A,5356.21510,N,02734.86222,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123655.000,5356.21516,N,02734.86225,E,1,06,04.8,255.1,M,26.0,M,,*6A +{"class":"TPV","tag":"GGA","time":1212064615.000,"ept":0.005,"lat":53.936919333,"lon":27.581037500,"alt":255.100,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123656.000,A,5356.21514,N,02734.86225,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.3*3B +$GPGSV,4,1,14,02,12,247,,03,11,065,,06,10,045,,07,75,084,35*70 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,12,106,47,25,54,069,37*76 +$GPGSV,4,3,14,27,83,102,32,28,05,181,45,33,17,229,,37,28,187,*7E +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":2.24,"vdop":1.66,"tdop":0.91,"hdop":2.54,"gdop":3.17,"pdop":3.04,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":75,"az":84,"ss":35,"used":true},{"PRN":8,"el":59,"az":224,"ss":0,"used":false},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":47,"used":true},{"PRN":25,"el":54,"az":69,"ss":37,"used":true},{"PRN":27,"el":83,"az":102,"ss":32,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.3,04.8,04.0*03 +$GPGGA,123656.000,5356.21518,N,02734.86229,E,1,06,04.8,255.1,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064616.000,"ept":0.005,"lat":53.936919667,"lon":27.581038167,"alt":255.100,"epx":11.155,"epy":18.919,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":37.84,"mode":3} +$GPRMC,123657.000,A,5356.21515,N,02734.86230,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123657.000,5356.21519,N,02734.86231,E,1,06,04.8,255.1,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064617.000,"ept":0.005,"lat":53.936919833,"lon":27.581038500,"alt":255.100,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":52.45,"mode":3} +$GPRMC,123658.000,A,5356.21517,N,02734.86231,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123658.000,5356.21521,N,02734.86233,E,1,06,04.8,255.1,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064618.000,"ept":0.005,"lat":53.936920167,"lon":27.581038833,"alt":255.100,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123659.000,A,5356.21519,N,02734.86233,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123659.000,5356.21524,N,02734.86232,E,1,06,04.8,255.1,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064619.000,"ept":0.005,"lat":53.936920667,"lon":27.581038667,"alt":255.100,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123700.000,A,5356.21522,N,02734.86232,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123700.000,5356.21526,N,02734.86232,E,1,06,04.8,255.0,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064620.000,"ept":0.005,"lat":53.936921000,"lon":27.581038667,"alt":255.000,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123701.000,A,5356.21522,N,02734.86233,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123701.000,5356.21526,N,02734.86232,E,1,06,04.8,255.1,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064621.000,"ept":0.005,"lat":53.936921000,"lon":27.581038667,"alt":255.100,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123702.000,A,5356.21524,N,02734.86232,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.3*3B +$GPGSV,4,1,14,02,12,247,,03,11,065,,06,10,045,,07,75,084,34*71 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,12,106,46,25,54,069,38*78 +$GPGSV,4,3,14,27,83,102,31,28,05,181,45,33,17,229,,37,28,187,*7D +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":2.24,"vdop":1.66,"tdop":0.91,"hdop":2.54,"gdop":3.17,"pdop":3.04,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":75,"az":84,"ss":34,"used":true},{"PRN":8,"el":59,"az":224,"ss":0,"used":false},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":54,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":102,"ss":31,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123702.000,5356.21528,N,02734.86231,E,1,06,04.8,255.0,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064622.000,"ept":0.005,"lat":53.936921333,"lon":27.581038500,"alt":255.000,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123703.000,A,5356.21526,N,02734.86231,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123703.000,5356.21529,N,02734.86230,E,1,06,04.8,255.0,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064623.000,"ept":0.005,"lat":53.936921500,"lon":27.581038333,"alt":255.000,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123704.000,A,5356.21526,N,02734.86230,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123704.000,5356.21530,N,02734.86228,E,1,06,04.8,255.0,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064624.000,"ept":0.005,"lat":53.936921667,"lon":27.581038000,"alt":255.000,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123705.000,A,5356.21528,N,02734.86228,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123705.000,5356.21533,N,02734.86226,E,1,06,04.8,255.0,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064625.000,"ept":0.005,"lat":53.936922167,"lon":27.581037667,"alt":255.000,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123706.000,A,5356.21530,N,02734.86226,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123706.000,5356.21534,N,02734.86224,E,1,06,04.8,255.0,M,26.0,M,,*6D +{"class":"TPV","tag":"GGA","time":1212064626.000,"ept":0.005,"lat":53.936922333,"lon":27.581037333,"alt":255.000,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123707.000,A,5356.21531,N,02734.86225,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.8,04.0*02 +$GPGGA,123707.000,5356.21536,N,02734.86223,E,1,06,04.7,254.9,M,26.0,M,,*6E +{"class":"TPV","tag":"GGA","time":1212064627.000,"ept":0.005,"lat":53.936922667,"lon":27.581037167,"alt":254.900,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123708.000,A,5356.21534,N,02734.86222,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.2*3A +$GPGSV,4,1,14,02,12,247,,03,11,065,,06,10,045,,07,75,084,36*73 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,12,106,45,25,54,069,38*7B +$GPGSV,4,3,14,27,83,102,31,28,05,181,46,33,17,229,,37,28,187,*7E +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":2.24,"vdop":1.66,"tdop":0.91,"hdop":2.54,"gdop":3.17,"pdop":3.04,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":75,"az":84,"ss":36,"used":true},{"PRN":8,"el":59,"az":224,"ss":0,"used":false},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":45,"used":true},{"PRN":25,"el":54,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":102,"ss":31,"used":true},{"PRN":28,"el":5,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123708.000,5356.21539,N,02734.86220,E,1,06,04.7,254.9,M,26.0,M,,*6D +{"class":"TPV","tag":"GGA","time":1212064628.000,"ept":0.005,"lat":53.936923167,"lon":27.581036667,"alt":254.900,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123709.000,A,5356.21536,N,02734.86219,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123709.000,5356.21541,N,02734.86218,E,1,06,04.7,254.8,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064629.000,"ept":0.005,"lat":53.936923500,"lon":27.581036333,"alt":254.800,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123710.000,A,5356.21538,N,02734.86220,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123710.000,5356.21542,N,02734.86219,E,1,06,04.7,254.8,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064630.000,"ept":0.005,"lat":53.936923667,"lon":27.581036500,"alt":254.800,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123711.000,A,5356.21539,N,02734.86219,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123711.000,5356.21543,N,02734.86218,E,1,06,04.7,254.8,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064631.000,"ept":0.005,"lat":53.936923833,"lon":27.581036333,"alt":254.800,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123712.000,A,5356.21541,N,02734.86218,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123712.000,5356.21544,N,02734.86218,E,1,06,04.7,254.7,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064632.000,"ept":0.005,"lat":53.936924000,"lon":27.581036333,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123713.000,A,5356.21541,N,02734.86219,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123713.000,5356.21544,N,02734.86218,E,1,06,04.7,254.7,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064633.000,"ept":0.005,"lat":53.936924000,"lon":27.581036333,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123714.000,A,5356.21541,N,02734.86219,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.2*3A +$GPGSV,4,1,14,02,12,247,,03,11,065,,06,10,045,,07,75,084,35*70 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,12,106,46,25,54,069,38*78 +$GPGSV,4,3,14,27,83,102,31,28,05,181,45,33,17,229,,37,28,187,*7D +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":2.24,"vdop":1.66,"tdop":0.91,"hdop":2.54,"gdop":3.17,"pdop":3.04,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":75,"az":84,"ss":35,"used":true},{"PRN":8,"el":59,"az":224,"ss":0,"used":false},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":54,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":102,"ss":31,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123714.000,5356.21544,N,02734.86217,E,1,06,04.7,254.7,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064634.000,"ept":0.005,"lat":53.936924000,"lon":27.581036167,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123715.000,A,5356.21542,N,02734.86218,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123715.000,5356.21544,N,02734.86216,E,1,06,04.7,254.7,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064635.000,"ept":0.005,"lat":53.936924000,"lon":27.581036000,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123716.000,A,5356.21542,N,02734.86216,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123716.000,5356.21544,N,02734.86215,E,1,06,04.7,254.7,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064636.000,"ept":0.005,"lat":53.936924000,"lon":27.581035833,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123717.000,A,5356.21542,N,02734.86215,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123717.000,5356.21543,N,02734.86213,E,1,06,04.7,254.7,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064637.000,"ept":0.005,"lat":53.936923833,"lon":27.581035500,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123718.000,A,5356.21540,N,02734.86214,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123718.000,5356.21542,N,02734.86211,E,1,06,04.7,254.7,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064638.000,"ept":0.005,"lat":53.936923667,"lon":27.581035167,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123719.000,A,5356.21540,N,02734.86211,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123719.000,5356.21542,N,02734.86209,E,1,06,04.7,254.7,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064639.000,"ept":0.005,"lat":53.936923667,"lon":27.581034833,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123720.000,A,5356.21539,N,02734.86210,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.2*3A +$GPGSV,4,1,14,02,12,247,,03,11,065,,06,10,045,,07,75,084,34*71 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,12,106,46,25,54,069,38*78 +$GPGSV,4,3,14,27,83,102,31,28,05,181,46,33,17,229,,37,28,187,*7E +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":2.24,"vdop":1.66,"tdop":0.91,"hdop":2.54,"gdop":3.17,"pdop":3.04,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":65,"ss":0,"used":false},{"PRN":6,"el":10,"az":45,"ss":0,"used":false},{"PRN":7,"el":75,"az":84,"ss":34,"used":true},{"PRN":8,"el":59,"az":224,"ss":0,"used":false},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":12,"az":106,"ss":46,"used":true},{"PRN":25,"el":54,"az":69,"ss":38,"used":true},{"PRN":27,"el":83,"az":102,"ss":31,"used":true},{"PRN":28,"el":5,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123720.000,5356.21542,N,02734.86206,E,1,06,04.7,254.7,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064640.000,"ept":0.005,"lat":53.936923667,"lon":27.581034333,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123721.000,A,5356.21540,N,02734.86205,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123721.000,5356.21543,N,02734.86202,E,1,06,04.7,254.7,M,26.0,M,,*65 +{"class":"TPV","tag":"GGA","time":1212064641.000,"ept":0.005,"lat":53.936923833,"lon":27.581033667,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123722.000,A,5356.21541,N,02734.86202,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123722.000,5356.21543,N,02734.86198,E,1,06,04.7,254.7,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064642.000,"ept":0.005,"lat":53.936923833,"lon":27.581033000,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123723.000,A,5356.21541,N,02734.86198,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123723.000,5356.21546,N,02734.86203,E,1,06,04.7,254.7,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064643.000,"ept":0.005,"lat":53.936924333,"lon":27.581033833,"alt":254.700,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123724.000,A,5356.21543,N,02734.86203,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123724.000,5356.21548,N,02734.86207,E,1,06,04.7,254.8,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064644.000,"ept":0.005,"lat":53.936924667,"lon":27.581034500,"alt":254.800,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123725.000,A,5356.21544,N,02734.86208,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123725.000,5356.21549,N,02734.86210,E,1,06,04.7,254.8,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064645.000,"ept":0.005,"lat":53.936924833,"lon":27.581035000,"alt":254.800,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123726.000,A,5356.21547,N,02734.86211,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.2*3A +$GPGSV,4,1,14,02,12,247,,03,11,064,,06,10,044,,07,75,084,34*71 +$GPGSV,4,2,14,08,59,224,,13,47,102,51,23,11,106,45,25,54,068,38*78 +$GPGSV,4,3,14,27,83,101,31,28,05,181,46,33,17,229,,37,28,187,*7D +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":2.21,"vdop":1.68,"tdop":0.92,"hdop":2.52,"gdop":3.16,"pdop":3.03,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":0,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":84,"ss":34,"used":true},{"PRN":8,"el":59,"az":224,"ss":0,"used":false},{"PRN":13,"el":47,"az":102,"ss":51,"used":true},{"PRN":23,"el":11,"az":106,"ss":45,"used":true},{"PRN":25,"el":54,"az":68,"ss":38,"used":true},{"PRN":27,"el":83,"az":101,"ss":31,"used":true},{"PRN":28,"el":5,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123726.000,5356.21550,N,02734.86213,E,1,06,04.7,254.8,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064646.000,"ept":0.005,"lat":53.936925000,"lon":27.581035500,"alt":254.800,"epx":18.139,"epy":33.532,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":67.06,"mode":3} +$GPRMC,123727.000,A,5356.21547,N,02734.86213,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123727.000,5356.21552,N,02734.86214,E,1,06,04.7,254.9,M,26.0,M,,*6A +{"class":"TPV","tag":"GGA","time":1212064647.000,"ept":0.005,"lat":53.936925333,"lon":27.581035667,"alt":254.900,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.64,"mode":3} +$GPRMC,123728.000,A,5356.21550,N,02734.86214,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123728.000,5356.21553,N,02734.86215,E,1,06,04.7,254.9,M,26.0,M,,*65 +{"class":"TPV","tag":"GGA","time":1212064648.000,"ept":0.005,"lat":53.936925500,"lon":27.581035833,"alt":254.900,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123729.000,A,5356.21551,N,02734.86214,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123729.000,5356.21555,N,02734.86214,E,1,06,04.7,254.8,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064649.000,"ept":0.005,"lat":53.936925833,"lon":27.581035667,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123730.000,A,5356.21553,N,02734.86214,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123730.000,5356.21557,N,02734.86213,E,1,06,04.7,254.8,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064650.000,"ept":0.005,"lat":53.936926167,"lon":27.581035500,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123731.000,A,5356.21554,N,02734.86214,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123731.000,5356.21557,N,02734.86212,E,1,06,04.7,254.8,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064651.000,"ept":0.005,"lat":53.936926167,"lon":27.581035333,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123732.000,A,5356.21555,N,02734.86212,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.1*39 +$GPGSV,4,1,14,02,12,247,,03,11,064,,06,10,044,,07,75,084,34*71 +$GPGSV,4,2,14,08,59,224,,13,47,102,51,23,11,106,46,25,54,068,38*7B +$GPGSV,4,3,14,27,83,101,32,28,05,181,45,33,17,229,,37,28,187,*7D +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":2.21,"vdop":1.68,"tdop":0.92,"hdop":2.52,"gdop":3.16,"pdop":3.03,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":0,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":84,"ss":34,"used":true},{"PRN":8,"el":59,"az":224,"ss":0,"used":false},{"PRN":13,"el":47,"az":102,"ss":51,"used":true},{"PRN":23,"el":11,"az":106,"ss":46,"used":true},{"PRN":25,"el":54,"az":68,"ss":38,"used":true},{"PRN":27,"el":83,"az":101,"ss":32,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123732.000,5356.21558,N,02734.86210,E,1,06,04.7,254.8,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064652.000,"ept":0.005,"lat":53.936926333,"lon":27.581035000,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123733.000,A,5356.21556,N,02734.86211,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123733.000,5356.21559,N,02734.86209,E,1,06,04.7,254.8,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064653.000,"ept":0.005,"lat":53.936926500,"lon":27.581034833,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123734.000,A,5356.21555,N,02734.86209,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123734.000,5356.21559,N,02734.86207,E,1,06,04.7,254.8,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064654.000,"ept":0.005,"lat":53.936926500,"lon":27.581034500,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123735.000,A,5356.21557,N,02734.86207,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123735.000,5356.21559,N,02734.86206,E,1,06,04.7,254.8,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064655.000,"ept":0.005,"lat":53.936926500,"lon":27.581034333,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123736.000,A,5356.21556,N,02734.86206,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123736.000,5356.21560,N,02734.86204,E,1,06,04.7,254.8,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064656.000,"ept":0.005,"lat":53.936926667,"lon":27.581034000,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123737.000,A,5356.21558,N,02734.86205,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123737.000,5356.21560,N,02734.86202,E,1,06,04.7,254.8,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064657.000,"ept":0.005,"lat":53.936926667,"lon":27.581033667,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123738.000,A,5356.21558,N,02734.86202,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.1*39 +$GPGSV,4,1,14,02,12,247,,03,11,064,18,06,10,044,,07,75,084,34*78 +$GPGSV,4,2,14,08,59,224,,13,47,102,51,23,11,106,47,25,54,068,38*7A +$GPGSV,4,3,14,27,83,101,32,28,05,181,45,33,17,229,,37,28,187,*7D +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":2.21,"vdop":1.68,"tdop":0.92,"hdop":2.52,"gdop":3.16,"pdop":3.03,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":18,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":84,"ss":34,"used":true},{"PRN":8,"el":59,"az":224,"ss":0,"used":false},{"PRN":13,"el":47,"az":102,"ss":51,"used":true},{"PRN":23,"el":11,"az":106,"ss":47,"used":true},{"PRN":25,"el":54,"az":68,"ss":38,"used":true},{"PRN":27,"el":83,"az":101,"ss":32,"used":true},{"PRN":28,"el":5,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123738.000,5356.21562,N,02734.86199,E,1,06,04.7,254.8,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064658.000,"ept":0.005,"lat":53.936927000,"lon":27.581033167,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123739.000,A,5356.21559,N,02734.86199,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123739.000,5356.21564,N,02734.86196,E,1,06,04.7,254.8,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064659.000,"ept":0.005,"lat":53.936927333,"lon":27.581032667,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123740.000,A,5356.21563,N,02734.86196,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123740.000,5356.21567,N,02734.86194,E,1,06,04.7,254.7,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064660.000,"ept":0.005,"lat":53.936927833,"lon":27.581032333,"alt":254.700,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123741.000,A,5356.21564,N,02734.86194,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123741.000,5356.21568,N,02734.86192,E,1,06,04.7,254.7,M,26.0,M,,*60 +{"class":"TPV","tag":"GGA","time":1212064661.000,"ept":0.005,"lat":53.936928000,"lon":27.581032000,"alt":254.700,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123742.000,A,5356.21566,N,02734.86192,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123742.000,5356.21570,N,02734.86190,E,1,06,04.7,254.7,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064662.000,"ept":0.005,"lat":53.936928333,"lon":27.581031667,"alt":254.700,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123743.000,A,5356.21567,N,02734.86191,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123743.000,5356.21571,N,02734.86189,E,1,06,04.7,254.6,M,26.0,M,,*61 +{"class":"TPV","tag":"GGA","time":1212064663.000,"ept":0.005,"lat":53.936928500,"lon":27.581031500,"alt":254.600,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123744.000,A,5356.21568,N,02734.86189,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.3*3B +$GPGSV,4,1,14,02,12,247,,03,11,064,,06,10,044,,07,75,084,35*70 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,11,106,46,25,54,068,38*7A +$GPGSV,4,3,14,27,83,101,32,28,05,181,46,33,17,229,,37,28,187,*7E +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":2.21,"vdop":1.68,"tdop":0.92,"hdop":2.52,"gdop":3.16,"pdop":3.03,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":0,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":84,"ss":35,"used":true},{"PRN":8,"el":59,"az":224,"ss":0,"used":false},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":11,"az":106,"ss":46,"used":true},{"PRN":25,"el":54,"az":68,"ss":38,"used":true},{"PRN":27,"el":83,"az":101,"ss":32,"used":true},{"PRN":28,"el":5,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123744.000,5356.21572,N,02734.86187,E,1,06,04.7,254.6,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064664.000,"ept":0.005,"lat":53.936928667,"lon":27.581031167,"alt":254.600,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123745.000,A,5356.21570,N,02734.86186,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123745.000,5356.21573,N,02734.86184,E,1,06,04.7,254.6,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064665.000,"ept":0.005,"lat":53.936928833,"lon":27.581030667,"alt":254.600,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123746.000,A,5356.21571,N,02734.86184,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123746.000,5356.21574,N,02734.86181,E,1,06,04.7,254.6,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064666.000,"ept":0.005,"lat":53.936929000,"lon":27.581030167,"alt":254.600,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123747.000,A,5356.21571,N,02734.86182,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123747.000,5356.21573,N,02734.86179,E,1,06,04.7,254.6,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064667.000,"ept":0.005,"lat":53.936928833,"lon":27.581029833,"alt":254.600,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123748.000,A,5356.21570,N,02734.86179,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123748.000,5356.21573,N,02734.86175,E,1,06,04.7,254.6,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064668.000,"ept":0.005,"lat":53.936928833,"lon":27.581029167,"alt":254.600,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123749.000,A,5356.21572,N,02734.86175,E,00.00,252.7,290508,,,A*69 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123749.000,5356.21573,N,02734.86173,E,1,06,04.7,254.6,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064669.000,"ept":0.005,"lat":53.936928833,"lon":27.581028833,"alt":254.600,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123750.000,A,5356.21569,N,02734.86174,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.3*3B +$GPGSV,4,1,14,02,12,247,,03,11,064,,06,10,044,,07,75,084,35*70 +$GPGSV,4,2,14,08,59,224,,13,47,102,50,23,11,106,46,25,54,068,38*7A +$GPGSV,4,3,14,27,83,101,32,28,05,181,47,33,17,229,,37,28,187,*7F +$GPGSV,4,4,14,39,28,183,,44,20,137,*71 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":2.21,"vdop":1.68,"tdop":0.92,"hdop":2.52,"gdop":3.16,"pdop":3.03,"satellites":[{"PRN":2,"el":12,"az":247,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":0,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":84,"ss":35,"used":true},{"PRN":8,"el":59,"az":224,"ss":0,"used":false},{"PRN":13,"el":47,"az":102,"ss":50,"used":true},{"PRN":23,"el":11,"az":106,"ss":46,"used":true},{"PRN":25,"el":54,"az":68,"ss":38,"used":true},{"PRN":27,"el":83,"az":101,"ss":32,"used":true},{"PRN":28,"el":5,"az":181,"ss":47,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123750.000,5356.21570,N,02734.86172,E,1,06,04.7,254.6,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064670.000,"ept":0.005,"lat":53.936928333,"lon":27.581028667,"alt":254.600,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123751.000,A,5356.21568,N,02734.86171,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123751.000,5356.21570,N,02734.86168,E,1,06,04.7,254.6,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064671.000,"ept":0.005,"lat":53.936928333,"lon":27.581028000,"alt":254.600,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123752.000,A,5356.21567,N,02734.86169,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123752.000,5356.21569,N,02734.86167,E,1,06,04.7,254.7,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064672.000,"ept":0.005,"lat":53.936928167,"lon":27.581027833,"alt":254.700,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123753.000,A,5356.21567,N,02734.86166,E,00.00,252.7,290508,,,A*64 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123753.000,5356.21570,N,02734.86172,E,1,06,04.7,254.7,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064673.000,"ept":0.005,"lat":53.936928333,"lon":27.581028667,"alt":254.700,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123754.000,A,5356.21567,N,02734.86172,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.4*3C +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123754.000,5356.21570,N,02734.86177,E,1,06,04.7,254.8,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064674.000,"ept":0.005,"lat":53.936928333,"lon":27.581029500,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123755.000,A,5356.21567,N,02734.86178,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123755.000,5356.21570,N,02734.86182,E,1,06,04.7,254.8,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064675.000,"ept":0.005,"lat":53.936928333,"lon":27.581030333,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123756.000,A,5356.21567,N,02734.86183,E,00.00,252.7,290508,,,A*6A +$PORZD,A,015.3*3B +$GPGSV,4,1,15,02,12,246,,03,11,064,,06,10,044,,07,75,083,36*74 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,106,46*7F +$GPGSV,4,3,15,25,54,068,38,27,83,099,32,28,06,181,46,33,17,229,*7F +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +{"class":"SKY","tag":"GSV","xdop":0.91,"ydop":1.56,"vdop":1.31,"tdop":0.86,"hdop":1.80,"gdop":2.39,"pdop":2.23,"satellites":[{"PRN":2,"el":12,"az":246,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":0,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":83,"ss":36,"used":true},{"PRN":8,"el":60,"az":224,"ss":0,"used":false},{"PRN":10,"el":46,"az":294,"ss":0,"used":false},{"PRN":13,"el":46,"az":102,"ss":50,"used":true},{"PRN":23,"el":11,"az":106,"ss":46,"used":true},{"PRN":25,"el":54,"az":68,"ss":38,"used":true},{"PRN":27,"el":83,"az":99,"ss":32,"used":true},{"PRN":28,"el":6,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123756.000,5356.21570,N,02734.86187,E,1,06,04.7,254.8,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064676.000,"ept":0.005,"lat":53.936928333,"lon":27.581031167,"alt":254.800,"epx":18.190,"epy":33.110,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":66.22,"mode":3} +$GPRMC,123757.000,A,5356.21567,N,02734.86186,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123757.000,5356.21568,N,02734.86191,E,1,06,04.7,254.9,M,26.0,M,,*6A +{"class":"TPV","tag":"GGA","time":1212064677.000,"ept":0.005,"lat":53.936928000,"lon":27.581031833,"alt":254.900,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":56.47,"mode":3} +$GPRMC,123758.000,A,5356.21565,N,02734.86193,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123758.000,5356.21567,N,02734.86196,E,1,06,04.7,254.9,M,26.0,M,,*6D +{"class":"TPV","tag":"GGA","time":1212064678.000,"ept":0.005,"lat":53.936927833,"lon":27.581032667,"alt":254.900,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123759.000,A,5356.21565,N,02734.86197,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123759.000,5356.21566,N,02734.86198,E,1,06,04.7,254.9,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064679.000,"ept":0.005,"lat":53.936927667,"lon":27.581033000,"alt":254.900,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123800.000,A,5356.21563,N,02734.86198,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123800.000,5356.21565,N,02734.86199,E,1,06,04.7,255.0,M,26.0,M,,*6A +{"class":"TPV","tag":"GGA","time":1212064680.000,"ept":0.005,"lat":53.936927500,"lon":27.581033167,"alt":255.000,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123801.000,A,5356.21563,N,02734.86200,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123801.000,5356.21564,N,02734.86202,E,1,06,04.7,255.0,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064681.000,"ept":0.005,"lat":53.936927333,"lon":27.581033667,"alt":255.000,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123802.000,A,5356.21562,N,02734.86202,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.3*3B +$GPGSV,4,1,15,02,12,246,,03,11,064,,06,10,044,,07,75,083,35*77 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,106,46*7F +$GPGSV,4,3,15,25,54,068,38,27,83,099,32,28,06,181,46,33,17,229,*7F +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +{"class":"SKY","tag":"GSV","xdop":0.91,"ydop":1.56,"vdop":1.31,"tdop":0.86,"hdop":1.80,"gdop":2.39,"pdop":2.23,"satellites":[{"PRN":2,"el":12,"az":246,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":0,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":83,"ss":35,"used":true},{"PRN":8,"el":60,"az":224,"ss":0,"used":false},{"PRN":10,"el":46,"az":294,"ss":0,"used":false},{"PRN":13,"el":46,"az":102,"ss":50,"used":true},{"PRN":23,"el":11,"az":106,"ss":46,"used":true},{"PRN":25,"el":54,"az":68,"ss":38,"used":true},{"PRN":27,"el":83,"az":99,"ss":32,"used":true},{"PRN":28,"el":6,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123802.000,5356.21563,N,02734.86203,E,1,06,04.7,255.0,M,26.0,M,,*6E +{"class":"TPV","tag":"GGA","time":1212064682.000,"ept":0.005,"lat":53.936927167,"lon":27.581033833,"alt":255.000,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123803.000,A,5356.21561,N,02734.86203,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123803.000,5356.21562,N,02734.86205,E,1,06,04.7,255.0,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064683.000,"ept":0.005,"lat":53.936927000,"lon":27.581034167,"alt":255.000,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123804.000,A,5356.21558,N,02734.86206,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123804.000,5356.21559,N,02734.86207,E,1,06,04.7,255.1,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064684.000,"ept":0.005,"lat":53.936926500,"lon":27.581034500,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123805.000,A,5356.21557,N,02734.86206,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123805.000,5356.21558,N,02734.86207,E,1,06,04.7,255.1,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064685.000,"ept":0.005,"lat":53.936926333,"lon":27.581034500,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123806.000,A,5356.21555,N,02734.86207,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123806.000,5356.21555,N,02734.86208,E,1,06,04.7,255.1,M,26.0,M,,*65 +{"class":"TPV","tag":"GGA","time":1212064686.000,"ept":0.005,"lat":53.936925833,"lon":27.581034667,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123807.000,A,5356.21552,N,02734.86210,E,00.00,252.7,290508,,,A*6E +$PORZD,A,015.3*3B +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123807.000,5356.21553,N,02734.86210,E,1,06,04.7,255.1,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064687.000,"ept":0.005,"lat":53.936925500,"lon":27.581035000,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123808.000,A,5356.21551,N,02734.86210,E,00.00,252.7,290508,,,A*62 +$PORZD,A,015.3*3B +$GPGSV,4,1,15,02,12,246,,03,11,064,,06,10,044,,07,75,083,35*77 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,106,46*7F +$GPGSV,4,3,15,25,54,068,37,27,83,099,32,28,06,181,46,33,17,229,*70 +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +{"class":"SKY","tag":"GSV","xdop":0.91,"ydop":1.56,"vdop":1.31,"tdop":0.86,"hdop":1.80,"gdop":2.39,"pdop":2.23,"satellites":[{"PRN":2,"el":12,"az":246,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":0,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":83,"ss":35,"used":true},{"PRN":8,"el":60,"az":224,"ss":0,"used":false},{"PRN":10,"el":46,"az":294,"ss":0,"used":false},{"PRN":13,"el":46,"az":102,"ss":50,"used":true},{"PRN":23,"el":11,"az":106,"ss":46,"used":true},{"PRN":25,"el":54,"az":68,"ss":37,"used":true},{"PRN":27,"el":83,"az":99,"ss":32,"used":true},{"PRN":28,"el":6,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123808.000,5356.21552,N,02734.86211,E,1,06,04.7,255.1,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064688.000,"ept":0.005,"lat":53.936925333,"lon":27.581035167,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123809.000,A,5356.21549,N,02734.86212,E,00.00,252.7,290508,,,A*68 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123809.000,5356.21550,N,02734.86212,E,1,06,04.7,255.1,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064689.000,"ept":0.005,"lat":53.936925000,"lon":27.581035333,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123810.000,A,5356.21548,N,02734.86212,E,00.00,252.7,290508,,,A*61 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123810.000,5356.21550,N,02734.86211,E,1,06,04.7,255.1,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064690.000,"ept":0.005,"lat":53.936925000,"lon":27.581035167,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123811.000,A,5356.21548,N,02734.86211,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123811.000,5356.21549,N,02734.86210,E,1,06,04.7,255.1,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064691.000,"ept":0.005,"lat":53.936924833,"lon":27.581035000,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123812.000,A,5356.21545,N,02734.86211,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.2,04.7,04.0*0D +$GPGGA,123812.000,5356.21548,N,02734.86209,E,1,06,04.7,255.1,M,26.0,M,,*6D +{"class":"TPV","tag":"GGA","time":1212064692.000,"ept":0.005,"lat":53.936924667,"lon":27.581034833,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123813.000,A,5356.21545,N,02734.86210,E,00.00,252.7,290508,,,A*6D +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123813.000,5356.21548,N,02734.86207,E,1,06,04.7,255.1,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064693.000,"ept":0.005,"lat":53.936924667,"lon":27.581034500,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123814.000,A,5356.21546,N,02734.86207,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.2*3A +$GPGSV,4,1,15,02,12,246,,03,11,064,,06,10,044,,07,75,083,36*74 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,106,45*7C +$GPGSV,4,3,15,25,54,068,38,27,83,099,32,28,06,181,45,33,17,229,*7C +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +{"class":"SKY","tag":"GSV","xdop":0.91,"ydop":1.56,"vdop":1.31,"tdop":0.86,"hdop":1.80,"gdop":2.39,"pdop":2.23,"satellites":[{"PRN":2,"el":12,"az":246,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":0,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":83,"ss":36,"used":true},{"PRN":8,"el":60,"az":224,"ss":0,"used":false},{"PRN":10,"el":46,"az":294,"ss":0,"used":false},{"PRN":13,"el":46,"az":102,"ss":50,"used":true},{"PRN":23,"el":11,"az":106,"ss":45,"used":true},{"PRN":25,"el":54,"az":68,"ss":38,"used":true},{"PRN":27,"el":83,"az":99,"ss":32,"used":true},{"PRN":28,"el":6,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123814.000,5356.21548,N,02734.86206,E,1,06,04.7,255.1,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064694.000,"ept":0.005,"lat":53.936924667,"lon":27.581034333,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123815.000,A,5356.21544,N,02734.86207,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123815.000,5356.21547,N,02734.86205,E,1,06,04.7,255.1,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064695.000,"ept":0.005,"lat":53.936924500,"lon":27.581034167,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123816.000,A,5356.21545,N,02734.86206,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123816.000,5356.21548,N,02734.86204,E,1,06,04.7,255.1,M,26.0,M,,*64 +{"class":"TPV","tag":"GGA","time":1212064696.000,"ept":0.005,"lat":53.936924667,"lon":27.581034000,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123817.000,A,5356.21545,N,02734.86204,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123817.000,5356.21549,N,02734.86202,E,1,06,04.7,255.1,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064697.000,"ept":0.005,"lat":53.936924833,"lon":27.581033667,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123818.000,A,5356.21546,N,02734.86202,E,00.00,252.7,290508,,,A*66 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123818.000,5356.21550,N,02734.86200,E,1,06,04.7,255.0,M,26.0,M,,*66 +{"class":"TPV","tag":"GGA","time":1212064698.000,"ept":0.005,"lat":53.936925000,"lon":27.581033333,"alt":255.000,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123819.000,A,5356.21547,N,02734.86201,E,00.00,252.7,290508,,,A*65 +$PORZD,A,015.2*3A +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123819.000,5356.21551,N,02734.86199,E,1,06,04.7,255.0,M,26.0,M,,*65 +{"class":"TPV","tag":"GGA","time":1212064699.000,"ept":0.005,"lat":53.936925167,"lon":27.581033167,"alt":255.000,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123820.000,A,5356.21548,N,02734.86201,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.1*39 +$GPGSV,4,1,15,02,12,246,,03,11,064,,06,10,044,,07,75,083,36*74 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,106,46*7F +$GPGSV,4,3,15,25,54,068,37,27,83,099,32,28,06,181,45,33,17,229,*73 +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +{"class":"SKY","tag":"GSV","xdop":0.91,"ydop":1.56,"vdop":1.31,"tdop":0.86,"hdop":1.80,"gdop":2.39,"pdop":2.23,"satellites":[{"PRN":2,"el":12,"az":246,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":0,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":83,"ss":36,"used":true},{"PRN":8,"el":60,"az":224,"ss":0,"used":false},{"PRN":10,"el":46,"az":294,"ss":0,"used":false},{"PRN":13,"el":46,"az":102,"ss":50,"used":true},{"PRN":23,"el":11,"az":106,"ss":46,"used":true},{"PRN":25,"el":54,"az":68,"ss":37,"used":true},{"PRN":27,"el":83,"az":99,"ss":32,"used":true},{"PRN":28,"el":6,"az":181,"ss":45,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123820.000,5356.21552,N,02734.86199,E,1,06,04.7,255.0,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064700.000,"ept":0.005,"lat":53.936925333,"lon":27.581033167,"alt":255.000,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123821.000,A,5356.21550,N,02734.86198,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123821.000,5356.21554,N,02734.86196,E,1,06,04.7,254.9,M,26.0,M,,*6C +{"class":"TPV","tag":"GGA","time":1212064701.000,"ept":0.005,"lat":53.936925667,"lon":27.581032667,"alt":254.900,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123822.000,A,5356.21551,N,02734.86196,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123822.000,5356.21555,N,02734.86193,E,1,06,04.7,254.9,M,26.0,M,,*6B +{"class":"TPV","tag":"GGA","time":1212064702.000,"ept":0.005,"lat":53.936925833,"lon":27.581032167,"alt":254.900,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123823.000,A,5356.21552,N,02734.86194,E,00.00,252.7,290508,,,A*67 +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123823.000,5356.21543,N,02734.86204,E,1,07,03.2,255.2,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064703.000,"ept":0.005,"lat":53.936923833,"lon":27.581034000,"alt":255.200,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123824.000,A,5356.21543,N,02734.86203,E,00.00,252.7,290508,,,A*6D +$PORZD,A,014.2*3B +$GPGSA,A,3,19,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,03.8,03.2,02.2*0C +$GPGGA,123824.000,5356.21547,N,02734.86205,E,1,06,04.7,255.2,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064704.000,"ept":0.005,"lat":53.936924500,"lon":27.581034167,"alt":255.200,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123825.000,A,5356.21544,N,02734.86207,E,00.00,252.7,290508,,,A*6F +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123825.000,5356.21551,N,02734.86207,E,1,06,04.7,255.1,M,26.0,M,,*6F +{"class":"TPV","tag":"GGA","time":1212064705.000,"ept":0.005,"lat":53.936925167,"lon":27.581034500,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123826.000,A,5356.21549,N,02734.86206,E,00.00,252.7,290508,,,A*60 +$PORZD,A,015.1*39 +$GPGSV,4,1,15,02,11,246,,03,11,064,,06,10,044,,07,75,083,36*77 +$GPGSV,4,2,15,08,60,224,,10,46,294,,13,46,102,50,23,11,107,47*7F +$GPGSV,4,3,15,25,54,068,37,27,82,098,32,28,06,181,46,33,17,229,*70 +$GPGSV,4,4,15,37,28,187,,39,28,183,,44,20,137,*40 +{"class":"SKY","tag":"GSV","xdop":0.91,"ydop":1.55,"vdop":1.29,"tdop":0.85,"hdop":1.80,"gdop":2.37,"pdop":2.22,"satellites":[{"PRN":2,"el":11,"az":246,"ss":0,"used":false},{"PRN":3,"el":11,"az":64,"ss":0,"used":false},{"PRN":6,"el":10,"az":44,"ss":0,"used":false},{"PRN":7,"el":75,"az":83,"ss":36,"used":true},{"PRN":8,"el":60,"az":224,"ss":0,"used":false},{"PRN":10,"el":46,"az":294,"ss":0,"used":false},{"PRN":13,"el":46,"az":102,"ss":50,"used":true},{"PRN":23,"el":11,"az":107,"ss":47,"used":true},{"PRN":25,"el":54,"az":68,"ss":37,"used":true},{"PRN":27,"el":82,"az":98,"ss":32,"used":true},{"PRN":28,"el":6,"az":181,"ss":46,"used":true},{"PRN":33,"el":17,"az":229,"ss":0,"used":false},{"PRN":37,"el":28,"az":187,"ss":0,"used":false},{"PRN":39,"el":28,"az":183,"ss":0,"used":false},{"PRN":44,"el":20,"az":137,"ss":0,"used":false}]} +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123826.000,5356.21556,N,02734.86205,E,1,06,04.7,255.1,M,26.0,M,,*69 +{"class":"TPV","tag":"GGA","time":1212064706.000,"ept":0.005,"lat":53.936926000,"lon":27.581034167,"alt":255.100,"epx":13.656,"epy":23.360,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.72,"mode":3} +$GPRMC,123827.000,A,5356.21553,N,02734.86207,E,00.00,252.7,290508,,,A*6B +$PORZD,A,015.1*39 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123827.000,5356.21558,N,02734.86205,E,1,06,04.7,255.0,M,26.0,M,,*67 +{"class":"TPV","tag":"GGA","time":1212064707.000,"ept":0.005,"lat":53.936926333,"lon":27.581034167,"alt":255.000,"epx":13.652,"epy":23.310,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.67,"mode":3} +$GPRMC,123828.000,A,5356.21555,N,02734.86206,E,00.00,252.7,290508,,,A*63 +$PORZD,A,015.0*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123828.000,5356.21561,N,02734.86204,E,1,06,04.7,255.0,M,26.0,M,,*63 +{"class":"TPV","tag":"GGA","time":1212064708.000,"ept":0.005,"lat":53.936926833,"lon":27.581034000,"alt":255.000,"epx":13.652,"epy":23.310,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.62,"mode":3} +$GPRMC,123829.000,A,5356.21559,N,02734.86204,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.0*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123829.000,5356.21565,N,02734.86202,E,1,06,04.7,254.9,M,26.0,M,,*68 +{"class":"TPV","tag":"GGA","time":1212064709.000,"ept":0.005,"lat":53.936927500,"lon":27.581033667,"alt":254.900,"epx":13.652,"epy":23.310,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.62,"mode":3} +$GPRMC,123830.000,A,5356.21562,N,02734.86204,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.0*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E +$GPGGA,123830.000,5356.21567,N,02734.86202,E,1,06,04.7,254.9,M,26.0,M,,*62 +{"class":"TPV","tag":"GGA","time":1212064710.000,"ept":0.005,"lat":53.936927833,"lon":27.581033667,"alt":254.900,"epx":13.652,"epy":23.310,"epv":0.000,"track":252.7000,"speed":0.000,"climb":0.000,"eps":46.62,"mode":3} +$GPRMC,123831.000,A,5356.21566,N,02734.86201,E,00.00,252.7,290508,,,A*6C +$PORZD,A,015.0*38 +$GPGSA,A,3,28,27,23,13,07,25,,,,,,,,,,,,,,,,,,,06.1,04.7,04.0*0E diff --git a/test/daemon/ch-4711.log b/test/daemon/ch-4711.log new file mode 100644 index 0000000..f6bff4d --- /dev/null +++ b/test/daemon/ch-4711.log @@ -0,0 +1,234 @@ +# Name: CH-4711 +# Chipset: CH-4706, rev "m4706 03.10 02/06/09 | 12044 | M2002 05.01 02/06/09" +# Description: Russian-made GPS mouse emitting GLONASS sentences. +# Cycle-time: 1 sec +# Submitted-by: walkie@mail.ru +# Location = Moscow, Russia, 55.71N 37.41E +# Notes: Emits GLONASS sentences. Mostly 2D fixes but it loses +# satellite lock near the end and the sentence mix changes. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GNGGA,135627.997,5543.0325,N,03724.7192,E,1,06,01.8,165.6,M,14.6,M,,*75 +$GNRMC,135627.997,A,5543.0325,N,03724.7192,E,00.00,129.5,051209,,,A*7F +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135628.997,5543.0325,N,03724.7193,E,1,06,01.8,165.6,M,14.6,M,,*7B +$GNRMC,135628.997,A,5543.0325,N,03724.7193,E,00.00,129.5,051209,,,A*71 +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135629.997,5543.0325,N,03724.7194,E,1,06,01.8,165.6,M,14.6,M,,*7D +$GNRMC,135629.997,A,5543.0325,N,03724.7194,E,00.00,129.5,051209,,,A*77 +$PORZD,A,024.1*3B +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,43,068,,19,58,270,35,21,16,107,,22,76,110,*7F +$GPGSV,4,3,14,26,42,127,,27,13,055,27,28,08,344,,33,11,238,*77 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +$GLGSV,2,1,06,66,18,048,,67,72,050,31,75,16,358,38,82,47,171,*68 +$GLGSV,2,2,06,83,66,292,37,84,16,325,34*6D +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGBS,135629.997,17.2,16.9,1.0,,,,*69 +$GNGGA,135630.997,5543.0325,N,03724.7194,E,1,06,01.8,165.6,M,14.6,M,,*75 +$GNRMC,135630.997,A,5543.0325,N,03724.7194,E,00.00,129.5,051209,,,A*7F +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135631.997,5543.0326,N,03724.7195,E,1,06,01.8,165.6,M,14.6,M,,*76 +$GNRMC,135631.997,A,5543.0326,N,03724.7195,E,00.00,129.5,051209,,,A*7C +$PORZD,A,023.8*35 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135632.997,5543.0326,N,03724.7195,E,1,06,01.8,165.6,M,14.6,M,,*75 +$GNRMC,135632.997,A,5543.0326,N,03724.7195,E,00.00,129.5,051209,,,A*7F +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135633.997,5543.0326,N,03724.7196,E,1,06,01.8,165.6,M,14.6,M,,*77 +$GNRMC,135633.997,A,5543.0326,N,03724.7196,E,00.00,129.5,051209,,,A*7D +$PORZD,A,023.9*34 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135634.997,5543.0326,N,03724.7196,E,1,06,01.8,165.6,M,14.6,M,,*70 +$GNRMC,135634.997,A,5543.0326,N,03724.7196,E,00.00,129.5,051209,,,A*7A +$PORZD,A,023.8*35 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135635.997,5543.0326,N,03724.7196,E,1,06,01.8,165.6,M,14.6,M,,*71 +$GNRMC,135635.997,A,5543.0326,N,03724.7196,E,00.00,129.5,051209,,,A*7B +$PORZD,A,024.1*3B +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,43,068,,19,58,270,34,21,16,107,,22,76,110,*7E +$GPGSV,4,3,14,26,42,127,,27,13,055,27,28,08,344,,33,11,238,*77 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +$GLGSV,2,1,06,66,18,048,,67,72,050,31,75,16,358,37,82,47,171,*67 +$GLGSV,2,2,06,83,66,292,37,84,16,325,33*6A +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135636.997,5543.0326,N,03724.7196,E,1,06,01.8,165.6,M,14.6,M,,*72 +$GNRMC,135636.997,A,5543.0326,N,03724.7196,E,00.00,129.5,051209,,,A*78 +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135637.997,5543.0326,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*72 +$GNRMC,135637.997,A,5543.0326,N,03724.7197,E,00.00,129.5,051209,,,A*78 +$PORZD,A,023.7*3A +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135638.997,5543.0326,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*7D +$GNRMC,135638.997,A,5543.0326,N,03724.7197,E,00.00,129.5,051209,,,A*77 +$PORZD,A,024.0*3A +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135639.997,5543.0326,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*7C +$GNRMC,135639.997,A,5543.0326,N,03724.7197,E,00.00,129.5,051209,,,A*76 +$PORZD,A,024.0*3A +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGBS,135639.997,17.2,16.8,1.0,,,,*69 +$GNGGA,135640.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*73 +$GNRMC,135640.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*79 +$PORZD,A,024.0*3A +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135641.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*72 +$GNRMC,135641.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*78 +$PORZD,A,024.0*3A +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,43,068,,19,58,270,34,21,16,107,,22,76,110,*7E +$GPGSV,4,3,14,26,42,127,,27,13,055,27,28,08,344,,33,11,238,*77 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +$GLGSV,2,1,06,66,18,048,,67,72,050,31,75,16,358,37,82,47,171,*67 +$GLGSV,2,2,06,83,66,292,37,84,16,325,32*6B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135642.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*71 +$GNRMC,135642.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*7B +$PORZD,A,024.4*3E +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135643.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*70 +$GNRMC,135643.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*7A +$PORZD,A,024.4*3E +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135644.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*77 +$GNRMC,135644.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*7D +$PORZD,A,024.4*3E +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135645.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*76 +$GNRMC,135645.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*7C +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135646.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*75 +$GNRMC,135646.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*7F +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135647.997,5543.0328,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*7B +$GNRMC,135647.997,A,5543.0328,N,03724.7197,E,00.00,129.5,051209,,,A*71 +$PORZD,A,024.4*3E +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,42,068,,19,58,270,34,21,16,107,,22,76,109,*77 +$GPGSV,4,3,14,26,42,127,,27,13,055,26,28,08,344,,33,11,238,*76 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +$GLGSV,2,1,06,66,18,048,,67,72,050,31,75,16,358,38,82,47,171,*68 +$GLGSV,2,2,06,83,66,291,37,84,17,325,34*6F +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135648.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*7B +$GNRMC,135648.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*71 +$PORZD,A,024.3*39 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135649.997,5543.0328,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*75 +$GNRMC,135649.997,A,5543.0328,N,03724.7197,E,00.00,129.5,051209,,,A*7F +$PORZD,A,024.3*39 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGBS,135649.997,17.2,17.1,1.0,,,,*66 +$GNGGA,135650.997,5543.0328,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*7D +$GNRMC,135650.997,A,5543.0328,N,03724.7197,E,00.00,129.5,051209,,,A*77 +$PORZD,A,024.2*38 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135651.997,5543.0328,N,03724.7198,E,1,06,01.8,165.6,M,14.6,M,,*73 +$GNRMC,135651.997,A,5543.0328,N,03724.7198,E,00.00,129.5,051209,,,A*79 +$PORZD,A,024.2*38 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135652.997,5543.0328,N,03724.7198,E,1,06,01.8,165.6,M,14.6,M,,*70 +$GNRMC,135652.997,A,5543.0328,N,03724.7198,E,00.00,129.5,051209,,,A*7A +$PORZD,A,024.5*3F +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135653.997,5543.0328,N,03724.7198,E,1,06,01.8,165.6,M,14.6,M,,*71 +$GNRMC,135653.997,A,5543.0328,N,03724.7198,E,00.00,129.5,051209,,,A*7B +$PORZD,A,024.4*3E +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,42,068,,19,58,270,36,21,16,107,,22,76,109,*75 +$GPGSV,4,3,14,26,42,127,,27,13,055,25,28,08,344,22,33,11,238,*75 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +$GLGSV,2,1,06,66,18,048,,67,72,050,32,75,16,358,39,82,47,171,*6A +$GLGSV,2,2,06,83,66,291,37,84,17,325,34*6F +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GLGGA,135654.997,5543.0328,N,03724.7197,E,1,04,02.3,165.6,M,14.6,M,,*71 +$GLRMC,135654.997,A,5543.0328,N,03724.7197,E,00.00,129.5,051209,,,A*71 +$PORZD,A,027.0*39 +$GLGSA,A,2,67,84,83,75,,,,,,,,,02.5,02.3,01.0*1C +$GNGGA,135655.997,5543.0328,N,03724.7199,E,1,06,01.8,165.6,M,14.6,M,,*76 +$GNRMC,135655.997,A,5543.0328,N,03724.7199,E,00.00,129.5,051209,,,A*7C +$PORZD,A,024.5*3F +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135656.997,5543.0329,N,03724.7201,E,1,06,01.8,165.6,M,14.6,M,,*76 +$GNRMC,135656.997,A,5543.0329,N,03724.7201,E,00.00,129.5,051209,,,A*7C +$PORZD,A,024.5*3F +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135657.997,5543.0328,N,03724.7204,E,1,06,01.8,165.6,M,14.6,M,,*73 +$GNRMC,135657.997,A,5543.0328,N,03724.7204,E,00.79,159.0,051209,,,A*75 +$PORZD,A,025.7*3C +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GPGGA,135658.997,5543.0326,N,03724.7205,E,0,,,165.6,M,14.6,M,,*7D +$GPRMC,135658.997,V,5543.0326,N,03724.7205,E,00.79,159.0,051209,,,N*73 +$PORZD,V,026.0*2F +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGGA,135659.997,5543.0324,N,03724.7207,E,0,,,165.6,M,14.6,M,,*7C +$GPRMC,135659.997,V,5543.0324,N,03724.7207,E,00.79,159.0,051209,,,N*72 +$PORZD,V,029.8*28 +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,42,068,,19,58,270,,21,16,107,,22,76,109,*70 +$GPGSV,4,3,14,26,42,127,,27,13,055,,28,08,344,,33,11,238,*72 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +$GLGSV,2,1,06,66,18,048,,67,72,050,,75,16,358,26,82,47,171,*65 +$GLGSV,2,2,06,83,66,291,,84,17,325,22*6C +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGBS,135659.997,,,,,,,*55 +$GPGGA,135700.997,5543.0322,N,03724.7208,E,0,,,165.6,M,14.6,M,,*78 +$GPRMC,135700.997,V,5543.0322,N,03724.7208,E,00.79,159.0,051209,,,N*76 +$PORZD,V,037.1*2E +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGGA,135701.997,5543.0320,N,03724.7210,E,0,,,165.6,M,14.6,M,,*72 +$GPRMC,135701.997,V,5543.0320,N,03724.7210,E,00.79,159.0,051209,,,N*7C +$PORZD,V,048.0*27 +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGGA,135702.997,5543.0318,N,03724.7211,E,0,,,165.6,M,14.6,M,,*7B +$GPRMC,135702.997,V,5543.0318,N,03724.7211,E,00.79,159.0,051209,,,N*75 +$PORZD,V,062.4*2B +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGGA,135703.997,5543.0316,N,03724.7212,E,0,,,165.6,M,14.6,M,,*77 +$GPRMC,135703.997,V,5543.0316,N,03724.7212,E,00.79,159.0,051209,,,N*79 +$PORZD,V,080.3*20 +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGGA,135704.997,5543.0314,N,03724.7214,E,0,,,165.6,M,14.6,M,,*74 +$GPRMC,135704.997,V,5543.0314,N,03724.7214,E,00.79,159.0,051209,,,N*7A +$PORZD,V,101.8*23 +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 diff --git a/test/daemon/ch-4711.log.chk b/test/daemon/ch-4711.log.chk new file mode 100644 index 0000000..075afe4 --- /dev/null +++ b/test/daemon/ch-4711.log.chk @@ -0,0 +1,268 @@ +$GNGGA,135627.997,5543.0325,N,03724.7192,E,1,06,01.8,165.6,M,14.6,M,,*75 +{"class":"TPV","tag":"GGA","lat":55.717208333,"lon":37.411986667,"alt":165.600,"mode":3} +$GNRMC,135627.997,A,5543.0325,N,03724.7192,E,00.00,129.5,051209,,,A*7F +{"class":"TPV","tag":"RMC","time":1260021387.997,"ept":0.005,"lat":55.717208333,"lon":37.411986667,"alt":165.600,"track":129.5000,"speed":0.000,"mode":3} +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135628.997,5543.0325,N,03724.7193,E,1,06,01.8,165.6,M,14.6,M,,*7B +$GNRMC,135628.997,A,5543.0325,N,03724.7193,E,00.00,129.5,051209,,,A*71 +{"class":"TPV","tag":"RMC","time":1260021388.997,"ept":0.005,"lat":55.717208333,"lon":37.411988333,"alt":165.600,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"mode":3} +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135629.997,5543.0325,N,03724.7194,E,1,06,01.8,165.6,M,14.6,M,,*7D +$GNRMC,135629.997,A,5543.0325,N,03724.7194,E,00.00,129.5,051209,,,A*77 +{"class":"TPV","tag":"RMC","time":1260021389.997,"ept":0.005,"lat":55.717208333,"lon":37.411990000,"alt":165.600,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"mode":3} +$PORZD,A,024.1*3B +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,43,068,,19,58,270,35,21,16,107,,22,76,110,*7F +$GPGSV,4,3,14,26,42,127,,27,13,055,27,28,08,344,,33,11,238,*77 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +{"class":"SKY","tag":"GSV","xdop":14.63,"ydop":4.47,"vdop":37.14,"tdop":21.29,"hdop":15.30,"gdop":45.46,"pdop":40.16,"satellites":[{"PRN":3,"el":50,"az":217,"ss":0,"used":false},{"PRN":6,"el":49,"az":201,"ss":0,"used":false},{"PRN":9,"el":10,"az":68,"ss":0,"used":false},{"PRN":14,"el":30,"az":153,"ss":0,"used":false},{"PRN":18,"el":43,"az":68,"ss":0,"used":false},{"PRN":19,"el":58,"az":270,"ss":35,"used":false},{"PRN":21,"el":16,"az":107,"ss":0,"used":false},{"PRN":22,"el":76,"az":110,"ss":0,"used":false},{"PRN":26,"el":42,"az":127,"ss":0,"used":false},{"PRN":27,"el":13,"az":55,"ss":27,"used":false},{"PRN":28,"el":8,"az":344,"ss":0,"used":false},{"PRN":33,"el":11,"az":238,"ss":0,"used":false},{"PRN":37,"el":25,"az":199,"ss":0,"used":false},{"PRN":39,"el":25,"az":194,"ss":0,"used":false}]} +$GLGSV,2,1,06,66,18,048,,67,72,050,31,75,16,358,38,82,47,171,*68 +$GLGSV,2,2,06,83,66,292,37,84,16,325,34*6D +{"class":"SKY","tag":"GSV","xdop":1.84,"ydop":1.12,"vdop":2.42,"tdop":1.78,"hdop":2.15,"gdop":3.69,"pdop":3.23,"satellites":[{"PRN":66,"el":18,"az":48,"ss":0,"used":false},{"PRN":67,"el":72,"az":50,"ss":31,"used":true},{"PRN":75,"el":16,"az":358,"ss":38,"used":true},{"PRN":82,"el":47,"az":171,"ss":0,"used":false},{"PRN":83,"el":66,"az":292,"ss":37,"used":true},{"PRN":84,"el":16,"az":325,"ss":34,"used":true}]} +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGBS,135629.997,17.2,16.9,1.0,,,,*69 +$GNGGA,135630.997,5543.0325,N,03724.7194,E,1,06,01.8,165.6,M,14.6,M,,*75 +$GNRMC,135630.997,A,5543.0325,N,03724.7194,E,00.00,129.5,051209,,,A*7F +{"class":"TPV","tag":"RMC","time":1260021390.997,"ept":0.005,"lat":55.717208333,"lon":37.411990000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":44.73,"mode":3} +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135631.997,5543.0326,N,03724.7195,E,1,06,01.8,165.6,M,14.6,M,,*76 +$GNRMC,135631.997,A,5543.0326,N,03724.7195,E,00.00,129.5,051209,,,A*7C +{"class":"TPV","tag":"RMC","time":1260021391.997,"ept":0.005,"lat":55.717210000,"lon":37.411991667,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,023.8*35 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135632.997,5543.0326,N,03724.7195,E,1,06,01.8,165.6,M,14.6,M,,*75 +$GNRMC,135632.997,A,5543.0326,N,03724.7195,E,00.00,129.5,051209,,,A*7F +{"class":"TPV","tag":"RMC","time":1260021392.997,"ept":0.005,"lat":55.717210000,"lon":37.411991667,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135633.997,5543.0326,N,03724.7196,E,1,06,01.8,165.6,M,14.6,M,,*77 +$GNRMC,135633.997,A,5543.0326,N,03724.7196,E,00.00,129.5,051209,,,A*7D +{"class":"TPV","tag":"RMC","time":1260021393.997,"ept":0.005,"lat":55.717210000,"lon":37.411993333,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,023.9*34 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135634.997,5543.0326,N,03724.7196,E,1,06,01.8,165.6,M,14.6,M,,*70 +$GNRMC,135634.997,A,5543.0326,N,03724.7196,E,00.00,129.5,051209,,,A*7A +{"class":"TPV","tag":"RMC","time":1260021394.997,"ept":0.005,"lat":55.717210000,"lon":37.411993333,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,023.8*35 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135635.997,5543.0326,N,03724.7196,E,1,06,01.8,165.6,M,14.6,M,,*71 +$GNRMC,135635.997,A,5543.0326,N,03724.7196,E,00.00,129.5,051209,,,A*7B +{"class":"TPV","tag":"RMC","time":1260021395.997,"ept":0.005,"lat":55.717210000,"lon":37.411993333,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.1*3B +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,43,068,,19,58,270,34,21,16,107,,22,76,110,*7E +$GPGSV,4,3,14,26,42,127,,27,13,055,27,28,08,344,,33,11,238,*77 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +{"class":"SKY","tag":"GSV","xdop":14.63,"ydop":4.47,"vdop":37.14,"tdop":21.29,"hdop":15.30,"gdop":45.46,"pdop":40.16,"satellites":[{"PRN":3,"el":50,"az":217,"ss":0,"used":false},{"PRN":6,"el":49,"az":201,"ss":0,"used":false},{"PRN":9,"el":10,"az":68,"ss":0,"used":false},{"PRN":14,"el":30,"az":153,"ss":0,"used":false},{"PRN":18,"el":43,"az":68,"ss":0,"used":false},{"PRN":19,"el":58,"az":270,"ss":34,"used":false},{"PRN":21,"el":16,"az":107,"ss":0,"used":false},{"PRN":22,"el":76,"az":110,"ss":0,"used":false},{"PRN":26,"el":42,"az":127,"ss":0,"used":false},{"PRN":27,"el":13,"az":55,"ss":27,"used":false},{"PRN":28,"el":8,"az":344,"ss":0,"used":false},{"PRN":33,"el":11,"az":238,"ss":0,"used":false},{"PRN":37,"el":25,"az":199,"ss":0,"used":false},{"PRN":39,"el":25,"az":194,"ss":0,"used":false}]} +$GLGSV,2,1,06,66,18,048,,67,72,050,31,75,16,358,37,82,47,171,*67 +$GLGSV,2,2,06,83,66,292,37,84,16,325,33*6A +{"class":"SKY","tag":"GSV","xdop":1.84,"ydop":1.12,"vdop":2.42,"tdop":1.78,"hdop":2.15,"gdop":3.69,"pdop":3.23,"satellites":[{"PRN":66,"el":18,"az":48,"ss":0,"used":false},{"PRN":67,"el":72,"az":50,"ss":31,"used":true},{"PRN":75,"el":16,"az":358,"ss":37,"used":true},{"PRN":82,"el":47,"az":171,"ss":0,"used":false},{"PRN":83,"el":66,"az":292,"ss":37,"used":true},{"PRN":84,"el":16,"az":325,"ss":33,"used":true}]} +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135636.997,5543.0326,N,03724.7196,E,1,06,01.8,165.6,M,14.6,M,,*72 +$GNRMC,135636.997,A,5543.0326,N,03724.7196,E,00.00,129.5,051209,,,A*78 +{"class":"TPV","tag":"RMC","time":1260021396.997,"ept":0.005,"lat":55.717210000,"lon":37.411993333,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135637.997,5543.0326,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*72 +$GNRMC,135637.997,A,5543.0326,N,03724.7197,E,00.00,129.5,051209,,,A*78 +{"class":"TPV","tag":"RMC","time":1260021397.997,"ept":0.005,"lat":55.717210000,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,023.7*3A +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135638.997,5543.0326,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*7D +$GNRMC,135638.997,A,5543.0326,N,03724.7197,E,00.00,129.5,051209,,,A*77 +{"class":"TPV","tag":"RMC","time":1260021398.997,"ept":0.005,"lat":55.717210000,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.0*3A +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135639.997,5543.0326,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*7C +$GNRMC,135639.997,A,5543.0326,N,03724.7197,E,00.00,129.5,051209,,,A*76 +{"class":"TPV","tag":"RMC","time":1260021399.997,"ept":0.005,"lat":55.717210000,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.0*3A +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGBS,135639.997,17.2,16.8,1.0,,,,*69 +{"class":"TPV","tag":"GBS","time":1260021399.997,"ept":0.005,"lat":55.717210000,"lon":37.411995000,"alt":165.600,"epx":16.800,"epy":17.200,"epv":1.000,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$GNGGA,135640.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*73 +$GNRMC,135640.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*79 +{"class":"TPV","tag":"RMC","time":1260021400.997,"ept":0.005,"lat":55.717211667,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":44.73,"mode":3} +$PORZD,A,024.0*3A +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135641.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*72 +$GNRMC,135641.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*78 +{"class":"TPV","tag":"RMC","time":1260021401.997,"ept":0.005,"lat":55.717211667,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.0*3A +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,43,068,,19,58,270,34,21,16,107,,22,76,110,*7E +$GPGSV,4,3,14,26,42,127,,27,13,055,27,28,08,344,,33,11,238,*77 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +{"class":"SKY","tag":"GSV","xdop":14.63,"ydop":4.47,"vdop":37.14,"tdop":21.29,"hdop":15.30,"gdop":45.46,"pdop":40.16,"satellites":[{"PRN":3,"el":50,"az":217,"ss":0,"used":false},{"PRN":6,"el":49,"az":201,"ss":0,"used":false},{"PRN":9,"el":10,"az":68,"ss":0,"used":false},{"PRN":14,"el":30,"az":153,"ss":0,"used":false},{"PRN":18,"el":43,"az":68,"ss":0,"used":false},{"PRN":19,"el":58,"az":270,"ss":34,"used":false},{"PRN":21,"el":16,"az":107,"ss":0,"used":false},{"PRN":22,"el":76,"az":110,"ss":0,"used":false},{"PRN":26,"el":42,"az":127,"ss":0,"used":false},{"PRN":27,"el":13,"az":55,"ss":27,"used":false},{"PRN":28,"el":8,"az":344,"ss":0,"used":false},{"PRN":33,"el":11,"az":238,"ss":0,"used":false},{"PRN":37,"el":25,"az":199,"ss":0,"used":false},{"PRN":39,"el":25,"az":194,"ss":0,"used":false}]} +$GLGSV,2,1,06,66,18,048,,67,72,050,31,75,16,358,37,82,47,171,*67 +$GLGSV,2,2,06,83,66,292,37,84,16,325,32*6B +{"class":"SKY","tag":"GSV","xdop":1.84,"ydop":1.12,"vdop":2.42,"tdop":1.78,"hdop":2.15,"gdop":3.69,"pdop":3.23,"satellites":[{"PRN":66,"el":18,"az":48,"ss":0,"used":false},{"PRN":67,"el":72,"az":50,"ss":31,"used":true},{"PRN":75,"el":16,"az":358,"ss":37,"used":true},{"PRN":82,"el":47,"az":171,"ss":0,"used":false},{"PRN":83,"el":66,"az":292,"ss":37,"used":true},{"PRN":84,"el":16,"az":325,"ss":32,"used":true}]} +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135642.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*71 +$GNRMC,135642.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*7B +{"class":"TPV","tag":"RMC","time":1260021402.997,"ept":0.005,"lat":55.717211667,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.4*3E +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135643.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*70 +$GNRMC,135643.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*7A +{"class":"TPV","tag":"RMC","time":1260021403.997,"ept":0.005,"lat":55.717211667,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.4*3E +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135644.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*77 +$GNRMC,135644.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*7D +{"class":"TPV","tag":"RMC","time":1260021404.997,"ept":0.005,"lat":55.717211667,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.4*3E +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135645.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*76 +$GNRMC,135645.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*7C +{"class":"TPV","tag":"RMC","time":1260021405.997,"ept":0.005,"lat":55.717211667,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135646.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*75 +$GNRMC,135646.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*7F +{"class":"TPV","tag":"RMC","time":1260021406.997,"ept":0.005,"lat":55.717211667,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.1*3B +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135647.997,5543.0328,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*7B +$GNRMC,135647.997,A,5543.0328,N,03724.7197,E,00.00,129.5,051209,,,A*71 +{"class":"TPV","tag":"RMC","time":1260021407.997,"ept":0.005,"lat":55.717213333,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.4*3E +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,42,068,,19,58,270,34,21,16,107,,22,76,109,*77 +$GPGSV,4,3,14,26,42,127,,27,13,055,26,28,08,344,,33,11,238,*76 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +{"class":"SKY","tag":"GSV","xdop":14.63,"ydop":4.47,"vdop":37.14,"tdop":21.29,"hdop":15.30,"gdop":45.46,"pdop":40.16,"satellites":[{"PRN":3,"el":50,"az":217,"ss":0,"used":false},{"PRN":6,"el":49,"az":201,"ss":0,"used":false},{"PRN":9,"el":10,"az":68,"ss":0,"used":false},{"PRN":14,"el":30,"az":153,"ss":0,"used":false},{"PRN":18,"el":42,"az":68,"ss":0,"used":false},{"PRN":19,"el":58,"az":270,"ss":34,"used":false},{"PRN":21,"el":16,"az":107,"ss":0,"used":false},{"PRN":22,"el":76,"az":109,"ss":0,"used":false},{"PRN":26,"el":42,"az":127,"ss":0,"used":false},{"PRN":27,"el":13,"az":55,"ss":26,"used":false},{"PRN":28,"el":8,"az":344,"ss":0,"used":false},{"PRN":33,"el":11,"az":238,"ss":0,"used":false},{"PRN":37,"el":25,"az":199,"ss":0,"used":false},{"PRN":39,"el":25,"az":194,"ss":0,"used":false}]} +$GLGSV,2,1,06,66,18,048,,67,72,050,31,75,16,358,38,82,47,171,*68 +$GLGSV,2,2,06,83,66,291,37,84,17,325,34*6F +{"class":"SKY","tag":"GSV","xdop":1.84,"ydop":1.12,"vdop":2.42,"tdop":1.78,"hdop":2.15,"gdop":3.69,"pdop":3.23,"satellites":[{"PRN":66,"el":18,"az":48,"ss":0,"used":false},{"PRN":67,"el":72,"az":50,"ss":31,"used":true},{"PRN":75,"el":16,"az":358,"ss":38,"used":true},{"PRN":82,"el":47,"az":171,"ss":0,"used":false},{"PRN":83,"el":66,"az":291,"ss":37,"used":true},{"PRN":84,"el":17,"az":325,"ss":34,"used":true}]} +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135648.997,5543.0327,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*7B +$GNRMC,135648.997,A,5543.0327,N,03724.7197,E,00.00,129.5,051209,,,A*71 +{"class":"TPV","tag":"RMC","time":1260021408.997,"ept":0.005,"lat":55.717211667,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.3*39 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135649.997,5543.0328,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*75 +$GNRMC,135649.997,A,5543.0328,N,03724.7197,E,00.00,129.5,051209,,,A*7F +{"class":"TPV","tag":"RMC","time":1260021409.997,"ept":0.005,"lat":55.717213333,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.3*39 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGBS,135649.997,17.2,17.1,1.0,,,,*66 +{"class":"TPV","tag":"GBS","time":1260021409.997,"ept":0.005,"lat":55.717213333,"lon":37.411995000,"alt":165.600,"epx":17.100,"epy":17.200,"epv":1.000,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$GNGGA,135650.997,5543.0328,N,03724.7197,E,1,06,01.8,165.6,M,14.6,M,,*7D +$GNRMC,135650.997,A,5543.0328,N,03724.7197,E,00.00,129.5,051209,,,A*77 +{"class":"TPV","tag":"RMC","time":1260021410.997,"ept":0.005,"lat":55.717213333,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":44.73,"mode":3} +$PORZD,A,024.2*38 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135651.997,5543.0328,N,03724.7198,E,1,06,01.8,165.6,M,14.6,M,,*73 +$GNRMC,135651.997,A,5543.0328,N,03724.7198,E,00.00,129.5,051209,,,A*79 +{"class":"TPV","tag":"RMC","time":1260021411.997,"ept":0.005,"lat":55.717213333,"lon":37.411996667,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.2*38 +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135652.997,5543.0328,N,03724.7198,E,1,06,01.8,165.6,M,14.6,M,,*70 +$GNRMC,135652.997,A,5543.0328,N,03724.7198,E,00.00,129.5,051209,,,A*7A +{"class":"TPV","tag":"RMC","time":1260021412.997,"ept":0.005,"lat":55.717213333,"lon":37.411996667,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.5*3F +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135653.997,5543.0328,N,03724.7198,E,1,06,01.8,165.6,M,14.6,M,,*71 +$GNRMC,135653.997,A,5543.0328,N,03724.7198,E,00.00,129.5,051209,,,A*7B +{"class":"TPV","tag":"RMC","time":1260021413.997,"ept":0.005,"lat":55.717213333,"lon":37.411996667,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.4*3E +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,42,068,,19,58,270,36,21,16,107,,22,76,109,*75 +$GPGSV,4,3,14,26,42,127,,27,13,055,25,28,08,344,22,33,11,238,*75 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +{"class":"SKY","tag":"GSV","xdop":14.63,"ydop":4.47,"vdop":37.14,"tdop":21.29,"hdop":15.30,"gdop":45.46,"pdop":40.16,"satellites":[{"PRN":3,"el":50,"az":217,"ss":0,"used":false},{"PRN":6,"el":49,"az":201,"ss":0,"used":false},{"PRN":9,"el":10,"az":68,"ss":0,"used":false},{"PRN":14,"el":30,"az":153,"ss":0,"used":false},{"PRN":18,"el":42,"az":68,"ss":0,"used":false},{"PRN":19,"el":58,"az":270,"ss":36,"used":false},{"PRN":21,"el":16,"az":107,"ss":0,"used":false},{"PRN":22,"el":76,"az":109,"ss":0,"used":false},{"PRN":26,"el":42,"az":127,"ss":0,"used":false},{"PRN":27,"el":13,"az":55,"ss":25,"used":false},{"PRN":28,"el":8,"az":344,"ss":22,"used":false},{"PRN":33,"el":11,"az":238,"ss":0,"used":false},{"PRN":37,"el":25,"az":199,"ss":0,"used":false},{"PRN":39,"el":25,"az":194,"ss":0,"used":false}]} +$GLGSV,2,1,06,66,18,048,,67,72,050,32,75,16,358,39,82,47,171,*6A +$GLGSV,2,2,06,83,66,291,37,84,17,325,34*6F +{"class":"SKY","tag":"GSV","xdop":1.84,"ydop":1.12,"vdop":2.42,"tdop":1.78,"hdop":2.15,"gdop":3.69,"pdop":3.23,"satellites":[{"PRN":66,"el":18,"az":48,"ss":0,"used":false},{"PRN":67,"el":72,"az":50,"ss":32,"used":true},{"PRN":75,"el":16,"az":358,"ss":39,"used":true},{"PRN":82,"el":47,"az":171,"ss":0,"used":false},{"PRN":83,"el":66,"az":291,"ss":37,"used":true},{"PRN":84,"el":17,"az":325,"ss":34,"used":true}]} +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GLGGA,135654.997,5543.0328,N,03724.7197,E,1,04,02.3,165.6,M,14.6,M,,*71 +$GLRMC,135654.997,A,5543.0328,N,03724.7197,E,00.00,129.5,051209,,,A*71 +{"class":"TPV","tag":"RMC","time":1260021414.997,"ept":0.005,"lat":55.717213333,"lon":37.411995000,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,027.0*39 +$GLGSA,A,2,67,84,83,75,,,,,,,,,02.5,02.3,01.0*1C +$GNGGA,135655.997,5543.0328,N,03724.7199,E,1,06,01.8,165.6,M,14.6,M,,*76 +$GNRMC,135655.997,A,5543.0328,N,03724.7199,E,00.00,129.5,051209,,,A*7C +{"class":"TPV","tag":"RMC","time":1260021415.997,"ept":0.005,"lat":55.717213333,"lon":37.411998333,"alt":165.600,"epx":27.527,"epy":16.729,"epv":23.000,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.5*3F +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135656.997,5543.0329,N,03724.7201,E,1,06,01.8,165.6,M,14.6,M,,*76 +$GNRMC,135656.997,A,5543.0329,N,03724.7201,E,00.00,129.5,051209,,,A*7C +{"class":"TPV","tag":"RMC","time":1260021416.997,"ept":0.005,"lat":55.717215000,"lon":37.412001667,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":129.5000,"speed":0.000,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,024.5*3F +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GNGGA,135657.997,5543.0328,N,03724.7204,E,1,06,01.8,165.6,M,14.6,M,,*73 +$GNRMC,135657.997,A,5543.0328,N,03724.7204,E,00.79,159.0,051209,,,A*75 +{"class":"TPV","tag":"RMC","time":1260021417.997,"ept":0.005,"lat":55.717213333,"lon":37.412006667,"alt":165.600,"epx":27.527,"epy":16.729,"epv":20.700,"track":159.0000,"speed":0.406,"climb":0.000,"eps":55.05,"mode":3} +$PORZD,A,025.7*3C +$GNGSA,A,2,19,27,,,,,,,,,,,02.1,01.8,00.9*13 +$GNGSA,A,2,67,84,83,75,,,,,,,,,02.1,01.8,00.9*1A +$GPGGA,135658.997,5543.0326,N,03724.7205,E,0,,,165.6,M,14.6,M,,*7D +$GPRMC,135658.997,V,5543.0326,N,03724.7205,E,00.79,159.0,051209,,,N*73 +$PORZD,V,026.0*2F +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGGA,135659.997,5543.0324,N,03724.7207,E,0,,,165.6,M,14.6,M,,*7C +$GPRMC,135659.997,V,5543.0324,N,03724.7207,E,00.79,159.0,051209,,,N*72 +$PORZD,V,029.8*28 +$GPGSV,4,1,14,03,50,217,,06,49,201,,09,10,068,,14,30,153,*74 +$GPGSV,4,2,14,18,42,068,,19,58,270,,21,16,107,,22,76,109,*70 +$GPGSV,4,3,14,26,42,127,,27,13,055,,28,08,344,,33,11,238,*72 +$GPGSV,4,4,14,37,25,199,,39,25,194,*7F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":3,"el":50,"az":217,"ss":0,"used":false},{"PRN":6,"el":49,"az":201,"ss":0,"used":false},{"PRN":9,"el":10,"az":68,"ss":0,"used":false},{"PRN":14,"el":30,"az":153,"ss":0,"used":false},{"PRN":18,"el":42,"az":68,"ss":0,"used":false},{"PRN":19,"el":58,"az":270,"ss":0,"used":false},{"PRN":21,"el":16,"az":107,"ss":0,"used":false},{"PRN":22,"el":76,"az":109,"ss":0,"used":false},{"PRN":26,"el":42,"az":127,"ss":0,"used":false},{"PRN":27,"el":13,"az":55,"ss":0,"used":false},{"PRN":28,"el":8,"az":344,"ss":0,"used":false},{"PRN":33,"el":11,"az":238,"ss":0,"used":false},{"PRN":37,"el":25,"az":199,"ss":0,"used":false},{"PRN":39,"el":25,"az":194,"ss":0,"used":false}]} +$GLGSV,2,1,06,66,18,048,,67,72,050,,75,16,358,26,82,47,171,*65 +$GLGSV,2,2,06,83,66,291,,84,17,325,22*6C +{"class":"SKY","tag":"GSV","satellites":[{"PRN":66,"el":18,"az":48,"ss":0,"used":false},{"PRN":67,"el":72,"az":50,"ss":0,"used":false},{"PRN":75,"el":16,"az":358,"ss":26,"used":false},{"PRN":82,"el":47,"az":171,"ss":0,"used":false},{"PRN":83,"el":66,"az":291,"ss":0,"used":false},{"PRN":84,"el":17,"az":325,"ss":22,"used":false}]} +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGBS,135659.997,,,,,,,*55 +$GPGGA,135700.997,5543.0322,N,03724.7208,E,0,,,165.6,M,14.6,M,,*78 +$GPRMC,135700.997,V,5543.0322,N,03724.7208,E,00.79,159.0,051209,,,N*76 +$PORZD,V,037.1*2E +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGGA,135701.997,5543.0320,N,03724.7210,E,0,,,165.6,M,14.6,M,,*72 +$GPRMC,135701.997,V,5543.0320,N,03724.7210,E,00.79,159.0,051209,,,N*7C +$PORZD,V,048.0*27 +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGGA,135702.997,5543.0318,N,03724.7211,E,0,,,165.6,M,14.6,M,,*7B +$GPRMC,135702.997,V,5543.0318,N,03724.7211,E,00.79,159.0,051209,,,N*75 +$PORZD,V,062.4*2B +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGGA,135703.997,5543.0316,N,03724.7212,E,0,,,165.6,M,14.6,M,,*77 +$GPRMC,135703.997,V,5543.0316,N,03724.7212,E,00.79,159.0,051209,,,N*79 +$PORZD,V,080.3*20 +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 +$GPGGA,135704.997,5543.0314,N,03724.7214,E,0,,,165.6,M,14.6,M,,*74 +$GPRMC,135704.997,V,5543.0314,N,03724.7214,E,00.79,159.0,051209,,,N*7A +$PORZD,V,101.8*23 +$GPGSA,A,1,,,,,,,,,,,,,00.0,00.0,00.0*00 diff --git a/test/daemon/com-1289.log b/test/daemon/com-1289.log new file mode 100644 index 0000000..02c24b3 --- /dev/null +++ b/test/daemon/com-1289.log @@ -0,0 +1,416 @@ +# Name: Eurotech Com-1289 +# Chipset: Fastrax iTrax03 +# Submitted-by: Simon Le Pape +# Date: 10 Dec 2007 +# Location: Rennes, Ile-etVilaine, France +# Documentation says this chip emits ZDA and RMC in that order. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,35,05,16,114,43,06,65,063,50,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,43,153,53,23,12,316,51*72 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,47*4A +$GPRMC,143748.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*0A +$GPGGA,143748.77,4806.3731,N,00138.6217,W,1,10,1.1,42.2,M,48.5,M,,*4B +$PFST,FOM,6*63 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,35,05,16,114,43,06,65,063,50,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,43,153,53,23,12,316,51*7C +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,47*4A +$GPRMC,143749.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*0B +$GPGGA,143749.77,4806.3731,N,00138.6217,W,1,10,1.1,42.2,M,48.5,M,,*4A +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,42,06,65,063,50,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,43,153,53,23,12,316,51*72 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,47*4A +$GPRMC,143750.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*03 +$GPGGA,143750.77,4806.3731,N,00138.6217,W,1,10,1.0,42.2,M,48.5,M,,*43 +$PFST,FOM,6*63 +$GPGSA,A,3,01,05,06,07,16,21,23,24,30,31,,,1.5,1.0,1.2*33 +$GPGSV,3,1,11,01,06,230,34,05,16,114,42,06,65,063,50,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,43,153,53,23,12,316,51*72 +$GPGSV,3,3,11,24,51,098,,110,50,31,60,230,46*4B +$GPRMC,143751.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*02 +$GPGGA,143751.77,4806.3731,N,00138.6217,W,1,10,1.3,42.2,M,48.5,M,,*41 +$PFST,FOM,6*63 +$GPGSA,A,3,01,05,06,07,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,35,05,16,114,42,06,65,063,50,07,72,061,47*78 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,43,153,53,23,12,316,51*72 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,46*4B +$GPRMC,143752.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*01 +$GPGGA,143752.77,4806.3731,N,00138.6217,W,1,10,1.1,42.1,M,48.5,M,,*43 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,35,05,16,114,42,06,65,063,50,07,72,061,47*78 +$GPGSV,3,2,11,10,09,057,41,16,35,295,48,21,44,152,53,23,12,316,51*75 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,46*4B +$GPRMC,143753.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*00 +$GPGGA,143753.77,4806.3731,N,00138.6217,W,1,10,1.1,42.2,M,48.5,M,,*41 +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,42,06,65,063,50,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,41,16,35,295,48,21,44,152,53,23,12,316,51*75 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,46*4B +$GPRMC,143754.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*07 +$GPGGA,143754.77,4806.3731,N,00138.6217,W,1,10,1.1,42.1,M,48.5,M,,*45 +$PFST,FOM,2*67 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,41,06,65,063,50,07,72,061,47*7A +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,51*74 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,47*4A +$GPRMC,143755.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*06 +$GPGGA,143755.77,4806.3731,N,00138.6217,W,1,10,1.1,42.1,M,48.5,M,,*44 +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,41,06,65,063,49,07,72,061,47*72 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,51*74 +$GPGSV,3,3,11,24,51,097,55,30,33,110,51,31,60,230,47*44 +$GPRMC,143756.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*05 +$GPGGA,143756.77,4806.3731,N,00138.6217,W,1,10,1.1,42.1,M,48.5,M,,*47 +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,33,05,16,114,42,06,65,063,49,07,72,061,47*76 +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,44,152,53,23,12,316,51*7A +$GPGSV,3,3,11,24,51,097,54,30,33,110,50,31,60,230,47*44 +$GPRMC,143757.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*04 +$GPGGA,143757.77,4806.3731,N,00138.6217,W,1,10,1.3,42.1,M,48.5,M,,*44 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,33,05,16,114,42,06,65,063,49,07,72,061,47*76 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,51*7B +$GPGSV,3,3,11,24,51,097,54,30,33,110,50,31,60,230,47*44 +$GPRMC,143758.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*0B +$GPGGA,143758.77,4806.3731,N,00138.6217,W,1,09,1.3,42.1,M,48.5,M,,*43 +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,32,05,16,114,42,06,65,063,49,07,72,061,46*76 +$GPGSV,3,2,11,10,09,057,37,16,35,295,48,21,44,152,53,23,12,316,51*74 +$GPGSV,3,3,11,24,51,097,54,30,33,110,50,31,60,230,47*44 +$GPRMC,143759.77,A,4806.3731,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*0B +$GPGGA,143759.77,4806.3731,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*43 +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,2.2,1.3,1.7*30 +$GPGSV,3,1,11,01,06,230,32,05,16,114,42,06,65,063,49,07,72,061,46*76 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,51*7B +$GPGSV,3,3,11,24,51,097,54,30,33,110,50,31,60,230,47*44 +$GPRMC,143800.77,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*0B +$GPGGA,143800.77,4806.3732,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*43 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,31,05,16,114,42,06,65,063,49,07,72,061,46*75 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,51*7B +$GPGSV,3,3,11,24,51,097,54,30,33,110,50,31,60,230,46*45 +$GPRMC,143801.77,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*0A +$GPGGA,143801.77,4806.3732,N,00138.6216,W,1,10,1.7,42.1,M,48.5,M,,*4E +$PFST,FOM,7*62 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,2.4,1.7,1.6*32 +$GPGSV,3,1,11,01,06,230,32,05,16,114,43,06,65,063,49,07,72,061,46*77 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,51*7B +$GPGSV,3,3,11,24,51,097,54,30,32,110,50,31,60,230,46*44 +$GPRMC,143802.77,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*09 +$GPGGA,143802.77,4806.3732,N,00138.6216,W,1,09,1.7,42.1,M,48.5,M,,*45 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,,,,2.4,1.7,1.6*30 +$GPGSV,3,1,11,01,06,230,32,05,16,114,43,06,65,063,49,07,72,061,47*76 +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,44,152,53,23,12,316,51*7A +$GPGSV,3,3,11,24,51,097,54,30,32,110,50,31,60,229,46*4C +$GPRMC,143803.77,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*08 +$GPGGA,143803.77,4806.3732,N,00138.6216,W,1,11,1.1,42.1,M,48.5,M,,*4B +$PFST,FOM,8*6D +$GPGSA,A,3,01,05,06,07,10,16,21,23,24,30,31,,1.7,1.1,1.2*31 +$GPGSV,3,1,11,01,06,230,32,05,16,114,44,06,65,063,49,07,72,061,47*71 +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,44,152,53,23,12,316,52*79 +$GPGSV,3,3,11,24,51,097,55,30,32,110,50,31,60,229,46*4D +$GPRMC,143804.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*00 +$GPGGA,143804.78,4806.3732,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*48 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,33,05,16,114,44,06,65,063,49,07,72,061,47*70 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,52*77 +$GPGSV,3,3,11,24,51,097,55,30,32,110,50,31,60,229,46*4D +$GPRMC,143805.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*01 +$GPGGA,143805.78,4806.3732,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*49 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,00,05,16,114,44,06,65,063,49,07,72,061,47*70 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,51*74 +$GPGSV,3,3,11,24,51,097,55,30,32,110,50,31,60,229,46*4D +$GPRMC,143806.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*02 +$GPGGA,143806.78,4806.3732,N,00138.6216,W,1,10,1.1,42.1,M,48.5,M,,*40 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,13,05,16,114,44,06,65,063,49,07,72,061,47*72 +$GPGSV,3,2,11,10,09,057,41,16,35,295,48,21,44,152,53,23,12,316,52*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,50,31,60,229,46*4D +$GPRMC,143807.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*03 +$GPGGA,143807.78,4806.3732,N,00138.6216,W,1,10,1.1,42.1,M,48.5,M,,*41 +$PFST,FOM,6*63 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,30,05,16,114,44,06,65,063,49,07,72,061,47*73 +$GPGSV,3,2,11,10,09,057,41,16,35,295,48,21,44,152,53,23,12,316,52*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,50,31,60,229,46*4D +$GPRMC,143808.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*0C +$GPGGA,143808.78,4806.3732,N,00138.6216,W,1,10,1.1,42.1,M,48.5,M,,*4E +$PFST,FOM,6*63 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,33,05,16,114,43,06,65,063,49,07,72,061,47*77 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,51*74 +$GPGSV,3,3,11,24,51,097,55,30,32,110,51,31,60,229,47*4D +$GPRMC,143809.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*0D +$GPGGA,143809.78,4806.3732,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*45 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,2.2,1.3,1.7*30 +$GPGSV,3,1,11,01,06,230,33,05,16,114,45,06,65,063,49,07,72,061,47*71 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,52*78 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,46*4D +$GPRMC,143810.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*05 +$GPGGA,143810.78,4806.3732,N,00138.6216,W,1,10,1.0,42.1,M,48.5,M,,*46 +$PFST,FOM,6*63 +$GPGSA,A,3,01,05,06,07,16,21,23,24,30,31,,,1.5,1.0,1.2*33 +$GPGSV,3,1,11,01,06,230,36,05,16,114,44,06,65,063,49,07,72,061,47*75 +$GPGSV,3,2,11,10,09,057,37,16,35,295,49,21,44,152,53,23,12,316,52*76 +$GPGSV,3,3,11,24,51,097,53,30,32,110,51,31,60,229,46*4A +$GPRMC,143811.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*04 +$GPGGA,143811.78,4806.3732,N,00138.6216,W,1,10,1.3,42.1,M,48.5,M,,*44 +$PFST,FOM,7*62 +$GPGSA,A,3,01,05,06,07,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,38,05,16,114,42,06,65,063,49,07,72,061,47*7D +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,51*7B +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,46*4D +$GPRMC,143812.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*07 +$GPGGA,143812.78,4806.3732,N,00138.6216,W,1,11,1.3,42.1,M,48.5,M,,*46 +$PFST,FOM,7*62 +$GPGSA,A,3,01,05,06,07,10,16,21,23,24,30,31,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,39,05,16,114,43,06,65,063,48,07,72,061,47*7C +$GPGSV,3,2,11,10,09,057,37,16,35,295,48,21,44,152,52,23,12,316,52*76 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,47*4C +$GPRMC,143813.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*06 +$GPGGA,143813.78,4806.3732,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*4E +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,38,05,16,114,44,06,65,063,48,07,72,061,47*7A +$GPGSV,3,2,11,10,09,057,36,16,35,295,47,21,44,152,53,23,12,316,51*7A +$GPGSV,3,3,11,24,51,097,54,30,32,110,50,31,60,229,48*42 +$GPRMC,143814.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*01 +$GPGGA,143814.78,4806.3732,N,00138.6216,W,1,10,1.3,42.1,M,48.5,M,,*41 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,38,05,16,114,44,06,65,063,47,07,72,061,47*75 +$GPGSV,3,2,11,10,09,057,37,16,35,295,48,21,44,152,52,23,12,316,52*76 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,48*43 +$GPRMC,143815.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*00 +$GPGGA,143815.78,4806.3732,N,00138.6216,W,1,10,1.2,42.1,M,48.5,M,,*41 +$PFST,FOM,2*67 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.2,1.3*32 +$GPGSV,3,1,11,01,06,230,37,05,16,114,45,06,65,063,48,07,72,061,47*74 +$GPGSV,3,2,11,10,09,057,40,16,35,295,49,21,44,152,52,23,12,316,50*75 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,46*4D +$GPRMC,143816.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*03 +$GPGGA,143816.78,4806.3732,N,00138.6216,W,1,10,1.2,42.1,M,48.5,M,,*42 +$PFST,FOM,4*61 +$GPGSA,A,3,01,05,06,07,10,16,21,23,24,30,,,1.7,1.2,1.3*31 +$GPGSV,3,1,11,01,06,230,37,05,16,114,45,06,65,063,48,07,72,061,46*75 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,52*77 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,45*4E +$GPRMC,143817.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*02 +$GPGGA,143817.78,4806.3732,N,00138.6216,W,1,11,0.8,42.1,M,48.5,M,,*49 +$PFST,FOM,4*61 +$GPGSA,A,3,01,05,06,07,10,16,21,23,24,30,31,,1.3,0.8,1.0*3F +$GPGSV,3,1,11,01,06,230,34,05,16,114,44,06,65,063,48,07,72,061,46*77 +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,44,152,53,23,12,316,51*7A +$GPGSV,3,3,11,24,51,097,54,30,32,110,50,31,60,229,44*4E +$GPRMC,143818.78,A,4806.3728,N,00138.6239,W,1.56,266.1,121007,2.6,W,A*0D +$GPGGA,143818.78,4806.3728,N,00138.6239,W,1,10,1.3,41.5,M,48.5,M,,*4C +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,34,05,16,114,44,06,65,063,48,07,72,061,46*77 +$GPGSV,3,2,11,10,09,057,42,16,35,295,47,21,44,152,52,23,12,316,51*78 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,46*4D +$GPRMC,143819.79,A,4806.3729,N,00138.6247,W,0.00,266.1,121007,2.6,W,A*07 +$GPGGA,143819.79,4806.3729,N,00138.6247,W,1,10,1.1,41.4,M,48.5,M,,*47 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,00,05,16,114,44,06,65,063,48,07,72,061,46*70 +$GPGSV,3,2,11,10,09,057,39,16,35,295,49,21,44,152,52,23,12,316,51*7A +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,48*40 +$GPRMC,143820.79,A,4806.3730,N,00138.6251,W,0.00,266.1,121007,2.6,W,A*02 +$GPGGA,143820.79,4806.3730,N,00138.6251,W,1,10,1.2,41.4,M,48.5,M,,*41 +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.2,1.5*3A +$GPGSV,3,1,11,01,06,230,20,05,16,114,44,06,65,063,48,07,72,061,45*71 +$GPGSV,3,2,11,10,09,057,40,16,35,295,50,21,44,152,53,23,12,316,51*7D +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,47*4F +$GPRMC,143821.79,A,4806.3732,N,00138.6265,W,2.31,266.8,121007,2.6,W,A*0F +$GPGGA,143821.79,4806.3732,N,00138.6265,W,1,10,1.2,41.4,M,48.5,M,,*45 +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.2,1.5*3A +$GPGSV,3,1,11,01,06,230,34,05,16,114,45,06,65,063,48,07,72,061,46*76 +$GPGSV,3,2,11,10,09,057,40,16,35,295,50,21,44,152,53,23,12,316,51*7D +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,46*4E +$GPRMC,143822.79,A,4806.3731,N,00138.6276,W,2.58,266.3,121007,2.6,W,A*09 +$GPGGA,143822.79,4806.3731,N,00138.6276,W,1,10,1.2,41.4,M,48.5,M,,*47 +$PFST,FOM,2*67 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.2,1.3*32 +$GPGSV,3,1,1230,00,05,16,114,44,06,65,063,49,07,72,061,47*70 +$GPGSV,3,2,11,10,09,057,39,16,35,295,50,21,44,152,53,23,12,316,51*73 +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,45*4D +$GPRMC,143823.79,A,4806.3728,N,00138.6293,W,2.82,266.9,121007,2.6,W,A*06 +$GPGGA,143823.79,4806.3728,N,00138.6293,W,1,10,1.1,41.4,M,48.5,M,,*46 +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,17,05,16,114,45,06,65,063,49,07,72,061,47*77 +$GPGSV,3,2,11,10,09,057,42,16,35,295,49,21,44,152,52,23,12,316,51*76 +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,46*4E +$GPRMC,143824.79,A,4806.3727,N,00138.6306,W,3.10,266.8,121007,2.6,W,A*08 +$GPGGA,143824.79,4806.3727,N,00138.6306,W,1,10,1.1,41.4,M,48.5,M,,*43 +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,44,06,65,063,49,07,72,061,46*76 +$GPGSV,3,2,11,10,09,057,42,16,35,295,50,21,44,152,52,23,12,316,50*7F +$GPGSV,3,3,11,24,51,097,55,30,32,110,51,31,60,229,47*4D +$GPRMC,143825.79,A,4806.3725,N,00138.6321,W,3.34,267.0,121007,2.6,W,A*01 +$GPGGA,143825.79,4806.3725,N,00138.6321,W,1,10,0.9,41.4,M,48.5,M,,*4C +$PFST,FOM,4*61 +$GPGSA,A,3,01,06,07,10,16,21,23,24,30,31,,,1.4,0.9,1.1*3D +$GPGSV,3,1,11,01,06,230,35,05,16,114,45,06,65,063,48,07,72,061,48*79 +$GPGSV,3,2,11,10,09,057,43,16,35,295,48,21,44,152,52,23,12,316,51*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,46*4E +$GPRMC,143826.79,A,4806.3724,N,00138.6335,W,3.61,266.8,121007,2.6,W,A*0F +$GPGGA,143826.79,4806.3724,N,00138.6335,W,1,10,1.1,41.4,M,48.5,M,,*42 +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,38,05,16,114,46,06,65,063,49,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,42,16,35,295,49,21,44,152,53,23,12,316,50*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,52,31,60,229,46*4F +$GPRMC,143827.79,A,4806.3724,N,00138.6352,W,3.85,267.0,121007,2.6,W,A*0C +$GPGGA,143827.79,4806.3724,N,00138.6352,W,1,10,1.1,41.4,M,48.5,M,,*42 +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,37,05,16,114,46,06,65,063,49,07,72,061,46*77 +$GPGSV,3,2,11,10,09,057,43,16,35,295,49,21,44,152,52,23,12,316,49*7E +$GPGSV,3,3,11,24,51,097,55,30,32,110,52,31,60,229,47*4E +$GPRMC,143828.79,A,4806.3725,N,00138.6368,W,4.12,266.8,121007,2.6,W,A*0B +$GPGGA,143828.79,4806.3725,N,00138.6368,W,1,11,0.8,41.4,M,48.5,M,,*4C +$PFST,FOM,4*61 +$GPGSA,A,3,01,05,06,07,10,16,21,23,24,30,31,,1.3,0.8,1.0*3F +$GPGSV,3,1,11,01,06,230,36,05,16,114,46,06,65,063,49,07,72,061,48*78 +$GPGSV,3,2,11,10,09,057,42,16,35,295,49,21,44,152,51,23,12,316,49*7C +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,47*4F +$GPRMC,143829.79,A,4806.3724,N,00138.6386,W,4.39,266.7,121007,2.6,W,A*0D +$GPGGA,143829.79,4806.3724,N,00138.6386,W,1,10,1.1,41.4,M,48.5,M,,*45 +$PFST,FOM,2*67 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,35,05,16,114,45,06,65,063,49,07,72,061,47*77 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,52,23,12,316,50*74 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,47*4C +$GPRMC,143830.79,A,4806.3723,N,00138.6405,W,4.66,266.3,121007,2.6,W,A*00 +$GPGGA,143830.79,4806.3723,N,00138.6405,W,1,10,1.1,41.4,M,48.5,M,,*46 +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,37,05,16,114,45,06,65,063,48,07,72,061,48*7B +$GPGSV,3,2,11,10,09,057,41,16,35,295,47,21,44,152,53,23,12,316,46*7C +$GPGSV,3,3,11,24,51,097,55,30,32,110,51,31,60,229,47*4D +$GPRMC,143831.79,A,4806.3723,N,00138.6424,W,4.91,266.5,121007,2.6,W,A*0C +$GPGGA,143831.79,4806.3723,N,00138.6424,W,1,10,1.3,41.4,M,48.5,M,,*46 +$PFST,FOM,7*62 +$GPGSA,A,3,01,05,06,07,16,21,23,24,30,31,,,1.9,1.3,1.4*3A +$GPGSV,3,1,11,01,06,230,38,05,16,114,45,06,65,063,48,07,72,061,47*7B +$GPGSV,3,2,11,10,09,057,38,16,35,295,46,21,44,152,53,23,12,316,43*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,51,31,60,229,47*4D +$GPRMC,143832.79,A,4806.3723,N,00138.6444,W,5.05,266.3,121007,2.6,W,A*03 +$GPGGA,143832.79,4806.3723,N,00138.6444,W,1,10,1.4,41.4,M,48.5,M,,*44 +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,2.0,1.4,1.4*37 +$GPGSV,3,1,11,01,06,230,37,05,16,114,44,06,65,063,48,07,72,061,48*7A +$GPGSV,3,2,11,10,09,057,37,16,35,295,47,21,44,152,53,23,12,316,44*7F +$GPGSV,3,3,11,24,51,097,55,30,32,110,52,31,60,229,47*4E +$GPRMC,143833.79,A,4806.3721,N,00138.6464,W,5.13,265.8,121007,2.6,W,A*0D +$GPGGA,143833.79,4806.3721,N,00138.6464,W,1,09,1.3,41.4,M,48.5,M,,*4A +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,38,05,16,114,43,06,65,063,48,07,72,061,48*72 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,52,23,12,316,46*7C +$GPGSV,3,3,11,24,51,097,55,30,32,110,52,31,60,229,47*4E +$GPRMC,143834.80,A,4806.3719,N,00138.6484,W,5.21,266.1,121007,2.6,W,A*02 +$GPGGA,143834.80,4806.3719,N,00138.6484,W,1,09,1.5,41.3,M,48.5,M,,*4F +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,2.3,1.5,1.8*38 +$GPGSV,3,1,11,01,06,230,36,05,16,114,44,06,65,063,48,07,72,061,48*7B +$GPGSV,3,2,11,10,09,057,38,16,35,295,47,21,44,152,52,23,12,316,43*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,48*40 +$GPRMC,143835.80,A,4806.3719,N,00138.6509,W,5.31,265.1,121007,2.6,W,A*05 +$GPGGA,143835.80,4806.3719,N,00138.6509,W,1,10,1.1,41.3,M,48.5,M,,*46 +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,36,05,16,114,42,06,65,063,48,07,72,061,48*7D +$GPGSV,3,2,11,10,09,057,39,16,35,295,47,21,44,152,52,23,12,316,48*7C +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,47*4F +$GPRMC,143836.80,A,4806.3718,N,00138.6527,W,5.42,264.6,121007,2.6,W,A*09 +$GPGGA,143836.80,4806.3718,N,00138.6527,W,1,10,1.2,41.4,M,48.5,M,,*4C +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.2,1.5*3A +$GPGSV,3,1,11,01,06,230,34,05,16,114,42,06,65,063,48,07,72,061,48*7F +$GPGSV,3,2,11,10,09,057,38,16,35,295,47,21,44,152,52,23,12,316,45*70 +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,47*4F +$GPRMC,143837.80,A,4806.3716,N,00138.6546,W,5.53,264.3,121007,2.6,W,A*04 +$GPGGA,143837.80,4806.3716,N,00138.6546,W,1,10,1.3,41.4,M,48.5,M,,*45 +$PFST,FOM,7*62 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,34,05,16,114,46,06,65,063,47,07,72,061,47*7B +$GPGSV,3,2,11,10,09,057,37,16,35,295,48,21,44,152,52,23,12,316,44*71 +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,47*4F +$GPRMC,143838.80,A,4806.3716,N,00138.6569,W,5.64,264.4,121007,2.6,W,A*05 +$GPGGA,143838.80,4806.3716,N,00138.6569,W,1,10,1.1,41.4,M,48.5,M,,*45 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,00,05,16,114,47,06,65,063,47,07,72,061,47*7D +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,52,23,12,316,47*7D +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,48*40 +$GPRMC,143839.80,A,4806.3715,N,00138.6593,W,5.74,264.1,121007,2.6,W,A*06 +$GPGGA,143839.80,4806.3715,N,00138.6593,W,1,09,1.3,41.5,M,48.5,M,,*49 +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,12,05,16,114,46,06,65,063,48,07,72,061,47*70 +$GPGSV,3,2,11,10,09,057,35,16,35,295,47,21,44,152,52,23,12,316,48*70 +$GPGSV,3,3,11,24,51,097,54,30,32,110,53,31,60,229,48*41 +$GPRMC,143840.80,A,4806.3715,N,00138.6618,W,5.91,263.8,121007,2.6,W,A*0D +$GPGGA,143840.80,4806.3715,N,00138.6618,W,1,10,1.4,41.4,M,48.5,M,,*49 +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,2.1,1.4,1.5*37 +$GPGSV,3,1,11,01,06,230,31,05,16,114,46,06,65,063,47,07,72,061,47*7E +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,51,23,12,316,48*71 +$GPGSV,3,3,11,24,51,097,54,30,32,110,53,31,60,229,48*41 +$GPRMC,143841.80,A,4806.3713,N,00138.6642,W,6.07,263.1,121007,2.6,W,A*00 +$GPGGA,143841.80,4806.3713,N,00138.6642,W,1,10,1.6,41.5,M,48.5,M,,*42 +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,2.5,1.6,1.9*3D +$GPGSV,3,1,11,01,06,230,32,05,16,114,47,06,65,063,47,07,72,061,46*7D +$GPGSV,3,2,11,10,09,057,41,16,35,295,49,21,44,152,50,23,12,316,48*7F +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,48*40 +$GPRMC,143842.80,A,4806.3713,N,00138.6667,W,6.33,262.2,121007,2.6,W,A*01 +$GPGGA,143842.80,4806.3713,N,00138.6667,W,1,10,1.1,41.5,M,48.5,M,,*41 +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,32,05,16,114,45,06,65,063,47,07,72,061,46*7F +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,44,152,51,23,12,316,48*70 +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,48*40 +$GPRMC,143843.80,A,4806.3711,N,00138.6694,W,6.52,261.1,121007,2.6,W,A*09 +$GPGGA,143843.80,4806.3711,N,00138.6694,W,1,10,1.1,41.5,M,48.5,M,,*4E +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,44,06,65,063,47,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,50,23,12,316,48*70 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,49*42 +$GPRMC,143844.80,A,4806.3707,N,00138.6723,W,6.72,261.3,121007,2.6,W,A*04 +$GPGGA,143844.80,4806.3707,N,00138.6723,W,1,10,1.1,41.6,M,48.5,M,,*40 +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,33,05,16,114,48,06,65,063,48,07,72,061,47*7D +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,50,23,12,316,47*70 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,48*43 +$GPRMC,143845.80,A,4806.3705,N,00138.6753,W,6.92,261.2,121007,2.6,W,A*0F +$GPGGA,143845.80,4806.3705,N,00138.6753,W,1,10,1.1,41.7,M,48.5,M,,*45 +$PFST,FOM,3*66 diff --git a/test/daemon/com-1289.log.chk b/test/daemon/com-1289.log.chk new file mode 100644 index 0000000..3c13480 --- /dev/null +++ b/test/daemon/com-1289.log.chk @@ -0,0 +1,522 @@ +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +{"class":"TPV","tag":"GSA","epv":27.600,"mode":3} +$GPGSV,3,1,11,01,06,230,35,05,16,114,43,06,65,063,50,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,43,153,53,23,12,316,51*72 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,47*4A +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.71,"vdop":1.09,"tdop":0.63,"hdop":0.88,"gdop":1.54,"pdop":1.41,"satellites":[{"PRN":1,"el":6,"az":230,"ss":35,"used":false},{"PRN":5,"el":16,"az":114,"ss":43,"used":true},{"PRN":6,"el":65,"az":63,"ss":50,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":43,"az":153,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":98,"ss":55,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":47,"used":true}]} +$GPRMC,143748.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*0A +{"class":"TPV","tag":"RMC","time":1192199868.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"epx":7.849,"epy":10.678,"track":266.5000,"speed":0.000,"mode":2} +$GPGGA,143748.77,4806.3731,N,00138.6217,W,1,10,1.1,42.2,M,48.5,M,,*4B +{"class":"TPV","tag":"GGA","time":1192199868.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.200,"epx":7.849,"epy":10.678,"epv":25.142,"track":266.5000,"speed":0.000,"mode":3} +$PFST,FOM,6*63 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +{"class":"TPV","tag":"GSA","time":1192199868.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.200,"epx":7.849,"epy":10.678,"epv":25.142,"track":266.5000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,3,1,11,01,06,230,35,05,16,114,43,06,65,063,50,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,43,153,53,23,12,316,51*7C +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,47*4A +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.71,"vdop":1.09,"tdop":0.63,"hdop":0.88,"gdop":1.54,"pdop":1.41,"satellites":[{"PRN":1,"el":6,"az":230,"ss":35,"used":false},{"PRN":5,"el":16,"az":114,"ss":43,"used":true},{"PRN":6,"el":65,"az":63,"ss":50,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":39,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":43,"az":153,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":98,"ss":55,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":47,"used":true}]} +$GPRMC,143749.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*0B +$GPGGA,143749.77,4806.3731,N,00138.6217,W,1,10,1.1,42.2,M,48.5,M,,*4A +{"class":"TPV","tag":"GGA","time":1192199869.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.200,"epx":7.849,"epy":10.678,"epv":25.142,"track":266.5000,"speed":0.000,"eps":21.36,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,42,06,65,063,50,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,43,153,53,23,12,316,51*72 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,47*4A +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.71,"vdop":1.09,"tdop":0.63,"hdop":0.88,"gdop":1.54,"pdop":1.41,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":50,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":43,"az":153,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":98,"ss":55,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":47,"used":true}]} +$GPRMC,143750.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*03 +$GPGGA,143750.77,4806.3731,N,00138.6217,W,1,10,1.0,42.2,M,48.5,M,,*43 +{"class":"TPV","tag":"GGA","time":1192199870.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.200,"epx":7.849,"epy":10.678,"epv":25.142,"track":266.5000,"speed":0.000,"eps":21.36,"mode":3} +$PFST,FOM,6*63 +$GPGSA,A,3,01,05,06,07,16,21,23,24,30,31,,,1.5,1.0,1.2*33 +$GPGSV,3,1,11,01,06,230,34,05,16,114,42,06,65,063,50,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,43,153,53,23,12,316,51*72 +$GPRMC,143751.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*02 +$GPGGA,143751.77,4806.3731,N,00138.6217,W,1,10,1.3,42.2,M,48.5,M,,*41 +{"class":"TPV","tag":"GGA","time":1192199871.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.200,"track":266.5000,"speed":0.000,"mode":3} +$PFST,FOM,6*63 +$GPGSA,A,3,01,05,06,07,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,35,05,16,114,42,06,65,063,50,07,72,061,47*78 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,43,153,53,23,12,316,51*72 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,46*4B +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.71,"vdop":1.09,"tdop":0.63,"hdop":0.88,"gdop":1.54,"pdop":1.41,"satellites":[{"PRN":1,"el":6,"az":230,"ss":35,"used":true},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":50,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":false},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":43,"az":153,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":98,"ss":55,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":46,"used":true}]} +$GPRMC,143752.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*01 +$GPGGA,143752.77,4806.3731,N,00138.6217,W,1,10,1.1,42.1,M,48.5,M,,*43 +{"class":"TPV","tag":"GGA","time":1192199872.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.100,"epx":7.849,"epy":10.678,"epv":25.142,"track":266.5000,"speed":0.000,"eps":21.36,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,35,05,16,114,42,06,65,063,50,07,72,061,47*78 +$GPGSV,3,2,11,10,09,057,41,16,35,295,48,21,44,152,53,23,12,316,51*75 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,46*4B +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.41,"satellites":[{"PRN":1,"el":6,"az":230,"ss":35,"used":false},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":50,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":41,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":98,"ss":55,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":46,"used":true}]} +$GPRMC,143753.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*00 +$GPGGA,143753.77,4806.3731,N,00138.6217,W,1,10,1.1,42.2,M,48.5,M,,*41 +{"class":"TPV","tag":"GGA","time":1192199873.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.200,"epx":7.850,"epy":10.734,"epv":25.086,"track":266.5000,"speed":0.000,"eps":21.41,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,42,06,65,063,50,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,41,16,35,295,48,21,44,152,53,23,12,316,51*75 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,46*4B +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.41,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":50,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":41,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":98,"ss":55,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":46,"used":true}]} +$GPRMC,143754.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*07 +$GPGGA,143754.77,4806.3731,N,00138.6217,W,1,10,1.1,42.1,M,48.5,M,,*45 +{"class":"TPV","tag":"GGA","time":1192199874.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.100,"epx":7.850,"epy":10.734,"epv":25.086,"track":266.5000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,2*67 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,41,06,65,063,50,07,72,061,47*7A +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,51*74 +$GPGSV,3,3,11,24,51,098,55,30,33,110,50,31,60,230,47*4A +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.41,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":41,"used":true},{"PRN":6,"el":65,"az":63,"ss":50,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":98,"ss":55,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":47,"used":true}]} +$GPRMC,143755.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*06 +$GPGGA,143755.77,4806.3731,N,00138.6217,W,1,10,1.1,42.1,M,48.5,M,,*44 +{"class":"TPV","tag":"GGA","time":1192199875.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.100,"epx":7.850,"epy":10.734,"epv":25.086,"track":266.5000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,41,06,65,063,49,07,72,061,47*72 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,51*74 +$GPGSV,3,3,11,24,51,097,55,30,33,110,51,31,60,230,47*44 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.41,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":41,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":33,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":230,"ss":47,"used":true}]} +$GPRMC,143756.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*05 +$GPGGA,143756.77,4806.3731,N,00138.6217,W,1,10,1.1,42.1,M,48.5,M,,*47 +{"class":"TPV","tag":"GGA","time":1192199876.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.100,"epx":7.848,"epy":10.736,"epv":25.088,"track":266.5000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,33,05,16,114,42,06,65,063,49,07,72,061,47*76 +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,44,152,53,23,12,316,51*7A +$GPGSV,3,3,11,24,51,097,54,30,33,110,50,31,60,230,47*44 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.41,"satellites":[{"PRN":1,"el":6,"az":230,"ss":33,"used":false},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":39,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":47,"used":true}]} +$GPRMC,143757.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*04 +$GPGGA,143757.77,4806.3731,N,00138.6217,W,1,10,1.3,42.1,M,48.5,M,,*44 +{"class":"TPV","tag":"GGA","time":1192199877.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.100,"epx":7.848,"epy":10.736,"epv":25.088,"track":266.5000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,33,05,16,114,42,06,65,063,49,07,72,061,47*76 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,51*7B +$GPGSV,3,3,11,24,51,097,54,30,33,110,50,31,60,230,47*44 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.41,"satellites":[{"PRN":1,"el":6,"az":230,"ss":33,"used":false},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":47,"used":true}]} +$GPRMC,143758.77,A,4806.3731,N,00138.6217,W,0.00,266.5,121007,2.6,W,A*0B +$GPGGA,143758.77,4806.3731,N,00138.6217,W,1,09,1.3,42.1,M,48.5,M,,*43 +{"class":"TPV","tag":"GGA","time":1192199878.770,"ept":0.005,"lat":48.106218333,"lon":-1.643695000,"alt":42.100,"epx":7.848,"epy":10.736,"epv":25.088,"track":266.5000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,32,05,16,114,42,06,65,063,49,07,72,061,46*76 +$GPGSV,3,2,11,10,09,057,37,16,35,295,48,21,44,152,53,23,12,316,51*74 +$GPGSV,3,3,11,24,51,097,54,30,33,110,50,31,60,230,47*44 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":32,"used":false},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":37,"used":false},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":47,"used":true}]} +$GPRMC,143759.77,A,4806.3731,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*0B +$GPGGA,143759.77,4806.3731,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*43 +{"class":"TPV","tag":"GGA","time":1192199879.770,"ept":0.005,"lat":48.106218333,"lon":-1.643693333,"alt":42.100,"epx":8.203,"epy":10.876,"epv":25.122,"track":266.5000,"speed":0.000,"eps":21.61,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,2.2,1.3,1.7*30 +$GPGSV,3,1,11,01,06,230,32,05,16,114,42,06,65,063,49,07,72,061,46*76 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,51*7B +$GPGSV,3,3,11,24,51,097,54,30,33,110,50,31,60,230,47*44 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":32,"used":false},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":false},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":47,"used":true}]} +$GPRMC,143800.77,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*0B +$GPGGA,143800.77,4806.3732,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*43 +{"class":"TPV","tag":"GGA","time":1192199880.770,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":8.203,"epy":10.876,"epv":25.122,"track":266.5000,"speed":0.000,"eps":21.75,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,31,05,16,114,42,06,65,063,49,07,72,061,46*75 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,51*7B +$GPGSV,3,3,11,24,51,097,54,30,33,110,50,31,60,230,46*45 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":31,"used":false},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":false},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":33,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":46,"used":true}]} +$GPRMC,143801.77,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*0A +$GPGGA,143801.77,4806.3732,N,00138.6216,W,1,10,1.7,42.1,M,48.5,M,,*4E +{"class":"TPV","tag":"GGA","time":1192199881.770,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":8.203,"epy":10.876,"epv":25.122,"track":266.5000,"speed":0.000,"eps":21.75,"mode":3} +$PFST,FOM,7*62 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,2.4,1.7,1.6*32 +$GPGSV,3,1,11,01,06,230,32,05,16,114,43,06,65,063,49,07,72,061,46*77 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,51*7B +$GPGSV,3,3,11,24,51,097,54,30,32,110,50,31,60,230,46*44 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":32,"used":false},{"PRN":5,"el":16,"az":114,"ss":43,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":230,"ss":46,"used":true}]} +$GPRMC,143802.77,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*09 +$GPGGA,143802.77,4806.3732,N,00138.6216,W,1,09,1.7,42.1,M,48.5,M,,*45 +{"class":"TPV","tag":"GGA","time":1192199882.770,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.5000,"speed":0.000,"eps":21.61,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,,,,2.4,1.7,1.6*30 +$GPGSV,3,1,11,01,06,230,32,05,16,114,43,06,65,063,49,07,72,061,47*76 +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,44,152,53,23,12,316,51*7A +$GPGSV,3,3,11,24,51,097,54,30,32,110,50,31,60,229,46*4C +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":32,"used":false},{"PRN":5,"el":16,"az":114,"ss":43,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":39,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":false}]} +$GPRMC,143803.77,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*08 +$GPGGA,143803.77,4806.3732,N,00138.6216,W,1,11,1.1,42.1,M,48.5,M,,*4B +{"class":"TPV","tag":"GGA","time":1192199883.770,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":8.203,"epy":10.876,"epv":25.122,"track":266.5000,"speed":0.000,"eps":21.61,"mode":3} +$PFST,FOM,8*6D +$GPGSA,A,3,01,05,06,07,10,16,21,23,24,30,31,,1.7,1.1,1.2*31 +$GPGSV,3,1,11,01,06,230,32,05,16,114,44,06,65,063,49,07,72,061,47*71 +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,44,152,53,23,12,316,52*79 +$GPGSV,3,3,11,24,51,097,55,30,32,110,50,31,60,229,46*4D +{"class":"SKY","tag":"GSV","xdop":0.49,"ydop":0.70,"vdop":1.01,"tdop":0.63,"hdop":0.85,"gdop":1.46,"pdop":1.32,"satellites":[{"PRN":1,"el":6,"az":230,"ss":32,"used":true},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":39,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":52,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143804.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*00 +$GPGGA,143804.78,4806.3732,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*48 +{"class":"TPV","tag":"GGA","time":1192199884.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.317,"epy":10.425,"epv":23.208,"track":266.5000,"speed":0.000,"eps":21.09,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,33,05,16,114,44,06,65,063,49,07,72,061,47*70 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,52*77 +$GPGSV,3,3,11,24,51,097,55,30,32,110,50,31,60,229,46*4D +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":33,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":false},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":52,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143805.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*01 +$GPGGA,143805.78,4806.3732,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*49 +{"class":"TPV","tag":"GGA","time":1192199885.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":8.203,"epy":10.876,"epv":25.122,"track":266.5000,"speed":0.000,"eps":21.30,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,00,05,16,114,44,06,65,063,49,07,72,061,47*70 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,51*74 +$GPGSV,3,3,11,24,51,097,55,30,32,110,50,31,60,229,46*4D +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":0,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":false},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143806.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*02 +$GPGGA,143806.78,4806.3732,N,00138.6216,W,1,10,1.1,42.1,M,48.5,M,,*40 +{"class":"TPV","tag":"GGA","time":1192199886.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":8.203,"epy":10.876,"epv":25.122,"track":266.5000,"speed":0.000,"eps":21.75,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,13,05,16,114,44,06,65,063,49,07,72,061,47*72 +$GPGSV,3,2,11,10,09,057,41,16,35,295,48,21,44,152,53,23,12,316,52*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,50,31,60,229,46*4D +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":13,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":41,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":52,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143807.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*03 +$GPGGA,143807.78,4806.3732,N,00138.6216,W,1,10,1.1,42.1,M,48.5,M,,*41 +{"class":"TPV","tag":"GGA","time":1192199887.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.5000,"speed":0.000,"eps":21.61,"mode":3} +$PFST,FOM,6*63 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,30,05,16,114,44,06,65,063,49,07,72,061,47*73 +$GPGSV,3,2,11,10,09,057,41,16,35,295,48,21,44,152,53,23,12,316,52*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,50,31,60,229,46*4D +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":30,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":41,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":52,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143808.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*0C +$GPGGA,143808.78,4806.3732,N,00138.6216,W,1,10,1.1,42.1,M,48.5,M,,*4E +{"class":"TPV","tag":"GGA","time":1192199888.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.5000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,6*63 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,33,05,16,114,43,06,65,063,49,07,72,061,47*77 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,51*74 +$GPGSV,3,3,11,24,51,097,55,30,32,110,51,31,60,229,47*4D +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":33,"used":false},{"PRN":5,"el":16,"az":114,"ss":43,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143809.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*0D +$GPGGA,143809.78,4806.3732,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*45 +{"class":"TPV","tag":"GGA","time":1192199889.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.5000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,2.2,1.3,1.7*30 +$GPGSV,3,1,11,01,06,230,33,05,16,114,45,06,65,063,49,07,72,061,47*71 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,52*78 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,46*4D +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":33,"used":false},{"PRN":5,"el":16,"az":114,"ss":45,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":false},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":52,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143810.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*05 +$GPGGA,143810.78,4806.3732,N,00138.6216,W,1,10,1.0,42.1,M,48.5,M,,*46 +{"class":"TPV","tag":"GGA","time":1192199890.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":8.203,"epy":10.876,"epv":25.122,"track":266.5000,"speed":0.000,"eps":21.61,"mode":3} +$PFST,FOM,6*63 +$GPGSA,A,3,01,05,06,07,16,21,23,24,30,31,,,1.5,1.0,1.2*33 +$GPGSV,3,1,11,01,06,230,36,05,16,114,44,06,65,063,49,07,72,061,47*75 +$GPGSV,3,2,11,10,09,057,37,16,35,295,49,21,44,152,53,23,12,316,52*76 +$GPGSV,3,3,11,24,51,097,53,30,32,110,51,31,60,229,46*4A +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":36,"used":true},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":37,"used":false},{"PRN":16,"el":35,"az":295,"ss":49,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":52,"used":true},{"PRN":24,"el":51,"az":97,"ss":53,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143811.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*04 +$GPGGA,143811.78,4806.3732,N,00138.6216,W,1,10,1.3,42.1,M,48.5,M,,*44 +{"class":"TPV","tag":"GGA","time":1192199891.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.5000,"speed":0.000,"eps":21.61,"mode":3} +$PFST,FOM,7*62 +$GPGSA,A,3,01,05,06,07,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,38,05,16,114,42,06,65,063,49,07,72,061,47*7D +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,53,23,12,316,51*7B +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,46*4D +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":38,"used":true},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":false},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143812.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*07 +$GPGGA,143812.78,4806.3732,N,00138.6216,W,1,11,1.3,42.1,M,48.5,M,,*46 +{"class":"TPV","tag":"GGA","time":1192199892.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.5000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,7*62 +$GPGSA,A,3,01,05,06,07,10,16,21,23,24,30,31,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,39,05,16,114,43,06,65,063,48,07,72,061,47*7C +$GPGSV,3,2,11,10,09,057,37,16,35,295,48,21,44,152,52,23,12,316,52*76 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,47*4C +{"class":"SKY","tag":"GSV","xdop":0.49,"ydop":0.70,"vdop":1.01,"tdop":0.63,"hdop":0.85,"gdop":1.46,"pdop":1.32,"satellites":[{"PRN":1,"el":6,"az":230,"ss":39,"used":true},{"PRN":5,"el":16,"az":114,"ss":43,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":37,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":52,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143813.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*06 +$GPGGA,143813.78,4806.3732,N,00138.6216,W,1,09,1.3,42.1,M,48.5,M,,*4E +{"class":"TPV","tag":"GGA","time":1192199893.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.317,"epy":10.425,"epv":23.208,"track":266.5000,"speed":0.000,"eps":21.16,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,38,05,16,114,44,06,65,063,48,07,72,061,47*7A +$GPGSV,3,2,11,10,09,057,36,16,35,295,47,21,44,152,53,23,12,316,51*7A +$GPGSV,3,3,11,24,51,097,54,30,32,110,50,31,60,229,48*42 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":38,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":36,"used":false},{"PRN":16,"el":35,"az":295,"ss":47,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":229,"ss":48,"used":true}]} +$GPRMC,143814.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*01 +$GPGGA,143814.78,4806.3732,N,00138.6216,W,1,10,1.3,42.1,M,48.5,M,,*41 +{"class":"TPV","tag":"GGA","time":1192199894.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":8.203,"epy":10.876,"epv":25.122,"track":266.5000,"speed":0.000,"eps":21.30,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,38,05,16,114,44,06,65,063,47,07,72,061,47*75 +$GPGSV,3,2,11,10,09,057,37,16,35,295,48,21,44,152,52,23,12,316,52*76 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,48*43 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":38,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":47,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":37,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":52,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":48,"used":true}]} +$GPRMC,143815.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*00 +$GPGGA,143815.78,4806.3732,N,00138.6216,W,1,10,1.2,42.1,M,48.5,M,,*41 +{"class":"TPV","tag":"GGA","time":1192199895.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.5000,"speed":0.000,"eps":21.61,"mode":3} +$PFST,FOM,2*67 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.2,1.3*32 +$GPGSV,3,1,11,01,06,230,37,05,16,114,45,06,65,063,48,07,72,061,47*74 +$GPGSV,3,2,11,10,09,057,40,16,35,295,49,21,44,152,52,23,12,316,50*75 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,46*4D +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":37,"used":false},{"PRN":5,"el":16,"az":114,"ss":45,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":49,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":50,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143816.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*03 +$GPGGA,143816.78,4806.3732,N,00138.6216,W,1,10,1.2,42.1,M,48.5,M,,*42 +{"class":"TPV","tag":"GGA","time":1192199896.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.5000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,01,05,06,07,10,16,21,23,24,30,,,1.7,1.2,1.3*31 +$GPGSV,3,1,11,01,06,230,37,05,16,114,45,06,65,063,48,07,72,061,46*75 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,53,23,12,316,52*77 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,45*4E +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":37,"used":true},{"PRN":5,"el":16,"az":114,"ss":45,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":52,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":45,"used":false}]} +$GPRMC,143817.78,A,4806.3732,N,00138.6216,W,0.00,266.5,121007,2.6,W,A*02 +$GPGGA,143817.78,4806.3732,N,00138.6216,W,1,11,0.8,42.1,M,48.5,M,,*49 +{"class":"TPV","tag":"GGA","time":1192199897.780,"ept":0.005,"lat":48.106220000,"lon":-1.643693333,"alt":42.100,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.5000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,01,05,06,07,10,16,21,23,24,30,31,,1.3,0.8,1.0*3F +$GPGSV,3,1,11,01,06,230,34,05,16,114,44,06,65,063,48,07,72,061,46*77 +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,44,152,53,23,12,316,51*7A +$GPGSV,3,3,11,24,51,097,54,30,32,110,50,31,60,229,44*4E +{"class":"SKY","tag":"GSV","xdop":0.49,"ydop":0.70,"vdop":1.01,"tdop":0.63,"hdop":0.85,"gdop":1.46,"pdop":1.32,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":true},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":39,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":50,"used":true},{"PRN":31,"el":60,"az":229,"ss":44,"used":true}]} +$GPRMC,143818.78,A,4806.3728,N,00138.6239,W,1.56,266.1,121007,2.6,W,A*0D +$GPGGA,143818.78,4806.3728,N,00138.6239,W,1,10,1.3,41.5,M,48.5,M,,*4C +{"class":"TPV","tag":"GGA","time":1192199898.780,"ept":0.005,"lat":48.106213333,"lon":-1.643731667,"alt":41.500,"epx":7.317,"epy":10.425,"epv":23.208,"track":266.1000,"speed":0.803,"eps":21.16,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,34,05,16,114,44,06,65,063,48,07,72,061,46*77 +$GPGSV,3,2,11,10,09,057,42,16,35,295,47,21,44,152,52,23,12,316,51*78 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,46*4D +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":42,"used":true},{"PRN":16,"el":35,"az":295,"ss":47,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143819.79,A,4806.3729,N,00138.6247,W,0.00,266.1,121007,2.6,W,A*07 +$GPGGA,143819.79,4806.3729,N,00138.6247,W,1,10,1.1,41.4,M,48.5,M,,*47 +{"class":"TPV","tag":"GGA","time":1192199899.790,"ept":0.005,"lat":48.106215000,"lon":-1.643745000,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.1000,"speed":0.000,"eps":20.95,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,00,05,16,114,44,06,65,063,48,07,72,061,46*70 +$GPGSV,3,2,11,10,09,057,39,16,35,295,49,21,44,152,52,23,12,316,51*7A +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,48*40 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":0,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":39,"used":true},{"PRN":16,"el":35,"az":295,"ss":49,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":48,"used":true}]} +$GPRMC,143820.79,A,4806.3730,N,00138.6251,W,0.00,266.1,121007,2.6,W,A*02 +$GPGGA,143820.79,4806.3730,N,00138.6251,W,1,10,1.2,41.4,M,48.5,M,,*41 +{"class":"TPV","tag":"GGA","time":1192199900.790,"ept":0.005,"lat":48.106216667,"lon":-1.643751667,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.1000,"speed":0.000,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.2,1.5*3A +$GPGSV,3,1,11,01,06,230,20,05,16,114,44,06,65,063,48,07,72,061,45*71 +$GPGSV,3,2,11,10,09,057,40,16,35,295,50,21,44,152,53,23,12,316,51*7D +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,47*4F +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":20,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":45,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":50,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143821.79,A,4806.3732,N,00138.6265,W,2.31,266.8,121007,2.6,W,A*0F +$GPGGA,143821.79,4806.3732,N,00138.6265,W,1,10,1.2,41.4,M,48.5,M,,*45 +{"class":"TPV","tag":"GGA","time":1192199901.790,"ept":0.005,"lat":48.106220000,"lon":-1.643775000,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.8000,"speed":1.188,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.2,1.5*3A +$GPGSV,3,1,11,01,06,230,34,05,16,114,45,06,65,063,48,07,72,061,46*76 +$GPGSV,3,2,11,10,09,057,40,16,35,295,50,21,44,152,53,23,12,316,51*7D +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,46*4E +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":45,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":50,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143822.79,A,4806.3731,N,00138.6276,W,2.58,266.3,121007,2.6,W,A*09 +$GPGGA,143822.79,4806.3731,N,00138.6276,W,1,10,1.2,41.4,M,48.5,M,,*47 +{"class":"TPV","tag":"GGA","time":1192199902.790,"ept":0.005,"lat":48.106218333,"lon":-1.643793333,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.3000,"speed":1.327,"eps":21.47,"mode":3} +$PFST,FOM,2*67 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.2,1.3*32 +$GPGSV,3,2,11,10,09,057,39,16,35,295,50,21,44,152,53,23,12,316,51*73 +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,45*4D +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.30,"tdop":0.63,"hdop":1.20,"gdop":1.54,"pdop":1.70,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":45,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":50,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":39,"used":true},{"PRN":16,"el":35,"az":295,"ss":50,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":45,"used":true}]} +$GPRMC,143823.79,A,4806.3728,N,00138.6293,W,2.82,266.9,121007,2.6,W,A*06 +$GPGGA,143823.79,4806.3728,N,00138.6293,W,1,10,1.1,41.4,M,48.5,M,,*46 +{"class":"TPV","tag":"GGA","time":1192199903.790,"ept":0.005,"lat":48.106213333,"lon":-1.643821667,"alt":41.400,"epx":7.830,"epy":10.734,"epv":29.900,"track":266.9000,"speed":1.451,"eps":21.47,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,17,05,16,114,45,06,65,063,49,07,72,061,47*77 +$GPGSV,3,2,11,10,09,057,42,16,35,295,49,21,44,152,52,23,12,316,51*76 +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,46*4E +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":17,"used":false},{"PRN":5,"el":16,"az":114,"ss":45,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":42,"used":true},{"PRN":16,"el":35,"az":295,"ss":49,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143824.79,A,4806.3727,N,00138.6306,W,3.10,266.8,121007,2.6,W,A*08 +$GPGGA,143824.79,4806.3727,N,00138.6306,W,1,10,1.1,41.4,M,48.5,M,,*43 +{"class":"TPV","tag":"GGA","time":1192199904.790,"ept":0.005,"lat":48.106211667,"lon":-1.643843333,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.8000,"speed":1.595,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,44,06,65,063,49,07,72,061,46*76 +$GPGSV,3,2,11,10,09,057,42,16,35,295,50,21,44,152,52,23,12,316,50*7F +$GPGSV,3,3,11,24,51,097,55,30,32,110,51,31,60,229,47*4D +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":42,"used":true},{"PRN":16,"el":35,"az":295,"ss":50,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":50,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143825.79,A,4806.3725,N,00138.6321,W,3.34,267.0,121007,2.6,W,A*01 +$GPGGA,143825.79,4806.3725,N,00138.6321,W,1,10,0.9,41.4,M,48.5,M,,*4C +{"class":"TPV","tag":"GGA","time":1192199905.790,"ept":0.005,"lat":48.106208333,"lon":-1.643868333,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":267.0000,"speed":1.718,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,01,06,07,10,16,21,23,24,30,31,,,1.4,0.9,1.1*3D +$GPGSV,3,1,11,01,06,230,35,05,16,114,45,06,65,063,48,07,72,061,48*79 +$GPGSV,3,2,11,10,09,057,43,16,35,295,48,21,44,152,52,23,12,316,51*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,46*4E +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":35,"used":true},{"PRN":5,"el":16,"az":114,"ss":45,"used":false},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":48,"used":true},{"PRN":10,"el":9,"az":57,"ss":43,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":51,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":53,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143826.79,A,4806.3724,N,00138.6335,W,3.61,266.8,121007,2.6,W,A*0F +$GPGGA,143826.79,4806.3724,N,00138.6335,W,1,10,1.1,41.4,M,48.5,M,,*42 +{"class":"TPV","tag":"GGA","time":1192199906.790,"ept":0.005,"lat":48.106206667,"lon":-1.643891667,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.8000,"speed":1.857,"eps":21.47,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,38,05,16,114,46,06,65,063,49,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,42,16,35,295,49,21,44,152,53,23,12,316,50*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,52,31,60,229,46*4F +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":38,"used":false},{"PRN":5,"el":16,"az":114,"ss":46,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":42,"used":true},{"PRN":16,"el":35,"az":295,"ss":49,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":50,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":46,"used":true}]} +$GPRMC,143827.79,A,4806.3724,N,00138.6352,W,3.85,267.0,121007,2.6,W,A*0C +$GPGGA,143827.79,4806.3724,N,00138.6352,W,1,10,1.1,41.4,M,48.5,M,,*42 +{"class":"TPV","tag":"GGA","time":1192199907.790,"ept":0.005,"lat":48.106206667,"lon":-1.643920000,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":267.0000,"speed":1.981,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,37,05,16,114,46,06,65,063,49,07,72,061,46*77 +$GPGSV,3,2,11,10,09,057,43,16,35,295,49,21,44,152,52,23,12,316,49*7E +$GPGSV,3,3,11,24,51,097,55,30,32,110,52,31,60,229,47*4E +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":37,"used":false},{"PRN":5,"el":16,"az":114,"ss":46,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":43,"used":true},{"PRN":16,"el":35,"az":295,"ss":49,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":49,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143828.79,A,4806.3725,N,00138.6368,W,4.12,266.8,121007,2.6,W,A*0B +$GPGGA,143828.79,4806.3725,N,00138.6368,W,1,11,0.8,41.4,M,48.5,M,,*4C +{"class":"TPV","tag":"GGA","time":1192199908.790,"ept":0.005,"lat":48.106208333,"lon":-1.643946667,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.8000,"speed":2.120,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,01,05,06,07,10,16,21,23,24,30,31,,1.3,0.8,1.0*3F +$GPGSV,3,1,11,01,06,230,36,05,16,114,46,06,65,063,49,07,72,061,48*78 +$GPGSV,3,2,11,10,09,057,42,16,35,295,49,21,44,152,51,23,12,316,49*7C +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,47*4F +{"class":"SKY","tag":"GSV","xdop":0.49,"ydop":0.70,"vdop":1.01,"tdop":0.63,"hdop":0.85,"gdop":1.46,"pdop":1.32,"satellites":[{"PRN":1,"el":6,"az":230,"ss":36,"used":true},{"PRN":5,"el":16,"az":114,"ss":46,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":48,"used":true},{"PRN":10,"el":9,"az":57,"ss":42,"used":true},{"PRN":16,"el":35,"az":295,"ss":49,"used":true},{"PRN":21,"el":44,"az":152,"ss":51,"used":true},{"PRN":23,"el":12,"az":316,"ss":49,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":53,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143829.79,A,4806.3724,N,00138.6386,W,4.39,266.7,121007,2.6,W,A*0D +$GPGGA,143829.79,4806.3724,N,00138.6386,W,1,10,1.1,41.4,M,48.5,M,,*45 +{"class":"TPV","tag":"GGA","time":1192199909.790,"ept":0.005,"lat":48.106206667,"lon":-1.643976667,"alt":41.400,"epx":7.317,"epy":10.425,"epv":23.208,"track":266.7000,"speed":2.258,"eps":21.16,"mode":3} +$PFST,FOM,2*67 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,35,05,16,114,45,06,65,063,49,07,72,061,47*77 +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,52,23,12,316,50*74 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,47*4C +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":35,"used":false},{"PRN":5,"el":16,"az":114,"ss":45,"used":true},{"PRN":6,"el":65,"az":63,"ss":49,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":50,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143830.79,A,4806.3723,N,00138.6405,W,4.66,266.3,121007,2.6,W,A*00 +$GPGGA,143830.79,4806.3723,N,00138.6405,W,1,10,1.1,41.4,M,48.5,M,,*46 +{"class":"TPV","tag":"GGA","time":1192199910.790,"ept":0.005,"lat":48.106205000,"lon":-1.644008333,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.3000,"speed":2.397,"eps":21.16,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,37,05,16,114,45,06,65,063,48,07,72,061,48*7B +$GPGSV,3,2,11,10,09,057,41,16,35,295,47,21,44,152,53,23,12,316,46*7C +$GPGSV,3,3,11,24,51,097,55,30,32,110,51,31,60,229,47*4D +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":37,"used":false},{"PRN":5,"el":16,"az":114,"ss":45,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":48,"used":true},{"PRN":10,"el":9,"az":57,"ss":41,"used":true},{"PRN":16,"el":35,"az":295,"ss":47,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":46,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143831.79,A,4806.3723,N,00138.6424,W,4.91,266.5,121007,2.6,W,A*0C +$GPGGA,143831.79,4806.3723,N,00138.6424,W,1,10,1.3,41.4,M,48.5,M,,*46 +{"class":"TPV","tag":"GGA","time":1192199911.790,"ept":0.005,"lat":48.106205000,"lon":-1.644040000,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.5000,"speed":2.526,"eps":21.47,"mode":3} +$PFST,FOM,7*62 +$GPGSA,A,3,01,05,06,07,16,21,23,24,30,31,,,1.9,1.3,1.4*3A +$GPGSV,3,1,11,01,06,230,38,05,16,114,45,06,65,063,48,07,72,061,47*7B +$GPGSV,3,2,11,10,09,057,38,16,35,295,46,21,44,152,53,23,12,316,43*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,51,31,60,229,47*4D +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":38,"used":true},{"PRN":5,"el":16,"az":114,"ss":45,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":false},{"PRN":16,"el":35,"az":295,"ss":46,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":43,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143832.79,A,4806.3723,N,00138.6444,W,5.05,266.3,121007,2.6,W,A*03 +$GPGGA,143832.79,4806.3723,N,00138.6444,W,1,10,1.4,41.4,M,48.5,M,,*44 +{"class":"TPV","tag":"GGA","time":1192199912.790,"ept":0.005,"lat":48.106205000,"lon":-1.644073333,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":266.3000,"speed":2.598,"eps":21.47,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,2.0,1.4,1.4*37 +$GPGSV,3,1,11,01,06,230,37,05,16,114,44,06,65,063,48,07,72,061,48*7A +$GPGSV,3,2,11,10,09,057,37,16,35,295,47,21,44,152,53,23,12,316,44*7F +$GPGSV,3,3,11,24,51,097,55,30,32,110,52,31,60,229,47*4E +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":37,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":48,"used":true},{"PRN":10,"el":9,"az":57,"ss":37,"used":true},{"PRN":16,"el":35,"az":295,"ss":47,"used":true},{"PRN":21,"el":44,"az":152,"ss":53,"used":true},{"PRN":23,"el":12,"az":316,"ss":44,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143833.79,A,4806.3721,N,00138.6464,W,5.13,265.8,121007,2.6,W,A*0D +$GPGGA,143833.79,4806.3721,N,00138.6464,W,1,09,1.3,41.4,M,48.5,M,,*4A +{"class":"TPV","tag":"GGA","time":1192199913.790,"ept":0.005,"lat":48.106201667,"lon":-1.644106667,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":265.8000,"speed":2.639,"eps":21.47,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,38,05,16,114,43,06,65,063,48,07,72,061,48*72 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,52,23,12,316,46*7C +$GPGSV,3,3,11,24,51,097,55,30,32,110,52,31,60,229,47*4E +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":38,"used":false},{"PRN":5,"el":16,"az":114,"ss":43,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":48,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":false},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":46,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143834.80,A,4806.3719,N,00138.6484,W,5.21,266.1,121007,2.6,W,A*02 +$GPGGA,143834.80,4806.3719,N,00138.6484,W,1,09,1.5,41.3,M,48.5,M,,*4F +{"class":"TPV","tag":"GGA","time":1192199914.800,"ept":0.005,"lat":48.106198333,"lon":-1.644140000,"alt":41.300,"epx":8.203,"epy":10.876,"epv":25.122,"track":266.1000,"speed":2.680,"eps":21.40,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,2.3,1.5,1.8*38 +$GPGSV,3,1,11,01,06,230,36,05,16,114,44,06,65,063,48,07,72,061,48*7B +$GPGSV,3,2,11,10,09,057,38,16,35,295,47,21,44,152,52,23,12,316,43*76 +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,48*40 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":36,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":48,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":false},{"PRN":16,"el":35,"az":295,"ss":47,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":43,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":53,"used":true},{"PRN":31,"el":60,"az":229,"ss":48,"used":true}]} +$GPRMC,143835.80,A,4806.3719,N,00138.6509,W,5.31,265.1,121007,2.6,W,A*05 +$GPGGA,143835.80,4806.3719,N,00138.6509,W,1,10,1.1,41.3,M,48.5,M,,*46 +{"class":"TPV","tag":"GGA","time":1192199915.800,"ept":0.005,"lat":48.106198333,"lon":-1.644181667,"alt":41.300,"epx":8.203,"epy":10.876,"epv":25.122,"track":265.1000,"speed":2.732,"eps":21.75,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,36,05,16,114,42,06,65,063,48,07,72,061,48*7D +$GPGSV,3,2,11,10,09,057,39,16,35,295,47,21,44,152,52,23,12,316,48*7C +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,47*4F +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":36,"used":false},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":48,"used":true},{"PRN":10,"el":9,"az":57,"ss":39,"used":true},{"PRN":16,"el":35,"az":295,"ss":47,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":48,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":53,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143836.80,A,4806.3718,N,00138.6527,W,5.42,264.6,121007,2.6,W,A*09 +$GPGGA,143836.80,4806.3718,N,00138.6527,W,1,10,1.2,41.4,M,48.5,M,,*4C +{"class":"TPV","tag":"GGA","time":1192199916.800,"ept":0.005,"lat":48.106196667,"lon":-1.644211667,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":264.6000,"speed":2.788,"eps":21.61,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.2,1.5*3A +$GPGSV,3,1,11,01,06,230,34,05,16,114,42,06,65,063,48,07,72,061,48*7F +$GPGSV,3,2,11,10,09,057,38,16,35,295,47,21,44,152,52,23,12,316,45*70 +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,47*4F +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":42,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":48,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":true},{"PRN":16,"el":35,"az":295,"ss":47,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":45,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":53,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143837.80,A,4806.3716,N,00138.6546,W,5.53,264.3,121007,2.6,W,A*04 +$GPGGA,143837.80,4806.3716,N,00138.6546,W,1,10,1.3,41.4,M,48.5,M,,*45 +{"class":"TPV","tag":"GGA","time":1192199917.800,"ept":0.005,"lat":48.106193333,"lon":-1.644243333,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":264.3000,"speed":2.845,"eps":21.47,"mode":3} +$PFST,FOM,7*62 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.9,1.3,1.3*3D +$GPGSV,3,1,11,01,06,230,34,05,16,114,46,06,65,063,47,07,72,061,47*7B +$GPGSV,3,2,11,10,09,057,37,16,35,295,48,21,44,152,52,23,12,316,44*71 +$GPGSV,3,3,11,24,51,097,55,30,32,110,53,31,60,229,47*4F +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":46,"used":true},{"PRN":6,"el":65,"az":63,"ss":47,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":37,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":44,"used":true},{"PRN":24,"el":51,"az":97,"ss":55,"used":true},{"PRN":30,"el":32,"az":110,"ss":53,"used":true},{"PRN":31,"el":60,"az":229,"ss":47,"used":true}]} +$GPRMC,143838.80,A,4806.3716,N,00138.6569,W,5.64,264.4,121007,2.6,W,A*05 +$GPGGA,143838.80,4806.3716,N,00138.6569,W,1,10,1.1,41.4,M,48.5,M,,*45 +{"class":"TPV","tag":"GGA","time":1192199918.800,"ept":0.005,"lat":48.106193333,"lon":-1.644281667,"alt":41.400,"epx":7.830,"epy":10.734,"epv":25.065,"track":264.4000,"speed":2.901,"eps":21.47,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,00,05,16,114,47,06,65,063,47,07,72,061,47*7D +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,52,23,12,316,47*7D +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,48*40 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":0,"used":false},{"PRN":5,"el":16,"az":114,"ss":47,"used":true},{"PRN":6,"el":65,"az":63,"ss":47,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":47,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":48,"used":true}]} +$GPRMC,143839.80,A,4806.3715,N,00138.6593,W,5.74,264.1,121007,2.6,W,A*06 +$GPGGA,143839.80,4806.3715,N,00138.6593,W,1,09,1.3,41.5,M,48.5,M,,*49 +{"class":"TPV","tag":"GGA","time":1192199919.800,"ept":0.005,"lat":48.106191667,"lon":-1.644321667,"alt":41.500,"epx":7.830,"epy":10.734,"epv":25.065,"track":264.1000,"speed":2.953,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,16,21,23,24,30,31,,,,1.9,1.3,1.3*3C +$GPGSV,3,1,11,01,06,230,12,05,16,114,46,06,65,063,48,07,72,061,47*70 +$GPGSV,3,2,11,10,09,057,35,16,35,295,47,21,44,152,52,23,12,316,48*70 +$GPGSV,3,3,11,24,51,097,54,30,32,110,53,31,60,229,48*41 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.73,"vdop":1.09,"tdop":0.64,"hdop":0.91,"gdop":1.56,"pdop":1.42,"satellites":[{"PRN":1,"el":6,"az":230,"ss":12,"used":false},{"PRN":5,"el":16,"az":114,"ss":46,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":35,"used":false},{"PRN":16,"el":35,"az":295,"ss":47,"used":true},{"PRN":21,"el":44,"az":152,"ss":52,"used":true},{"PRN":23,"el":12,"az":316,"ss":48,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":53,"used":true},{"PRN":31,"el":60,"az":229,"ss":48,"used":true}]} +$GPRMC,143840.80,A,4806.3715,N,00138.6618,W,5.91,263.8,121007,2.6,W,A*0D +$GPGGA,143840.80,4806.3715,N,00138.6618,W,1,10,1.4,41.4,M,48.5,M,,*49 +{"class":"TPV","tag":"GGA","time":1192199920.800,"ept":0.005,"lat":48.106191667,"lon":-1.644363333,"alt":41.400,"epx":8.203,"epy":10.876,"epv":25.122,"track":263.8000,"speed":3.040,"eps":21.61,"mode":3} +$PFST,FOM,5*60 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,2.1,1.4,1.5*37 +$GPGSV,3,1,11,01,06,230,31,05,16,114,46,06,65,063,47,07,72,061,47*7E +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,51,23,12,316,48*71 +$GPGSV,3,3,11,24,51,097,54,30,32,110,53,31,60,229,48*41 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":31,"used":false},{"PRN":5,"el":16,"az":114,"ss":46,"used":true},{"PRN":6,"el":65,"az":63,"ss":47,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":51,"used":true},{"PRN":23,"el":12,"az":316,"ss":48,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":53,"used":true},{"PRN":31,"el":60,"az":229,"ss":48,"used":true}]} +$GPRMC,143841.80,A,4806.3713,N,00138.6642,W,6.07,263.1,121007,2.6,W,A*00 +$GPGGA,143841.80,4806.3713,N,00138.6642,W,1,10,1.6,41.5,M,48.5,M,,*42 +{"class":"TPV","tag":"GGA","time":1192199921.800,"ept":0.005,"lat":48.106188333,"lon":-1.644403333,"alt":41.500,"epx":7.830,"epy":10.734,"epv":25.065,"track":263.1000,"speed":3.123,"eps":21.61,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,2.5,1.6,1.9*3D +$GPGSV,3,1,11,01,06,230,32,05,16,114,47,06,65,063,47,07,72,061,46*7D +$GPGSV,3,2,11,10,09,057,41,16,35,295,49,21,44,152,50,23,12,316,48*7F +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,48*40 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":32,"used":false},{"PRN":5,"el":16,"az":114,"ss":47,"used":true},{"PRN":6,"el":65,"az":63,"ss":47,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":41,"used":true},{"PRN":16,"el":35,"az":295,"ss":49,"used":true},{"PRN":21,"el":44,"az":152,"ss":50,"used":true},{"PRN":23,"el":12,"az":316,"ss":48,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":48,"used":true}]} +$GPRMC,143842.80,A,4806.3713,N,00138.6667,W,6.33,262.2,121007,2.6,W,A*01 +$GPGGA,143842.80,4806.3713,N,00138.6667,W,1,10,1.1,41.5,M,48.5,M,,*41 +{"class":"TPV","tag":"GGA","time":1192199922.800,"ept":0.005,"lat":48.106188333,"lon":-1.644445000,"alt":41.500,"epx":7.830,"epy":10.734,"epv":25.065,"track":262.2000,"speed":3.256,"eps":21.47,"mode":3} +$PFST,FOM,3*66 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,32,05,16,114,45,06,65,063,47,07,72,061,46*7F +$GPGSV,3,2,11,10,09,057,39,16,35,295,48,21,44,152,51,23,12,316,48*70 +$GPGSV,3,3,11,24,51,097,54,30,32,110,52,31,60,229,48*40 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":32,"used":false},{"PRN":5,"el":16,"az":114,"ss":45,"used":true},{"PRN":6,"el":65,"az":63,"ss":47,"used":true},{"PRN":7,"el":72,"az":61,"ss":46,"used":true},{"PRN":10,"el":9,"az":57,"ss":39,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":51,"used":true},{"PRN":23,"el":12,"az":316,"ss":48,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":52,"used":true},{"PRN":31,"el":60,"az":229,"ss":48,"used":true}]} +$GPRMC,143843.80,A,4806.3711,N,00138.6694,W,6.52,261.1,121007,2.6,W,A*09 +$GPGGA,143843.80,4806.3711,N,00138.6694,W,1,10,1.1,41.5,M,48.5,M,,*4E +{"class":"TPV","tag":"GGA","time":1192199923.800,"ept":0.005,"lat":48.106185000,"lon":-1.644490000,"alt":41.500,"epx":7.830,"epy":10.734,"epv":25.065,"track":261.1000,"speed":3.354,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,34,05,16,114,44,06,65,063,47,07,72,061,47*79 +$GPGSV,3,2,11,10,09,057,38,16,35,295,48,21,44,152,50,23,12,316,48*70 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,49*42 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":34,"used":false},{"PRN":5,"el":16,"az":114,"ss":44,"used":true},{"PRN":6,"el":65,"az":63,"ss":47,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":38,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":50,"used":true},{"PRN":23,"el":12,"az":316,"ss":48,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":49,"used":true}]} +$GPRMC,143844.80,A,4806.3707,N,00138.6723,W,6.72,261.3,121007,2.6,W,A*04 +$GPGGA,143844.80,4806.3707,N,00138.6723,W,1,10,1.1,41.6,M,48.5,M,,*40 +{"class":"TPV","tag":"GGA","time":1192199924.800,"ept":0.005,"lat":48.106178333,"lon":-1.644538333,"alt":41.600,"epx":7.830,"epy":10.734,"epv":25.065,"track":261.3000,"speed":3.457,"eps":21.47,"mode":3} +$PFST,FOM,4*61 +$GPGSA,A,3,05,06,07,10,16,21,23,24,30,31,,,1.7,1.1,1.2*30 +$GPGSV,3,1,11,01,06,230,33,05,16,114,48,06,65,063,48,07,72,061,47*7D +$GPGSV,3,2,11,10,09,057,40,16,35,295,48,21,44,152,50,23,12,316,47*70 +$GPGSV,3,3,11,24,51,097,54,30,32,110,51,31,60,229,48*43 +{"class":"SKY","tag":"GSV","xdop":0.52,"ydop":0.72,"vdop":1.09,"tdop":0.63,"hdop":0.89,"gdop":1.54,"pdop":1.40,"satellites":[{"PRN":1,"el":6,"az":230,"ss":33,"used":false},{"PRN":5,"el":16,"az":114,"ss":48,"used":true},{"PRN":6,"el":65,"az":63,"ss":48,"used":true},{"PRN":7,"el":72,"az":61,"ss":47,"used":true},{"PRN":10,"el":9,"az":57,"ss":40,"used":true},{"PRN":16,"el":35,"az":295,"ss":48,"used":true},{"PRN":21,"el":44,"az":152,"ss":50,"used":true},{"PRN":23,"el":12,"az":316,"ss":47,"used":true},{"PRN":24,"el":51,"az":97,"ss":54,"used":true},{"PRN":30,"el":32,"az":110,"ss":51,"used":true},{"PRN":31,"el":60,"az":229,"ss":48,"used":true}]} +$GPRMC,143845.80,A,4806.3705,N,00138.6753,W,6.92,261.2,121007,2.6,W,A*0F +$GPGGA,143845.80,4806.3705,N,00138.6753,W,1,10,1.1,41.7,M,48.5,M,,*45 +{"class":"TPV","tag":"GGA","time":1192199925.800,"ept":0.005,"lat":48.106175000,"lon":-1.644588333,"alt":41.700,"epx":7.830,"epy":10.734,"epv":25.065,"track":261.2000,"speed":3.560,"eps":21.47,"mode":3} +$PFST,FOM,3*66 diff --git a/test/daemon/eXplorist210.log b/test/daemon/eXplorist210.log new file mode 100644 index 0000000..9429b2c --- /dev/null +++ b/test/daemon/eXplorist210.log @@ -0,0 +1,61 @@ +# Name: Magellan eXplorist 210 +# Chipset: unknown +# Submitted-by: "Paul B van den Berg" +# Date: 20 May 2006 +# Location: Groningen, NL, 53.2N6.6E +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# mode V2.1 GSA +# Lines up to but not including the first GPGLL are +# `cat /dev/ttyACM0` at startup +# Following lines are +# `cat /dev/ttyACM0` stationary +$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B +$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78 +$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79 +$PMGNST,01.75,3,F,816,11.1,+00000,20*5E +$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B +$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78 +$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79 +$PMGNST,01.75,3,F,816,11.1,+00000,20*5E +$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B +$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78 +$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79 +$PMGNST,01.75,3,F,822,11.2,+00000,20*5A +$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B +$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78 +$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79 +$PMGNST,01.75,3,F,822,11.2,+00000,20*5A +$GPGSV,3,1,12,09,76,287,,17,38,073,36,26,34,163,,05,33,230,*72 +$GPGSV,3,2,12,29,27,161,,18,24,256,,22,24,299,,28,11,055,*73 +$GPGSV,3,3,12,14,08,319,,11,03,017,,30,02,232,,24,00,084,*71 +$PMGNST,01.75,3,F,822,11.2,-00673,20*5E +# This device has some strange bug that causes it to emit three-digit +# fractional parts on GPGLL timestamps: you can see one in the next line. +# These produce spurious start-of-cycle events. +$GPGLL,5313.2228,N,00634.4228,E,200619.295,A*35 +$GPGGA,200619.30,5313.2228,N,00634.4228,E,1,05,2.6,00000,M,,,,*2C +$GPRMC,200619.30,A,5313.2228,N,00634.4228,E,00.0,000.0,200506,00,W*59 +$GPGSA,A,3,26,05,22,09,18,,,,,,,,05.1,02.6,04.4*03 +$GPGSV,3,1,10,09,78,288,39,17,38,071,,05,34,230,45,26,33,163,39*77 +$GPGSV,3,2,10,29,26,162,,18,24,255,42,22,24,298,44,28,10,056,*75 +$GPGSV,3,3,10,14,09,319,,11,03,016,,136,27,157,,124,28,162,*71 +$GPGLL,5313.2228,N,00634.4228,E,200620.303,A*31 +$GPGGA,200620.30,5313.2228,N,00634.4228,E,1,05,2.5,00000,M,,,,*25 +$GPRMC,200620.30,A,5313.2228,N,00634.4228,E,00.0,000.0,200506,00,W*53 +$GPGSA,A,3,26,05,22,09,18,,,,,,,,05.0,02.5,04.3*06 +$PMGNST,01.75,3,T,816,11.1,-00496,00*43 +$GPGLL,5313.2227,N,00634.4228,E,200621.297,A*33 +$GPGGA,200621.30,5313.2227,N,00634.4228,E,1,05,2.6,00000,M,,,,*28 +$GPRMC,200621.30,A,5313.2227,N,00634.4228,E,00.0,000.0,200506,00,W*5D +$GPGSA,A,3,26,05,22,09,18,,,,,,,,05.2,02.6,04.5*01 +$GPGSV,3,1,10,09,78,288,38,17,38,071,,05,34,230,45,26,33,163,39*76 +$GPGSV,3,2,10,29,26,162,,18,24,255,42,22,24,298,44,28,10,056,*75 +$GPGSV,3,3,10,14,09,319,,11,03,016,,136,27,157,,124,28,162,*71 +$GPGLL,5313.2227,N,00634.4228,E,200622.305,A*3A +$GPGGA,200622.31,5313.2227,N,00634.4228,E,1,05,2.5,00000,M,,,,*29 +$GPRMC,200622.31,A,5313.2227,N,00634.4228,E,00.0,000.0,200506,00,W*5F +$GPGSA,A,3,26,05,22,09,18,,,,,,,,05.0,02.5,04.3*06 +$PMGNST,01.75,3,T,816,11.1,-00495,00*40 diff --git a/test/daemon/eXplorist210.log.chk b/test/daemon/eXplorist210.log.chk new file mode 100644 index 0000000..ae499cf --- /dev/null +++ b/test/daemon/eXplorist210.log.chk @@ -0,0 +1,54 @@ +$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B +$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78 +$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79 +$PMGNST,01.75,3,F,816,11.1,+00000,20*5E +$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B +$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78 +$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79 +$PMGNST,01.75,3,F,816,11.1,+00000,20*5E +$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B +$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78 +$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79 +$PMGNST,01.75,3,F,822,11.2,+00000,20*5A +$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B +$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78 +$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79 +$PMGNST,01.75,3,F,822,11.2,+00000,20*5A +$GPGSV,3,1,12,09,76,287,,17,38,073,36,26,34,163,,05,33,230,*72 +$GPGSV,3,2,12,29,27,161,,18,24,256,,22,24,299,,28,11,055,*73 +$GPGSV,3,3,12,14,08,319,,11,03,017,,30,02,232,,24,00,084,*71 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":9,"el":76,"az":287,"ss":0,"used":false},{"PRN":17,"el":38,"az":73,"ss":36,"used":false},{"PRN":26,"el":34,"az":163,"ss":0,"used":false},{"PRN":5,"el":33,"az":230,"ss":0,"used":false},{"PRN":29,"el":27,"az":161,"ss":0,"used":false},{"PRN":18,"el":24,"az":256,"ss":0,"used":false},{"PRN":22,"el":24,"az":299,"ss":0,"used":false},{"PRN":28,"el":11,"az":55,"ss":0,"used":false},{"PRN":14,"el":8,"az":319,"ss":0,"used":false},{"PRN":11,"el":3,"az":17,"ss":0,"used":false},{"PRN":30,"el":2,"az":232,"ss":0,"used":false},{"PRN":24,"el":0,"az":84,"ss":0,"used":false}]} +$PMGNST,01.75,3,F,822,11.2,-00673,20*5E +$GPGLL,5313.2228,N,00634.4228,E,200619.295,A*35 +{"class":"TPV","tag":"GLL","lat":53.220380000,"lon":6.573713333,"mode":2} +$GPGGA,200619.30,5313.2228,N,00634.4228,E,1,05,2.6,00000,M,,,,*2C +{"class":"TPV","tag":"GGA","lat":53.220380000,"lon":6.573713333,"alt":0.000,"mode":3} +$GPRMC,200619.30,A,5313.2228,N,00634.4228,E,00.0,000.0,200506,00,W*59 +{"class":"TPV","tag":"RMC","time":1148155579.300,"ept":0.005,"lat":53.220380000,"lon":6.573713333,"alt":0.000,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,3,26,05,22,09,18,,,,,,,,05.1,02.6,04.4*03 +{"class":"TPV","tag":"GSA","time":1148155579.300,"ept":0.005,"lat":53.220380000,"lon":6.573713333,"alt":0.000,"epv":101.200,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,3,1,10,09,78,288,39,17,38,071,,05,34,230,45,26,33,163,39*77 +$GPGSV,3,2,10,29,26,162,,18,24,255,42,22,24,298,44,28,10,056,*75 +$GPGSV,3,3,10,14,09,319,,11,03,016,,136,27,157,,124,28,162,*71 +{"class":"SKY","tag":"GSV","xdop":1.19,"ydop":1.62,"vdop":3.99,"tdop":3.09,"hdop":2.01,"gdop":5.43,"pdop":4.47,"satellites":[{"PRN":9,"el":78,"az":288,"ss":39,"used":true},{"PRN":17,"el":38,"az":71,"ss":0,"used":false},{"PRN":5,"el":34,"az":230,"ss":45,"used":true},{"PRN":26,"el":33,"az":163,"ss":39,"used":true},{"PRN":29,"el":26,"az":162,"ss":0,"used":false},{"PRN":18,"el":24,"az":255,"ss":42,"used":true},{"PRN":22,"el":24,"az":298,"ss":44,"used":true},{"PRN":28,"el":10,"az":56,"ss":0,"used":false},{"PRN":14,"el":9,"az":319,"ss":0,"used":false},{"PRN":11,"el":3,"az":16,"ss":0,"used":false},{"PRN":136,"el":27,"az":157,"ss":0,"used":false},{"PRN":124,"el":28,"az":162,"ss":0,"used":false}]} +$GPGLL,5313.2228,N,00634.4228,E,200620.303,A*31 +$GPGGA,200620.30,5313.2228,N,00634.4228,E,1,05,2.5,00000,M,,,,*25 +$GPRMC,200620.30,A,5313.2228,N,00634.4228,E,00.0,000.0,200506,00,W*53 +{"class":"TPV","tag":"RMC","time":1148155580.300,"ept":0.005,"lat":53.220380000,"lon":6.573713333,"alt":0.000,"epx":17.848,"epy":24.244,"epv":91.776,"track":0.0000,"speed":0.000,"climb":0.000,"eps":48.34,"mode":3} +$GPGSA,A,3,26,05,22,09,18,,,,,,,,05.0,02.5,04.3*06 +$PMGNST,01.75,3,T,816,11.1,-00496,00*43 +$GPGLL,5313.2227,N,00634.4228,E,200621.297,A*33 +$GPGGA,200621.30,5313.2227,N,00634.4228,E,1,05,2.6,00000,M,,,,*28 +$GPRMC,200621.30,A,5313.2227,N,00634.4228,E,00.0,000.0,200506,00,W*5D +{"class":"TPV","tag":"RMC","time":1148155581.300,"ept":0.005,"lat":53.220378333,"lon":6.573713333,"alt":0.000,"epx":17.848,"epy":24.244,"epv":98.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":48.63,"mode":3} +$GPGSA,A,3,26,05,22,09,18,,,,,,,,05.2,02.6,04.5*01 +$GPGSV,3,1,10,09,78,288,38,17,38,071,,05,34,230,45,26,33,163,39*76 +$GPGSV,3,2,10,29,26,162,,18,24,255,42,22,24,298,44,28,10,056,*75 +$GPGSV,3,3,10,14,09,319,,11,03,016,,136,27,157,,124,28,162,*71 +{"class":"SKY","tag":"GSV","xdop":1.19,"ydop":1.62,"vdop":3.99,"tdop":3.09,"hdop":2.01,"gdop":5.43,"pdop":4.47,"satellites":[{"PRN":9,"el":78,"az":288,"ss":38,"used":true},{"PRN":17,"el":38,"az":71,"ss":0,"used":false},{"PRN":5,"el":34,"az":230,"ss":45,"used":true},{"PRN":26,"el":33,"az":163,"ss":39,"used":true},{"PRN":29,"el":26,"az":162,"ss":0,"used":false},{"PRN":18,"el":24,"az":255,"ss":42,"used":true},{"PRN":22,"el":24,"az":298,"ss":44,"used":true},{"PRN":28,"el":10,"az":56,"ss":0,"used":false},{"PRN":14,"el":9,"az":319,"ss":0,"used":false},{"PRN":11,"el":3,"az":16,"ss":0,"used":false},{"PRN":136,"el":27,"az":157,"ss":0,"used":false},{"PRN":124,"el":28,"az":162,"ss":0,"used":false}]} +$GPGLL,5313.2227,N,00634.4228,E,200622.305,A*3A +$GPGGA,200622.31,5313.2227,N,00634.4228,E,1,05,2.5,00000,M,,,,*29 +$GPRMC,200622.31,A,5313.2227,N,00634.4228,E,00.0,000.0,200506,00,W*5F +{"class":"TPV","tag":"RMC","time":1148155582.310,"ept":0.005,"lat":53.220378333,"lon":6.573713333,"alt":0.000,"epx":17.848,"epy":24.244,"epv":91.776,"track":0.0000,"speed":0.000,"climb":0.000,"eps":48.25,"mode":3} +$GPGSA,A,3,26,05,22,09,18,,,,,,,,05.0,02.5,04.3*06 +$PMGNST,01.75,3,T,816,11.1,-00495,00*40 diff --git a/test/daemon/et-332.log b/test/daemon/et-332.log new file mode 100644 index 0000000..50e6218 --- /dev/null +++ b/test/daemon/et-332.log @@ -0,0 +1,368 @@ +# Name: ET-322 engine board from GlobalSat +# Chipset: SiRF-III +# Submitted-by: Val Schmidt +# Date: 25 Apr 2010 +# Location: Newark, DE +# Transport: UDP +# +# The bard lives inside a Gavia AUV , which was +# placed in the parking log of a university laboratory for the capture +# of this data. It was completely stationary. Also, this sample +# contains strings that indicate the date. +# +# The contents of the Transport header tell the gpsd test framework to +# ship the file to the subordinate gpsd via IP datagrams. The source +# is passed in as a udp:// URL. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPZDA,153347.000,23,04,2010,,*57 +$GPGGA,153347.000,3940.6986,N,07544.9356,W,1,09,1.3,75.2,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153347.000,A,3940.6986,N,07544.9356,W,0.12,87.21,230410,,*29 +$GPVTG,87.21,T,,M,0.12,N,0.2,K*5D +$GPZDA,153348.000,23,04,2010,,*58 +$GPGGA,153348.000,3940.6986,N,07544.9356,W,1,09,1.3,75.0,M,-33.8,M,,0000*5E +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153348.000,A,3940.6986,N,07544.9356,W,0.12,82.56,230410,,*23 +$GPVTG,82.56,T,,M,0.12,N,0.2,K*58 +$GPZDA,153349.000,23,04,2010,,*59 +$GPGGA,153349.000,3940.6986,N,07544.9357,W,1,09,1.3,74.6,M,-33.8,M,,0000*59 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153349.000,A,3940.6986,N,07544.9357,W,0.09,115.18,230410,,*1C +$GPVTG,115.18,T,,M,0.09,N,0.2,K*67 +$GPZDA,153350.000,23,04,2010,,*51 +$GPGGA,153350.000,3940.6986,N,07544.9357,W,1,09,1.3,74.4,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,270,40,21,73,256,40,24,66,289,38,18,58,312,45*7E +$GPGSV,3,2,12,27,51,116,44,15,47,048,40,09,46,136,40,22,26,291,22*76 +$GPGSV,3,3,12,06,13,303,28,03,06,312,,29,06,199,20,05,05,096,25*77 ++ 6: 28 (.....) ++ 9: 40 (........) ++15: 40 (........) ++21: 40 (........) ++24: 38 (.......) ++26: 40 (........) ++27: 44 (........) ++29: 20 (....) +$GPRMC,153350.000,A,3940.6986,N,07544.9357,W,0.09,87.19,230410,,*2F +$GPVTG,87.19,T,,M,0.09,N,0.2,K*5C +$GPZDA,153351.000,23,04,2010,,*50 +$GPGGA,153351.000,3940.6985,N,07544.9358,W,1,09,1.3,74.1,M,-33.8,M,,0000*5B +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153351.000,A,3940.6985,N,07544.9358,W,0.09,91.11,230410,,*2D +$GPVTG,91.11,T,,M,0.09,N,0.2,K*53 +$GPZDA,153352.000,23,04,2010,,*53 +$GPGGA,153352.000,3940.6985,N,07544.9358,W,1,09,1.3,73.9,M,-33.8,M,,0000*57 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153352.000,A,3940.6985,N,07544.9358,W,0.07,136.11,230410,,*1C +$GPVTG,136.11,T,,M,0.07,N,0.1,K*62 +$GPZDA,153353.000,23,04,2010,,*52 +$GPGGA,153353.000,3940.6985,N,07544.9358,W,1,09,1.3,74.0,M,-33.8,M,,0000*58 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153353.000,A,3940.6985,N,07544.9358,W,0.10,73.57,230410,,*29 +$GPVTG,73.57,T,,M,0.10,N,0.2,K*55 +$GPZDA,153354.000,23,04,2010,,*55 +$GPGGA,153354.000,3940.6985,N,07544.9358,W,1,09,1.3,73.9,M,-33.8,M,,0000*51 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153354.000,A,3940.6985,N,07544.9358,W,0.06,86.02,230410,,*23 +$GPVTG,86.02,T,,M,0.06,N,0.1,K*5B +$GPZDA,153355.000,23,04,2010,,*54 +$GPGGA,153355.000,3940.6985,N,07544.9358,W,1,09,1.3,73.9,M,-33.8,M,,0000*50 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,270,40,21,73,256,40,24,66,289,38,18,58,312,45*7E +$GPGSV,3,2,12,27,51,116,44,15,47,048,40,09,46,136,40,22,26,291,19*7E +$GPGSV,3,3,12,06,13,303,,03,06,312,10,29,06,199,23,05,05,096,25*7F ++ 3: 10 (..) +-( 6: 28 (.....)) + 9: 40 (........) +15: 40 (........) +21: 40 (........) +24: 38 (.......) +26: 40 (........) +27: 44 (........) +29: 20 (....) +$GPRMC,153355.000,A,3940.6985,N,07544.9358,W,0.11,71.30,230410,,*2D +$GPVTG,71.30,T,,M,0.11,N,0.2,K*57 +$GPZDA,153356.000,23,04,2010,,*57 +$GPGGA,153356.000,3940.6985,N,07544.9358,W,1,09,1.3,73.9,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153356.000,A,3940.6985,N,07544.9358,W,0.04,127.06,230410,,*1D +$GPVTG,127.06,T,,M,0.04,N,0.1,K*67 +$GPZDA,153357.000,23,04,2010,,*56 +$GPGGA,153357.000,3940.6985,N,07544.9358,W,1,09,1.3,73.7,M,-33.8,M,,0000*5C +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153357.000,A,3940.6985,N,07544.9358,W,0.09,191.66,230410,,*1A +$GPVTG,191.66,T,,M,0.09,N,0.2,K*62 +$GPZDA,153358.000,23,04,2010,,*59 +$GPGGA,153358.000,3940.6985,N,07544.9358,W,1,09,1.3,73.7,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153358.000,A,3940.6985,N,07544.9358,W,0.05,118.29,230410,,*13 +$GPVTG,118.29,T,,M,0.05,N,0.1,K*67 +$GPZDA,153359.000,23,04,2010,,*58 +$GPGGA,153359.000,3940.6985,N,07544.9359,W,1,09,1.3,73.2,M,-33.8,M,,0000*56 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153359.000,A,3940.6985,N,07544.9359,W,0.12,206.85,230410,,*1F +$GPVTG,206.85,T,,M,0.12,N,0.2,K*68 +$GPZDA,153400.000,23,04,2010,,*53 +$GPGGA,153400.000,3940.6985,N,07544.9359,W,1,09,1.3,72.9,M,-33.8,M,,0000*57 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,270,39,21,73,256,39,24,66,289,39,18,58,312,45*7F +$GPGSV,3,2,12,27,51,116,43,15,47,048,30,09,46,136,42,22,26,291,14*71 +$GPGSV,3,3,12,06,13,303,27,03,06,312,,29,06,199,22,05,05,096,25*7A +-( 3: 10 (..)) ++ 6: 27 (.....) + 9: 40 (........) +15: 40 (........) +21: 40 (........) +24: 38 (.......) +26: 40 (........) +27: 44 (........) +29: 23 (....) +$GPRMC,153400.000,A,3940.6985,N,07544.9359,W,0.19,205.81,230410,,*18 +$GPVTG,205.81,T,,M,0.19,N,0.3,K*65 +$GPZDA,153401.000,23,04,2010,,*52 +$GPGGA,153401.000,3940.6985,N,07544.9360,W,1,09,1.3,72.6,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153401.000,A,3940.6985,N,07544.9360,W,0.24,45.90,230410,,*2B +$GPVTG,45.90,T,,M,0.24,N,0.4,K*5A +$GPZDA,153402.000,23,04,2010,,*51 +$GPGGA,153402.000,3940.6985,N,07544.9360,W,1,09,1.3,72.4,M,-33.8,M,,0000*52 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153402.000,A,3940.6985,N,07544.9360,W,0.14,217.87,230410,,*18 +$GPVTG,217.87,T,,M,0.14,N,0.3,K*6D +$GPZDA,153403.000,23,04,2010,,*50 +$GPGGA,153403.000,3940.6985,N,07544.9360,W,1,09,1.3,72.3,M,-33.8,M,,0000*54 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153403.000,A,3940.6985,N,07544.9360,W,0.17,48.77,230410,,*2D +$GPVTG,48.77,T,,M,0.17,N,0.3,K*59 +$GPZDA,153404.000,23,04,2010,,*57 +$GPGGA,153404.000,3940.6985,N,07544.9360,W,1,09,1.3,72.3,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153404.000,A,3940.6985,N,07544.9360,W,0.12,198.25,230410,,*14 +$GPVTG,198.25,T,,M,0.12,N,0.2,K*66 +$GPZDA,153405.000,23,04,2010,,*56 +$GPGGA,153405.000,3940.6985,N,07544.9360,W,1,09,1.3,72.4,M,-33.8,M,,0000*55 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,270,39,21,73,256,38,24,66,289,39,18,58,312,44*7F +$GPGSV,3,2,12,27,51,116,43,15,47,048,37,09,46,136,41,22,26,291,11*70 +$GPGSV,3,3,12,06,13,303,28,03,06,312,,29,06,199,23,05,05,096,25*74 + 6: 27 (.....) + 9: 42 (........) +15: 30 (......) +21: 39 (.......) +24: 39 (.......) +26: 39 (.......) +27: 43 (........) +29: 22 (....) +$GPRMC,153405.000,A,3940.6985,N,07544.9360,W,0.21,205.69,230410,,*1A +$GPVTG,205.69,T,,M,0.21,N,0.4,K*6F +$GPZDA,153406.000,23,04,2010,,*55 +$GPGGA,153406.000,3940.6984,N,07544.9360,W,1,09,1.3,72.5,M,-33.8,M,,0000*56 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153406.000,A,3940.6984,N,07544.9360,W,0.11,198.24,230410,,*15 +$GPVTG,198.24,T,,M,0.11,N,0.2,K*64 +$GPZDA,153407.000,23,04,2010,,*54 +$GPGGA,153407.000,3940.6984,N,07544.9361,W,1,09,1.3,72.7,M,-33.8,M,,0000*54 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153407.000,A,3940.6984,N,07544.9361,W,0.09,185.69,230410,,*19 +$GPVTG,185.69,T,,M,0.09,N,0.2,K*68 +$GPZDA,153408.000,23,04,2010,,*5B +$GPGGA,153408.000,3940.6984,N,07544.9360,W,1,09,1.3,73.0,M,-33.8,M,,0000*5C +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153408.000,A,3940.6984,N,07544.9360,W,0.08,68.19,230410,,*23 +$GPVTG,68.19,T,,M,0.08,N,0.1,K*5F +$GPZDA,153409.000,23,04,2010,,*5A +$GPGGA,153409.000,3940.6984,N,07544.9360,W,1,09,1.3,72.8,M,-33.8,M,,0000*54 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153409.000,A,3940.6984,N,07544.9360,W,0.03,136.94,230410,,*16 +$GPVTG,136.94,T,,M,0.03,N,0.1,K*6B +$GPZDA,153410.000,23,04,2010,,*52 +$GPGGA,153410.000,3940.6985,N,07544.9360,W,1,09,1.3,72.6,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,270,39,21,73,256,37,24,66,289,40,18,58,312,44*7E +$GPGSV,3,2,12,27,51,116,43,15,47,048,40,09,46,136,42,22,26,291,13*71 +$GPGSV,3,3,12,06,13,303,,03,06,312,,29,06,199,24,05,05,096,24*78 +-( 6: 28 (.....)) + 9: 41 (........) +15: 37 (.......) +21: 38 (.......) +24: 39 (.......) +26: 39 (.......) +27: 43 (........) +29: 23 (....) +$GPRMC,153410.000,A,3940.6985,N,07544.9360,W,0.04,163.02,230410,,*17 +$GPVTG,163.02,T,,M,0.04,N,0.1,K*63 +$GPZDA,153411.000,23,04,2010,,*53 +$GPGGA,153411.000,3940.6985,N,07544.9360,W,1,09,1.3,72.5,M,-33.8,M,,0000*51 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153411.000,A,3940.6985,N,07544.9360,W,0.09,55.20,230410,,*2F +$GPVTG,55.20,T,,M,0.09,N,0.2,K*59 +$GPZDA,153412.000,23,04,2010,,*50 +$GPGGA,153412.000,3940.6985,N,07544.9359,W,1,09,1.3,72.3,M,-33.8,M,,0000*5E +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153412.000,A,3940.6985,N,07544.9359,W,0.09,58.22,230410,,*29 +$GPVTG,58.22,T,,M,0.09,N,0.2,K*56 +$GPZDA,153413.000,23,04,2010,,*51 +$GPGGA,153413.000,3940.6986,N,07544.9359,W,1,09,1.3,72.1,M,-33.8,M,,0000*5E +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153413.000,A,3940.6986,N,07544.9359,W,0.13,65.66,230410,,*2E +$GPVTG,65.66,T,,M,0.13,N,0.2,K*53 +$GPZDA,153414.000,23,04,2010,,*56 +$GPGGA,153414.000,3940.6986,N,07544.9359,W,1,09,1.3,71.8,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153414.000,A,3940.6986,N,07544.9359,W,0.06,72.14,230410,,*2E +$GPVTG,72.14,T,,M,0.06,N,0.1,K*57 +$GPZDA,153415.000,23,04,2010,,*57 +$GPGGA,153415.000,3940.6986,N,07544.9359,W,1,08,1.9,71.8,M,-33.8,M,,0000*59 +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPGSV,3,1,12,26,82,270,39,21,73,256,37,24,66,289,39,18,58,312,44*70 +$GPGSV,3,2,12,27,51,116,42,15,47,048,40,09,46,136,42,22,26,291,*72 +$GPGSV,3,3,12,06,13,303,27,03,06,312,,29,06,199,17,05,05,096,19*73 ++ 6: 27 (.....) + 9: 42 (........) +15: 40 (........) +21: 37 (.......) +24: 40 (........) +26: 39 (.......) +27: 43 (........) +29: 24 (....) +$GPRMC,153415.000,A,3940.6986,N,07544.9359,W,0.07,71.45,230410,,*29 +$GPVTG,71.45,T,,M,0.07,N,0.1,K*51 +$GPZDA,153416.000,23,04,2010,,*54 +$GPGGA,153416.000,3940.6986,N,07544.9359,W,1,08,1.9,71.9,M,-33.8,M,,0000*5B +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPRMC,153416.000,A,3940.6986,N,07544.9359,W,0.04,125.99,230410,,*18 +$GPVTG,125.99,T,,M,0.04,N,0.1,K*63 +$GPZDA,153417.000,23,04,2010,,*55 +$GPGGA,153417.000,3940.6986,N,07544.9359,W,1,09,1.3,71.6,M,-33.8,M,,0000*5E +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153417.000,A,3940.6986,N,07544.9359,W,0.16,60.22,230410,,*2A +$GPVTG,60.22,T,,M,0.16,N,0.3,K*52 +$GPZDA,153418.000,23,04,2010,,*5A +$GPGGA,153418.000,3940.6986,N,07544.9359,W,1,09,1.3,71.5,M,-33.8,M,,0000*52 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153418.000,A,3940.6986,N,07544.9359,W,0.04,108.21,230410,,*1A +$GPVTG,108.21,T,,M,0.04,N,0.1,K*6F +$GPZDA,153419.000,23,04,2010,,*5B +$GPGGA,153419.000,3940.6987,N,07544.9359,W,1,09,1.3,71.6,M,-33.8,M,,0000*51 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153419.000,A,3940.6987,N,07544.9359,W,0.32,53.50,230410,,*26 +$GPVTG,53.50,T,,M,0.32,N,0.6,K*54 +$GPZDA,153420.000,23,04,2010,,*51 +$GPGGA,153420.000,3940.6987,N,07544.9358,W,1,09,1.3,71.8,M,-33.8,M,,0000*54 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,272,39,21,73,256,35,24,67,288,39,18,59,312,37*75 +$GPGSV,3,2,12,27,51,115,43,15,47,048,40,09,46,136,43,22,26,291,11*71 +$GPGSV,3,3,12,06,13,303,27,03,06,312,,29,06,199,17,14,05,232,*77 + 6: 27 (.....) + 9: 42 (........) +15: 40 (........) +21: 37 (.......) +24: 39 (.......) +26: 39 (.......) +27: 42 (........) +29: 17 (...) +$GPRMC,153420.000,A,3940.6987,N,07544.9358,W,0.31,53.43,230410,,*2C +$GPVTG,53.43,T,,M,0.31,N,0.6,K*55 +$GPZDA,153421.000,23,04,2010,,*50 +$GPGGA,153421.000,3940.6988,N,07544.9357,W,1,09,1.3,71.6,M,-33.8,M,,0000*5B +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153421.000,A,3940.6988,N,07544.9357,W,0.31,59.72,230410,,*25 +$GPVTG,59.72,T,,M,0.31,N,0.6,K*5D +$GPZDA,153422.000,23,04,2010,,*53 +$GPGGA,153422.000,3940.6988,N,07544.9357,W,1,09,1.3,71.5,M,-33.8,M,,0000*5B +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153422.000,A,3940.6988,N,07544.9357,W,0.06,123.72,230410,,*1E +$GPVTG,123.72,T,,M,0.06,N,0.1,K*62 +$GPZDA,153423.000,23,04,2010,,*52 +$GPGGA,153423.000,3940.6988,N,07544.9358,W,1,09,1.3,71.2,M,-33.8,M,,0000*52 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153423.000,A,3940.6988,N,07544.9358,W,0.08,129.63,230410,,*14 +$GPVTG,129.63,T,,M,0.08,N,0.1,K*66 +$GPZDA,153424.000,23,04,2010,,*55 +$GPGGA,153424.000,3940.6987,N,07544.9358,W,1,09,1.3,71.1,M,-33.8,M,,0000*59 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153424.000,A,3940.6987,N,07544.9358,W,0.07,100.77,230410,,*1D +$GPVTG,100.77,T,,M,0.07,N,0.1,K*67 +$GPZDA,153425.000,23,04,2010,,*54 +$GPGGA,153425.000,3940.6987,N,07544.9359,W,1,09,1.3,70.9,M,-33.8,M,,0000*50 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,272,39,21,73,256,36,24,67,288,38,18,59,312,42*75 +$GPGSV,3,2,12,27,51,115,42,15,47,048,40,09,46,136,43,22,26,291,07*77 +$GPGSV,3,3,12,06,13,303,,03,06,312,12,29,06,199,25,14,05,232,*70 ++ 3: 12 (..) +-( 6: 27 (.....)) + 9: 43 (........) +15: 40 (........) +21: 35 (.......) +24: 39 (.......) +26: 39 (.......) +27: 43 (........) +29: 17 (...) +$GPRMC,153425.000,A,3940.6987,N,07544.9359,W,0.10,89.40,230410,,*2F +$GPVTG,89.40,T,,M,0.10,N,0.2,K*56 +$GPZDA,153426.000,23,04,2010,,*57 +$GPGGA,153426.000,3940.6987,N,07544.9359,W,1,09,1.3,70.4,M,-33.8,M,,0000*5E +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153426.000,A,3940.6987,N,07544.9359,W,0.15,63.07,230410,,*2E +$GPVTG,63.07,T,,M,0.15,N,0.3,K*55 +$GPZDA,153427.000,23,04,2010,,*56 +$GPGGA,153427.000,3940.6987,N,07544.9359,W,1,08,1.9,70.5,M,-33.8,M,,0000*55 +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPRMC,153427.000,A,3940.6987,N,07544.9359,W,0.14,65.26,230410,,*2B +$GPVTG,65.26,T,,M,0.14,N,0.3,K*51 +$GPZDA,153428.000,23,04,2010,,*59 +$GPGGA,153428.000,3940.6987,N,07544.9359,W,1,08,1.9,70.7,M,-33.8,M,,0000*58 +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPRMC,153428.000,A,3940.6987,N,07544.9359,W,0.10,75.11,230410,,*25 +$GPVTG,75.11,T,,M,0.10,N,0.2,K*51 +$GPZDA,153429.000,23,04,2010,,*58 +$GPGGA,153429.000,3940.6987,N,07544.9359,W,1,09,1.3,70.1,M,-33.8,M,,0000*54 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153429.000,A,3940.6987,N,07544.9359,W,0.13,65.02,230410,,*24 +$GPVTG,65.02,T,,M,0.13,N,0.2,K*51 +$GPZDA,153430.000,23,04,2010,,*50 +$GPGGA,153430.000,3940.6987,N,07544.9360,W,1,09,1.3,69.6,M,-33.8,M,,0000*59 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,272,39,21,73,256,36,24,67,288,37,18,59,312,42*7A +$GPGSV,3,2,12,27,51,115,42,15,47,048,39,09,46,136,43,22,26,291,*7E +$GPGSV,3,3,12,06,13,303,27,03,06,312,,29,06,199,13,14,05,232,*73 +-( 3: 12 (..)) ++ 6: 27 (.....) + 9: 43 (........) +15: 40 (........) +21: 36 (.......) +24: 38 (.......) +26: 39 (.......) +27: 42 (........) +29: 25 (.....) +$GPRMC,153430.000,A,3940.6987,N,07544.9360,W,0.09,67.21,230410,,*2E +$GPVTG,67.21,T,,M,0.09,N,0.2,K*59 +$GPZDA,153431.000,23,04,2010,,*51 +$GPGGA,153431.000,3940.6987,N,07544.9361,W,1,09,1.3,69.4,M,-33.8,M,,0000*5B +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153431.000,A,3940.6987,N,07544.9361,W,0.06,167.61,230410,,*14 +$GPVTG,167.61,T,,M,0.06,N,0.1,K*60 +$GPZDA,153432.000,23,04,2010,,*52 +$GPGGA,153432.000,3940.6986,N,07544.9362,W,1,09,1.3,68.9,M,-33.8,M,,0000*56 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153432.000,A,3940.6986,N,07544.9362,W,0.15,61.34,230410,,*20 +$GPVTG,61.34,T,,M,0.15,N,0.3,K*57 +$GPZDA,153433.000,23,04,2010,,*53 +$GPGGA,153433.000,3940.6987,N,07544.9362,W,1,08,1.9,69.0,M,-33.8,M,,0000*55 +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPRMC,153433.000,A,3940.6987,N,07544.9362,W,0.06,83.09,230410,,*20 +$GPVTG,83.09,T,,M,0.06,N,0.1,K*55 +$GPZDA,153434.000,23,04,2010,,*54 +$GPGGA,153434.000,3940.6987,N,07544.9361,W,1,08,1.9,69.2,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPRMC,153434.000,A,3940.6987,N,07544.9361,W,0.09,68.77,230410,,*27 +$GPVTG,68.77,T,,M,0.09,N,0.2,K*55 +$GPZDA,153435.000,23,04,2010,,*55 +$GPGGA,153435.000,3940.6987,N,07544.9361,W,1,08,1.9,69.5,M,-33.8,M,,0000*55 +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPGSV,3,1,12,26,82,272,39,21,73,256,37,24,67,288,38,18,59,312,42*74 +$GPGSV,3,2,12,27,51,115,42,15,47,048,39,09,46,136,43,22,26,291,*7E +$GPGSV,3,3,12,06,13,303,27,03,06,312,12,29,06,199,,14,05,232,*72 diff --git a/test/daemon/et-332.log.chk b/test/daemon/et-332.log.chk new file mode 100644 index 0000000..91b9457 --- /dev/null +++ b/test/daemon/et-332.log.chk @@ -0,0 +1,341 @@ +$GPZDA,153347.000,23,04,2010,,*57 +$GPGGA,153347.000,3940.6986,N,07544.9356,W,1,09,1.3,75.2,M,-33.8,M,,0000*53 +{"class":"TPV","tag":"GGA","time":1272036827.000,"ept":0.005,"lat":39.678310000,"lon":-75.748926667,"alt":75.200,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +{"class":"TPV","tag":"GSA","time":1272036827.000,"ept":0.005,"lat":39.678310000,"lon":-75.748926667,"alt":75.200,"epv":32.200,"speed":0.000,"climb":0.000,"mode":3} +$GPRMC,153347.000,A,3940.6986,N,07544.9356,W,0.12,87.21,230410,,*29 +{"class":"TPV","tag":"RMC","time":1272036827.000,"ept":0.005,"lat":39.678310000,"lon":-75.748926667,"alt":75.200,"epv":32.200,"track":87.2100,"speed":0.062,"climb":0.000,"mode":3} +$GPVTG,87.21,T,,M,0.12,N,0.2,K*5D +$GPZDA,153348.000,23,04,2010,,*58 +$GPGGA,153348.000,3940.6986,N,07544.9356,W,1,09,1.3,75.0,M,-33.8,M,,0000*5E +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153348.000,A,3940.6986,N,07544.9356,W,0.12,82.56,230410,,*23 +{"class":"TPV","tag":"RMC","time":1272036828.000,"ept":0.005,"lat":39.678310000,"lon":-75.748926667,"alt":75.000,"epv":32.200,"track":82.5600,"speed":0.062,"climb":0.000,"mode":3} +$GPVTG,82.56,T,,M,0.12,N,0.2,K*58 +$GPZDA,153349.000,23,04,2010,,*59 +$GPGGA,153349.000,3940.6986,N,07544.9357,W,1,09,1.3,74.6,M,-33.8,M,,0000*59 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153349.000,A,3940.6986,N,07544.9357,W,0.09,115.18,230410,,*1C +{"class":"TPV","tag":"RMC","time":1272036829.000,"ept":0.005,"lat":39.678310000,"lon":-75.748928333,"alt":74.600,"epv":32.200,"track":115.1800,"speed":0.046,"climb":0.000,"mode":3} +$GPVTG,115.18,T,,M,0.09,N,0.2,K*67 +$GPZDA,153350.000,23,04,2010,,*51 +$GPGGA,153350.000,3940.6986,N,07544.9357,W,1,09,1.3,74.4,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,270,40,21,73,256,40,24,66,289,38,18,58,312,45*7E +$GPGSV,3,2,12,27,51,116,44,15,47,048,40,09,46,136,40,22,26,291,22*76 +$GPGSV,3,3,12,06,13,303,28,03,06,312,,29,06,199,20,05,05,096,25*77 +{"class":"SKY","tag":"GSV","xdop":0.82,"ydop":1.32,"vdop":1.61,"tdop":1.30,"hdop":1.55,"gdop":2.59,"pdop":2.24,"satellites":[{"PRN":26,"el":82,"az":270,"ss":40,"used":true},{"PRN":21,"el":73,"az":256,"ss":40,"used":true},{"PRN":24,"el":66,"az":289,"ss":38,"used":true},{"PRN":18,"el":58,"az":312,"ss":45,"used":true},{"PRN":27,"el":51,"az":116,"ss":44,"used":true},{"PRN":15,"el":47,"az":48,"ss":40,"used":true},{"PRN":9,"el":46,"az":136,"ss":40,"used":true},{"PRN":22,"el":26,"az":291,"ss":22,"used":false},{"PRN":6,"el":13,"az":303,"ss":28,"used":false},{"PRN":3,"el":6,"az":312,"ss":0,"used":false},{"PRN":29,"el":6,"az":199,"ss":20,"used":true},{"PRN":5,"el":5,"az":96,"ss":25,"used":true}]} +$GPRMC,153350.000,A,3940.6986,N,07544.9357,W,0.09,87.19,230410,,*2F +{"class":"TPV","tag":"RMC","time":1272036830.000,"ept":0.005,"lat":39.678310000,"lon":-75.748928333,"alt":74.400,"epx":12.310,"epy":19.762,"epv":32.200,"track":87.1900,"speed":0.046,"climb":0.000,"mode":3} +$GPVTG,87.19,T,,M,0.09,N,0.2,K*5C +$GPZDA,153351.000,23,04,2010,,*50 +$GPGGA,153351.000,3940.6985,N,07544.9358,W,1,09,1.3,74.1,M,-33.8,M,,0000*5B +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153351.000,A,3940.6985,N,07544.9358,W,0.09,91.11,230410,,*2D +{"class":"TPV","tag":"RMC","time":1272036831.000,"ept":0.005,"lat":39.678308333,"lon":-75.748930000,"alt":74.100,"epx":12.310,"epy":19.762,"epv":37.112,"track":91.1100,"speed":0.046,"climb":0.000,"mode":3} +$GPVTG,91.11,T,,M,0.09,N,0.2,K*53 +$GPZDA,153352.000,23,04,2010,,*53 +$GPGGA,153352.000,3940.6985,N,07544.9358,W,1,09,1.3,73.9,M,-33.8,M,,0000*57 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153352.000,A,3940.6985,N,07544.9358,W,0.07,136.11,230410,,*1C +{"class":"TPV","tag":"RMC","time":1272036832.000,"ept":0.005,"lat":39.678308333,"lon":-75.748930000,"alt":73.900,"epx":12.310,"epy":19.762,"epv":32.200,"track":136.1100,"speed":0.036,"climb":0.000,"mode":3} +$GPVTG,136.11,T,,M,0.07,N,0.1,K*62 +$GPZDA,153353.000,23,04,2010,,*52 +$GPGGA,153353.000,3940.6985,N,07544.9358,W,1,09,1.3,74.0,M,-33.8,M,,0000*58 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153353.000,A,3940.6985,N,07544.9358,W,0.10,73.57,230410,,*29 +{"class":"TPV","tag":"RMC","time":1272036833.000,"ept":0.005,"lat":39.678308333,"lon":-75.748930000,"alt":74.000,"epx":12.310,"epy":19.762,"epv":32.200,"track":73.5700,"speed":0.051,"climb":0.000,"mode":3} +$GPVTG,73.57,T,,M,0.10,N,0.2,K*55 +$GPZDA,153354.000,23,04,2010,,*55 +$GPGGA,153354.000,3940.6985,N,07544.9358,W,1,09,1.3,73.9,M,-33.8,M,,0000*51 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153354.000,A,3940.6985,N,07544.9358,W,0.06,86.02,230410,,*23 +{"class":"TPV","tag":"RMC","time":1272036834.000,"ept":0.005,"lat":39.678308333,"lon":-75.748930000,"alt":73.900,"epx":12.310,"epy":19.762,"epv":32.200,"track":86.0200,"speed":0.031,"climb":0.000,"mode":3} +$GPVTG,86.02,T,,M,0.06,N,0.1,K*5B +$GPZDA,153355.000,23,04,2010,,*54 +$GPGGA,153355.000,3940.6985,N,07544.9358,W,1,09,1.3,73.9,M,-33.8,M,,0000*50 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,270,40,21,73,256,40,24,66,289,38,18,58,312,45*7E +$GPGSV,3,2,12,27,51,116,44,15,47,048,40,09,46,136,40,22,26,291,19*7E +$GPGSV,3,3,12,06,13,303,,03,06,312,10,29,06,199,23,05,05,096,25*7F +{"class":"SKY","tag":"GSV","xdop":0.82,"ydop":1.32,"vdop":1.61,"tdop":1.30,"hdop":1.55,"gdop":2.59,"pdop":2.24,"satellites":[{"PRN":26,"el":82,"az":270,"ss":40,"used":true},{"PRN":21,"el":73,"az":256,"ss":40,"used":true},{"PRN":24,"el":66,"az":289,"ss":38,"used":true},{"PRN":18,"el":58,"az":312,"ss":45,"used":true},{"PRN":27,"el":51,"az":116,"ss":44,"used":true},{"PRN":15,"el":47,"az":48,"ss":40,"used":true},{"PRN":9,"el":46,"az":136,"ss":40,"used":true},{"PRN":22,"el":26,"az":291,"ss":19,"used":false},{"PRN":6,"el":13,"az":303,"ss":0,"used":false},{"PRN":3,"el":6,"az":312,"ss":10,"used":false},{"PRN":29,"el":6,"az":199,"ss":23,"used":true},{"PRN":5,"el":5,"az":96,"ss":25,"used":true}]} +$GPRMC,153355.000,A,3940.6985,N,07544.9358,W,0.11,71.30,230410,,*2D +{"class":"TPV","tag":"RMC","time":1272036835.000,"ept":0.005,"lat":39.678308333,"lon":-75.748930000,"alt":73.900,"epx":12.310,"epy":19.762,"epv":32.200,"track":71.3000,"speed":0.057,"climb":0.000,"mode":3} +$GPVTG,71.30,T,,M,0.11,N,0.2,K*57 +$GPZDA,153356.000,23,04,2010,,*57 +$GPGGA,153356.000,3940.6985,N,07544.9358,W,1,09,1.3,73.9,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153356.000,A,3940.6985,N,07544.9358,W,0.04,127.06,230410,,*1D +{"class":"TPV","tag":"RMC","time":1272036836.000,"ept":0.005,"lat":39.678308333,"lon":-75.748930000,"alt":73.900,"epx":12.310,"epy":19.762,"epv":37.112,"track":127.0600,"speed":0.021,"climb":0.000,"mode":3} +$GPVTG,127.06,T,,M,0.04,N,0.1,K*67 +$GPZDA,153357.000,23,04,2010,,*56 +$GPGGA,153357.000,3940.6985,N,07544.9358,W,1,09,1.3,73.7,M,-33.8,M,,0000*5C +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153357.000,A,3940.6985,N,07544.9358,W,0.09,191.66,230410,,*1A +{"class":"TPV","tag":"RMC","time":1272036837.000,"ept":0.005,"lat":39.678308333,"lon":-75.748930000,"alt":73.700,"epx":12.310,"epy":19.762,"epv":32.200,"track":191.6600,"speed":0.046,"climb":0.000,"mode":3} +$GPVTG,191.66,T,,M,0.09,N,0.2,K*62 +$GPZDA,153358.000,23,04,2010,,*59 +$GPGGA,153358.000,3940.6985,N,07544.9358,W,1,09,1.3,73.7,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153358.000,A,3940.6985,N,07544.9358,W,0.05,118.29,230410,,*13 +{"class":"TPV","tag":"RMC","time":1272036838.000,"ept":0.005,"lat":39.678308333,"lon":-75.748930000,"alt":73.700,"epx":12.310,"epy":19.762,"epv":32.200,"track":118.2900,"speed":0.026,"climb":0.000,"mode":3} +$GPVTG,118.29,T,,M,0.05,N,0.1,K*67 +$GPZDA,153359.000,23,04,2010,,*58 +$GPGGA,153359.000,3940.6985,N,07544.9359,W,1,09,1.3,73.2,M,-33.8,M,,0000*56 +$GPRMC,153359.000,A,3940.6985,N,07544.9359,W,0.12,206.85,230410,,*1F +{"class":"TPV","tag":"RMC","time":1272036839.000,"ept":0.005,"lat":39.678308333,"lon":-75.748931667,"alt":73.200,"epx":12.310,"epy":19.762,"epv":32.200,"track":206.8500,"speed":0.062,"climb":0.000,"mode":3} +$GPVTG,206.85,T,,M,0.12,N,0.2,K*68 +$GPZDA,153400.000,23,04,2010,,*53 +$GPGGA,153400.000,3940.6985,N,07544.9359,W,1,09,1.3,72.9,M,-33.8,M,,0000*57 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,270,39,21,73,256,39,24,66,289,39,18,58,312,45*7F +$GPGSV,3,2,12,27,51,116,43,15,47,048,30,09,46,136,42,22,26,291,14*71 +$GPGSV,3,3,12,06,13,303,27,03,06,312,,29,06,199,22,05,05,096,25*7A +{"class":"SKY","tag":"GSV","xdop":0.82,"ydop":1.32,"vdop":1.61,"tdop":1.30,"hdop":1.55,"gdop":2.59,"pdop":2.24,"satellites":[{"PRN":26,"el":82,"az":270,"ss":39,"used":true},{"PRN":21,"el":73,"az":256,"ss":39,"used":true},{"PRN":24,"el":66,"az":289,"ss":39,"used":true},{"PRN":18,"el":58,"az":312,"ss":45,"used":true},{"PRN":27,"el":51,"az":116,"ss":43,"used":true},{"PRN":15,"el":47,"az":48,"ss":30,"used":true},{"PRN":9,"el":46,"az":136,"ss":42,"used":true},{"PRN":22,"el":26,"az":291,"ss":14,"used":false},{"PRN":6,"el":13,"az":303,"ss":27,"used":false},{"PRN":3,"el":6,"az":312,"ss":0,"used":false},{"PRN":29,"el":6,"az":199,"ss":22,"used":true},{"PRN":5,"el":5,"az":96,"ss":25,"used":true}]} +$GPRMC,153400.000,A,3940.6985,N,07544.9359,W,0.19,205.81,230410,,*18 +{"class":"TPV","tag":"RMC","time":1272036840.000,"ept":0.005,"lat":39.678308333,"lon":-75.748931667,"alt":72.900,"epx":12.310,"epy":19.762,"epv":32.200,"track":205.8100,"speed":0.098,"climb":0.000,"mode":3} +$GPVTG,205.81,T,,M,0.19,N,0.3,K*65 +$GPZDA,153401.000,23,04,2010,,*52 +$GPGGA,153401.000,3940.6985,N,07544.9360,W,1,09,1.3,72.6,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153401.000,A,3940.6985,N,07544.9360,W,0.24,45.90,230410,,*2B +{"class":"TPV","tag":"RMC","time":1272036841.000,"ept":0.005,"lat":39.678308333,"lon":-75.748933333,"alt":72.600,"epx":12.310,"epy":19.762,"epv":37.112,"track":45.9000,"speed":0.123,"climb":0.000,"mode":3} +$GPVTG,45.90,T,,M,0.24,N,0.4,K*5A +$GPZDA,153402.000,23,04,2010,,*51 +$GPGGA,153402.000,3940.6985,N,07544.9360,W,1,09,1.3,72.4,M,-33.8,M,,0000*52 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153402.000,A,3940.6985,N,07544.9360,W,0.14,217.87,230410,,*18 +{"class":"TPV","tag":"RMC","time":1272036842.000,"ept":0.005,"lat":39.678308333,"lon":-75.748933333,"alt":72.400,"epx":12.310,"epy":19.762,"epv":32.200,"track":217.8700,"speed":0.072,"climb":0.000,"mode":3} +$GPVTG,217.87,T,,M,0.14,N,0.3,K*6D +$GPZDA,153403.000,23,04,2010,,*50 +$GPGGA,153403.000,3940.6985,N,07544.9360,W,1,09,1.3,72.3,M,-33.8,M,,0000*54 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153403.000,A,3940.6985,N,07544.9360,W,0.17,48.77,230410,,*2D +{"class":"TPV","tag":"RMC","time":1272036843.000,"ept":0.005,"lat":39.678308333,"lon":-75.748933333,"alt":72.300,"epx":12.310,"epy":19.762,"epv":32.200,"track":48.7700,"speed":0.087,"climb":0.000,"mode":3} +$GPVTG,48.77,T,,M,0.17,N,0.3,K*59 +$GPZDA,153404.000,23,04,2010,,*57 +$GPGGA,153404.000,3940.6985,N,07544.9360,W,1,09,1.3,72.3,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153404.000,A,3940.6985,N,07544.9360,W,0.12,198.25,230410,,*14 +{"class":"TPV","tag":"RMC","time":1272036844.000,"ept":0.005,"lat":39.678308333,"lon":-75.748933333,"alt":72.300,"epx":12.310,"epy":19.762,"epv":32.200,"track":198.2500,"speed":0.062,"climb":0.000,"mode":3} +$GPVTG,198.25,T,,M,0.12,N,0.2,K*66 +$GPZDA,153405.000,23,04,2010,,*56 +$GPGGA,153405.000,3940.6985,N,07544.9360,W,1,09,1.3,72.4,M,-33.8,M,,0000*55 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,270,39,21,73,256,38,24,66,289,39,18,58,312,44*7F +$GPGSV,3,2,12,27,51,116,43,15,47,048,37,09,46,136,41,22,26,291,11*70 +$GPGSV,3,3,12,06,13,303,28,03,06,312,,29,06,199,23,05,05,096,25*74 +{"class":"SKY","tag":"GSV","xdop":0.82,"ydop":1.32,"vdop":1.61,"tdop":1.30,"hdop":1.55,"gdop":2.59,"pdop":2.24,"satellites":[{"PRN":26,"el":82,"az":270,"ss":39,"used":true},{"PRN":21,"el":73,"az":256,"ss":38,"used":true},{"PRN":24,"el":66,"az":289,"ss":39,"used":true},{"PRN":18,"el":58,"az":312,"ss":44,"used":true},{"PRN":27,"el":51,"az":116,"ss":43,"used":true},{"PRN":15,"el":47,"az":48,"ss":37,"used":true},{"PRN":9,"el":46,"az":136,"ss":41,"used":true},{"PRN":22,"el":26,"az":291,"ss":11,"used":false},{"PRN":6,"el":13,"az":303,"ss":28,"used":false},{"PRN":3,"el":6,"az":312,"ss":0,"used":false},{"PRN":29,"el":6,"az":199,"ss":23,"used":true},{"PRN":5,"el":5,"az":96,"ss":25,"used":true}]} +$GPRMC,153405.000,A,3940.6985,N,07544.9360,W,0.21,205.69,230410,,*1A +{"class":"TPV","tag":"RMC","time":1272036845.000,"ept":0.005,"lat":39.678308333,"lon":-75.748933333,"alt":72.400,"epx":12.310,"epy":19.762,"epv":32.200,"track":205.6900,"speed":0.108,"climb":0.000,"mode":3} +$GPVTG,205.69,T,,M,0.21,N,0.4,K*6F +$GPZDA,153406.000,23,04,2010,,*55 +$GPGGA,153406.000,3940.6984,N,07544.9360,W,1,09,1.3,72.5,M,-33.8,M,,0000*56 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153406.000,A,3940.6984,N,07544.9360,W,0.11,198.24,230410,,*15 +{"class":"TPV","tag":"RMC","time":1272036846.000,"ept":0.005,"lat":39.678306667,"lon":-75.748933333,"alt":72.500,"epx":12.310,"epy":19.762,"epv":37.112,"track":198.2400,"speed":0.057,"climb":0.000,"mode":3} +$GPVTG,198.24,T,,M,0.11,N,0.2,K*64 +$GPZDA,153407.000,23,04,2010,,*54 +$GPGGA,153407.000,3940.6984,N,07544.9361,W,1,09,1.3,72.7,M,-33.8,M,,0000*54 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153407.000,A,3940.6984,N,07544.9361,W,0.09,185.69,230410,,*19 +{"class":"TPV","tag":"RMC","time":1272036847.000,"ept":0.005,"lat":39.678306667,"lon":-75.748935000,"alt":72.700,"epx":12.310,"epy":19.762,"epv":32.200,"track":185.6900,"speed":0.046,"climb":0.000,"mode":3} +$GPVTG,185.69,T,,M,0.09,N,0.2,K*68 +$GPZDA,153408.000,23,04,2010,,*5B +$GPGGA,153408.000,3940.6984,N,07544.9360,W,1,09,1.3,73.0,M,-33.8,M,,0000*5C +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153408.000,A,3940.6984,N,07544.9360,W,0.08,68.19,230410,,*23 +{"class":"TPV","tag":"RMC","time":1272036848.000,"ept":0.005,"lat":39.678306667,"lon":-75.748933333,"alt":73.000,"epx":12.310,"epy":19.762,"epv":32.200,"track":68.1900,"speed":0.041,"climb":0.000,"mode":3} +$GPVTG,68.19,T,,M,0.08,N,0.1,K*5F +$GPZDA,153409.000,23,04,2010,,*5A +$GPGGA,153409.000,3940.6984,N,07544.9360,W,1,09,1.3,72.8,M,-33.8,M,,0000*54 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153409.000,A,3940.6984,N,07544.9360,W,0.03,136.94,230410,,*16 +{"class":"TPV","tag":"RMC","time":1272036849.000,"ept":0.005,"lat":39.678306667,"lon":-75.748933333,"alt":72.800,"epx":12.310,"epy":19.762,"epv":32.200,"track":136.9400,"speed":0.015,"climb":0.000,"mode":3} +$GPVTG,136.94,T,,M,0.03,N,0.1,K*6B +$GPZDA,153410.000,23,04,2010,,*52 +$GPGGA,153410.000,3940.6985,N,07544.9360,W,1,09,1.3,72.6,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,270,39,21,73,256,37,24,66,289,40,18,58,312,44*7E +$GPGSV,3,2,12,27,51,116,43,15,47,048,40,09,46,136,42,22,26,291,13*71 +$GPGSV,3,3,12,06,13,303,,03,06,312,,29,06,199,24,05,05,096,24*78 +{"class":"SKY","tag":"GSV","xdop":0.82,"ydop":1.32,"vdop":1.61,"tdop":1.30,"hdop":1.55,"gdop":2.59,"pdop":2.24,"satellites":[{"PRN":26,"el":82,"az":270,"ss":39,"used":true},{"PRN":21,"el":73,"az":256,"ss":37,"used":true},{"PRN":24,"el":66,"az":289,"ss":40,"used":true},{"PRN":18,"el":58,"az":312,"ss":44,"used":true},{"PRN":27,"el":51,"az":116,"ss":43,"used":true},{"PRN":15,"el":47,"az":48,"ss":40,"used":true},{"PRN":9,"el":46,"az":136,"ss":42,"used":true},{"PRN":22,"el":26,"az":291,"ss":13,"used":false},{"PRN":6,"el":13,"az":303,"ss":0,"used":false},{"PRN":3,"el":6,"az":312,"ss":0,"used":false},{"PRN":29,"el":6,"az":199,"ss":24,"used":true},{"PRN":5,"el":5,"az":96,"ss":24,"used":true}]} +$GPRMC,153410.000,A,3940.6985,N,07544.9360,W,0.04,163.02,230410,,*17 +{"class":"TPV","tag":"RMC","time":1272036850.000,"ept":0.005,"lat":39.678308333,"lon":-75.748933333,"alt":72.600,"epx":12.310,"epy":19.762,"epv":32.200,"track":163.0200,"speed":0.021,"climb":0.000,"mode":3} +$GPZDA,153411.000,23,04,2010,,*53 +$GPGGA,153411.000,3940.6985,N,07544.9360,W,1,09,1.3,72.5,M,-33.8,M,,0000*51 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153411.000,A,3940.6985,N,07544.9360,W,0.09,55.20,230410,,*2F +{"class":"TPV","tag":"RMC","time":1272036851.000,"ept":0.005,"lat":39.678308333,"lon":-75.748933333,"alt":72.500,"epx":12.310,"epy":19.762,"epv":37.112,"track":55.2000,"speed":0.046,"climb":0.000,"mode":3} +$GPVTG,55.20,T,,M,0.09,N,0.2,K*59 +$GPZDA,153412.000,23,04,2010,,*50 +$GPGGA,153412.000,3940.6985,N,07544.9359,W,1,09,1.3,72.3,M,-33.8,M,,0000*5E +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153412.000,A,3940.6985,N,07544.9359,W,0.09,58.22,230410,,*29 +{"class":"TPV","tag":"RMC","time":1272036852.000,"ept":0.005,"lat":39.678308333,"lon":-75.748931667,"alt":72.300,"epx":12.310,"epy":19.762,"epv":32.200,"track":58.2200,"speed":0.046,"climb":0.000,"mode":3} +$GPVTG,58.22,T,,M,0.09,N,0.2,K*56 +$GPZDA,153413.000,23,04,2010,,*51 +$GPGGA,153413.000,3940.6986,N,07544.9359,W,1,09,1.3,72.1,M,-33.8,M,,0000*5E +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153413.000,A,3940.6986,N,07544.9359,W,0.13,65.66,230410,,*2E +{"class":"TPV","tag":"RMC","time":1272036853.000,"ept":0.005,"lat":39.678310000,"lon":-75.748931667,"alt":72.100,"epx":12.310,"epy":19.762,"epv":32.200,"track":65.6600,"speed":0.067,"climb":0.000,"mode":3} +$GPVTG,65.66,T,,M,0.13,N,0.2,K*53 +$GPZDA,153414.000,23,04,2010,,*56 +$GPGGA,153414.000,3940.6986,N,07544.9359,W,1,09,1.3,71.8,M,-33.8,M,,0000*53 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153414.000,A,3940.6986,N,07544.9359,W,0.06,72.14,230410,,*2E +{"class":"TPV","tag":"RMC","time":1272036854.000,"ept":0.005,"lat":39.678310000,"lon":-75.748931667,"alt":71.800,"epx":12.310,"epy":19.762,"epv":32.200,"track":72.1400,"speed":0.031,"climb":0.000,"mode":3} +$GPVTG,72.14,T,,M,0.06,N,0.1,K*57 +$GPZDA,153415.000,23,04,2010,,*57 +$GPGGA,153415.000,3940.6986,N,07544.9359,W,1,08,1.9,71.8,M,-33.8,M,,0000*59 +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPGSV,3,1,12,26,82,270,39,21,73,256,37,24,66,289,39,18,58,312,44*70 +$GPGSV,3,2,12,27,51,116,42,15,47,048,40,09,46,136,42,22,26,291,*72 +$GPGSV,3,3,12,06,13,303,27,03,06,312,,29,06,199,17,05,05,096,19*73 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.32,"vdop":2.18,"tdop":1.79,"hdop":1.56,"gdop":3.23,"pdop":2.68,"satellites":[{"PRN":26,"el":82,"az":270,"ss":39,"used":true},{"PRN":21,"el":73,"az":256,"ss":37,"used":true},{"PRN":24,"el":66,"az":289,"ss":39,"used":true},{"PRN":18,"el":58,"az":312,"ss":44,"used":true},{"PRN":27,"el":51,"az":116,"ss":42,"used":true},{"PRN":15,"el":47,"az":48,"ss":40,"used":true},{"PRN":9,"el":46,"az":136,"ss":42,"used":true},{"PRN":22,"el":26,"az":291,"ss":0,"used":false},{"PRN":6,"el":13,"az":303,"ss":27,"used":false},{"PRN":3,"el":6,"az":312,"ss":0,"used":false},{"PRN":29,"el":6,"az":199,"ss":17,"used":false},{"PRN":5,"el":5,"az":96,"ss":19,"used":true}]} +$GPRMC,153415.000,A,3940.6986,N,07544.9359,W,0.07,71.45,230410,,*29 +{"class":"TPV","tag":"RMC","time":1272036855.000,"ept":0.005,"lat":39.678310000,"lon":-75.748931667,"alt":71.800,"epx":12.310,"epy":19.762,"epv":32.200,"track":71.4500,"speed":0.036,"climb":0.000,"mode":3} +$GPVTG,71.45,T,,M,0.07,N,0.1,K*51 +$GPZDA,153416.000,23,04,2010,,*54 +$GPGGA,153416.000,3940.6986,N,07544.9359,W,1,08,1.9,71.9,M,-33.8,M,,0000*5B +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPRMC,153416.000,A,3940.6986,N,07544.9359,W,0.04,125.99,230410,,*18 +{"class":"TPV","tag":"RMC","time":1272036856.000,"ept":0.005,"lat":39.678310000,"lon":-75.748931667,"alt":71.900,"epx":12.488,"epy":19.838,"epv":50.214,"track":125.9900,"speed":0.021,"climb":0.000,"mode":3} +$GPVTG,125.99,T,,M,0.04,N,0.1,K*63 +$GPZDA,153417.000,23,04,2010,,*55 +$GPGGA,153417.000,3940.6986,N,07544.9359,W,1,09,1.3,71.6,M,-33.8,M,,0000*5E +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153417.000,A,3940.6986,N,07544.9359,W,0.16,60.22,230410,,*2A +{"class":"TPV","tag":"RMC","time":1272036857.000,"ept":0.005,"lat":39.678310000,"lon":-75.748931667,"alt":71.600,"epx":12.488,"epy":19.838,"epv":55.200,"track":60.2200,"speed":0.082,"climb":0.000,"mode":3} +$GPVTG,60.22,T,,M,0.16,N,0.3,K*52 +$GPZDA,153418.000,23,04,2010,,*5A +$GPGGA,153418.000,3940.6986,N,07544.9359,W,1,09,1.3,71.5,M,-33.8,M,,0000*52 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153418.000,A,3940.6986,N,07544.9359,W,0.04,108.21,230410,,*1A +{"class":"TPV","tag":"RMC","time":1272036858.000,"ept":0.005,"lat":39.678310000,"lon":-75.748931667,"alt":71.500,"epx":12.488,"epy":19.838,"epv":32.200,"track":108.2100,"speed":0.021,"climb":0.000,"mode":3} +$GPVTG,108.21,T,,M,0.04,N,0.1,K*6F +$GPZDA,153419.000,23,04,2010,,*5B +$GPGGA,153419.000,3940.6987,N,07544.9359,W,1,09,1.3,71.6,M,-33.8,M,,0000*51 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153419.000,A,3940.6987,N,07544.9359,W,0.32,53.50,230410,,*26 +{"class":"TPV","tag":"RMC","time":1272036859.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":71.600,"epx":12.488,"epy":19.838,"epv":32.200,"track":53.5000,"speed":0.165,"climb":0.000,"mode":3} +$GPVTG,53.50,T,,M,0.32,N,0.6,K*54 +$GPZDA,153420.000,23,04,2010,,*51 +$GPGGA,153420.000,3940.6987,N,07544.9358,W,1,09,1.3,71.8,M,-33.8,M,,0000*54 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,272,39,21,73,256,35,24,67,288,39,18,59,312,37*75 +$GPGSV,3,2,12,27,51,115,43,15,47,048,40,09,46,136,43,22,26,291,11*71 +$GPGSV,3,3,12,06,13,303,27,03,06,312,,29,06,199,17,14,05,232,*77 +{"class":"SKY","tag":"GSV","xdop":0.82,"ydop":1.32,"vdop":1.61,"tdop":1.29,"hdop":1.56,"gdop":2.58,"pdop":2.24,"satellites":[{"PRN":26,"el":82,"az":272,"ss":39,"used":true},{"PRN":21,"el":73,"az":256,"ss":35,"used":true},{"PRN":24,"el":67,"az":288,"ss":39,"used":true},{"PRN":18,"el":59,"az":312,"ss":37,"used":true},{"PRN":27,"el":51,"az":115,"ss":43,"used":true},{"PRN":15,"el":47,"az":48,"ss":40,"used":true},{"PRN":9,"el":46,"az":136,"ss":43,"used":true},{"PRN":22,"el":26,"az":291,"ss":11,"used":false},{"PRN":6,"el":13,"az":303,"ss":27,"used":false},{"PRN":3,"el":6,"az":312,"ss":0,"used":false},{"PRN":29,"el":6,"az":199,"ss":17,"used":true},{"PRN":14,"el":5,"az":232,"ss":0,"used":false}]} +$GPRMC,153420.000,A,3940.6987,N,07544.9358,W,0.31,53.43,230410,,*2C +{"class":"TPV","tag":"RMC","time":1272036860.000,"ept":0.005,"lat":39.678311667,"lon":-75.748930000,"alt":71.800,"epx":12.488,"epy":19.838,"epv":32.200,"track":53.4300,"speed":0.159,"climb":0.000,"mode":3} +$GPVTG,53.43,T,,M,0.31,N,0.6,K*55 +$GPZDA,153421.000,23,04,2010,,*50 +$GPGGA,153421.000,3940.6988,N,07544.9357,W,1,09,1.3,71.6,M,-33.8,M,,0000*5B +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153421.000,A,3940.6988,N,07544.9357,W,0.31,59.72,230410,,*25 +{"class":"TPV","tag":"RMC","time":1272036861.000,"ept":0.005,"lat":39.678313333,"lon":-75.748928333,"alt":71.600,"epx":12.276,"epy":19.848,"epv":36.942,"track":59.7200,"speed":0.159,"climb":0.000,"mode":3} +$GPVTG,59.72,T,,M,0.31,N,0.6,K*5D +$GPZDA,153422.000,23,04,2010,,*53 +$GPGGA,153422.000,3940.6988,N,07544.9357,W,1,09,1.3,71.5,M,-33.8,M,,0000*5B +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153422.000,A,3940.6988,N,07544.9357,W,0.06,123.72,230410,,*1E +{"class":"TPV","tag":"RMC","time":1272036862.000,"ept":0.005,"lat":39.678313333,"lon":-75.748928333,"alt":71.500,"epx":12.276,"epy":19.848,"epv":32.200,"track":123.7200,"speed":0.031,"climb":0.000,"mode":3} +$GPVTG,123.72,T,,M,0.06,N,0.1,K*62 +$GPZDA,153423.000,23,04,2010,,*52 +$GPGGA,153423.000,3940.6988,N,07544.9358,W,1,09,1.3,71.2,M,-33.8,M,,0000*52 +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPVTG,129.63,T,,M,0.08,N,0.1,K*66 +$GPZDA,153424.000,23,04,2010,,*55 +$GPGGA,153424.000,3940.6987,N,07544.9358,W,1,09,1.3,71.1,M,-33.8,M,,0000*59 +{"class":"TPV","tag":"GGA","time":1272036864.000,"ept":0.005,"lat":39.678311667,"lon":-75.748930000,"alt":71.100,"epx":12.276,"epy":19.848,"epv":32.200,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153424.000,A,3940.6987,N,07544.9358,W,0.07,100.77,230410,,*1D +{"class":"TPV","tag":"RMC","time":1272036864.000,"ept":0.005,"lat":39.678311667,"lon":-75.748930000,"alt":71.100,"epx":12.276,"epy":19.848,"epv":32.200,"track":100.7700,"speed":0.036,"climb":0.000,"mode":3} +$GPVTG,100.77,T,,M,0.07,N,0.1,K*67 +$GPZDA,153425.000,23,04,2010,,*54 +$GPGGA,153425.000,3940.6987,N,07544.9359,W,1,09,1.3,70.9,M,-33.8,M,,0000*50 +{"class":"TPV","tag":"GGA","time":1272036865.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":70.900,"epx":12.276,"epy":19.848,"epv":32.200,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,272,39,21,73,256,36,24,67,288,38,18,59,312,42*75 +$GPGSV,3,2,12,27,51,115,42,15,47,048,40,09,46,136,43,22,26,291,07*77 +$GPGSV,3,3,12,06,13,303,,03,06,312,12,29,06,199,25,14,05,232,*70 +{"class":"SKY","tag":"GSV","xdop":0.82,"ydop":1.32,"vdop":1.61,"tdop":1.29,"hdop":1.56,"gdop":2.58,"pdop":2.24,"satellites":[{"PRN":26,"el":82,"az":272,"ss":39,"used":true},{"PRN":21,"el":73,"az":256,"ss":36,"used":true},{"PRN":24,"el":67,"az":288,"ss":38,"used":true},{"PRN":18,"el":59,"az":312,"ss":42,"used":true},{"PRN":27,"el":51,"az":115,"ss":42,"used":true},{"PRN":15,"el":47,"az":48,"ss":40,"used":true},{"PRN":9,"el":46,"az":136,"ss":43,"used":true},{"PRN":22,"el":26,"az":291,"ss":7,"used":false},{"PRN":6,"el":13,"az":303,"ss":0,"used":false},{"PRN":3,"el":6,"az":312,"ss":12,"used":false},{"PRN":29,"el":6,"az":199,"ss":25,"used":true},{"PRN":14,"el":5,"az":232,"ss":0,"used":false}]} +$GPRMC,153425.000,A,3940.6987,N,07544.9359,W,0.10,89.40,230410,,*2F +{"class":"TPV","tag":"RMC","time":1272036865.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":70.900,"epx":12.276,"epy":19.848,"epv":32.200,"track":89.4000,"speed":0.051,"climb":0.000,"mode":3} +$GPVTG,89.40,T,,M,0.10,N,0.2,K*56 +$GPZDA,153426.000,23,04,2010,,*57 +$GPGGA,153426.000,3940.6987,N,07544.9359,W,1,09,1.3,70.4,M,-33.8,M,,0000*5E +{"class":"TPV","tag":"GGA","time":1272036866.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":70.400,"epx":12.276,"epy":19.848,"epv":36.942,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153426.000,A,3940.6987,N,07544.9359,W,0.15,63.07,230410,,*2E +{"class":"TPV","tag":"RMC","time":1272036866.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":70.400,"epx":12.276,"epy":19.848,"epv":36.942,"track":63.0700,"speed":0.077,"climb":0.000,"mode":3} +$GPVTG,63.07,T,,M,0.15,N,0.3,K*55 +$GPZDA,153427.000,23,04,2010,,*56 +$GPGGA,153427.000,3940.6987,N,07544.9359,W,1,08,1.9,70.5,M,-33.8,M,,0000*55 +{"class":"TPV","tag":"GGA","time":1272036867.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":70.500,"epx":12.276,"epy":19.848,"epv":32.200,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPRMC,153427.000,A,3940.6987,N,07544.9359,W,0.14,65.26,230410,,*2B +{"class":"TPV","tag":"RMC","time":1272036867.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":70.500,"epx":12.276,"epy":19.848,"epv":32.200,"track":65.2600,"speed":0.072,"climb":0.000,"mode":3} +$GPVTG,65.26,T,,M,0.14,N,0.3,K*51 +$GPZDA,153428.000,23,04,2010,,*59 +$GPGGA,153428.000,3940.6987,N,07544.9359,W,1,08,1.9,70.7,M,-33.8,M,,0000*58 +{"class":"TPV","tag":"GGA","time":1272036868.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":70.700,"epx":12.276,"epy":19.848,"epv":55.200,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPRMC,153428.000,A,3940.6987,N,07544.9359,W,0.10,75.11,230410,,*25 +{"class":"TPV","tag":"RMC","time":1272036868.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":70.700,"epx":12.276,"epy":19.848,"epv":55.200,"track":75.1100,"speed":0.051,"climb":0.000,"mode":3} +$GPVTG,75.11,T,,M,0.10,N,0.2,K*51 +$GPZDA,153429.000,23,04,2010,,*58 +$GPGGA,153429.000,3940.6987,N,07544.9359,W,1,09,1.3,70.1,M,-33.8,M,,0000*54 +{"class":"TPV","tag":"GGA","time":1272036869.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":70.100,"epx":12.276,"epy":19.848,"epv":55.200,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153429.000,A,3940.6987,N,07544.9359,W,0.13,65.02,230410,,*24 +{"class":"TPV","tag":"RMC","time":1272036869.000,"ept":0.005,"lat":39.678311667,"lon":-75.748931667,"alt":70.100,"epx":12.276,"epy":19.848,"epv":55.200,"track":65.0200,"speed":0.067,"climb":0.000,"mode":3} +$GPVTG,65.02,T,,M,0.13,N,0.2,K*51 +$GPZDA,153430.000,23,04,2010,,*50 +$GPGGA,153430.000,3940.6987,N,07544.9360,W,1,09,1.3,69.6,M,-33.8,M,,0000*59 +{"class":"TPV","tag":"GGA","time":1272036870.000,"ept":0.005,"lat":39.678311667,"lon":-75.748933333,"alt":69.600,"epx":12.276,"epy":19.848,"epv":32.200,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPGSV,3,1,12,26,82,272,39,21,73,256,36,24,67,288,37,18,59,312,42*7A +$GPGSV,3,2,12,27,51,115,42,15,47,048,39,09,46,136,43,22,26,291,*7E +$GPGSV,3,3,12,06,13,303,27,03,06,312,,29,06,199,13,14,05,232,*73 +{"class":"SKY","tag":"GSV","xdop":0.82,"ydop":1.32,"vdop":1.61,"tdop":1.29,"hdop":1.56,"gdop":2.58,"pdop":2.24,"satellites":[{"PRN":26,"el":82,"az":272,"ss":39,"used":true},{"PRN":21,"el":73,"az":256,"ss":36,"used":true},{"PRN":24,"el":67,"az":288,"ss":37,"used":true},{"PRN":18,"el":59,"az":312,"ss":42,"used":true},{"PRN":27,"el":51,"az":115,"ss":42,"used":true},{"PRN":15,"el":47,"az":48,"ss":39,"used":true},{"PRN":9,"el":46,"az":136,"ss":43,"used":true},{"PRN":22,"el":26,"az":291,"ss":0,"used":false},{"PRN":6,"el":13,"az":303,"ss":27,"used":false},{"PRN":3,"el":6,"az":312,"ss":0,"used":false},{"PRN":29,"el":6,"az":199,"ss":13,"used":true},{"PRN":14,"el":5,"az":232,"ss":0,"used":false}]} +$GPRMC,153430.000,A,3940.6987,N,07544.9360,W,0.09,67.21,230410,,*2E +{"class":"TPV","tag":"RMC","time":1272036870.000,"ept":0.005,"lat":39.678311667,"lon":-75.748933333,"alt":69.600,"epx":12.276,"epy":19.848,"epv":32.200,"track":67.2100,"speed":0.046,"climb":0.000,"mode":3} +$GPVTG,67.21,T,,M,0.09,N,0.2,K*59 +$GPZDA,153431.000,23,04,2010,,*51 +$GPGGA,153431.000,3940.6987,N,07544.9361,W,1,09,1.3,69.4,M,-33.8,M,,0000*5B +{"class":"TPV","tag":"GGA","time":1272036871.000,"ept":0.005,"lat":39.678311667,"lon":-75.748935000,"alt":69.400,"epx":12.276,"epy":19.848,"epv":36.942,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153431.000,A,3940.6987,N,07544.9361,W,0.06,167.61,230410,,*14 +{"class":"TPV","tag":"RMC","time":1272036871.000,"ept":0.005,"lat":39.678311667,"lon":-75.748935000,"alt":69.400,"epx":12.276,"epy":19.848,"epv":36.942,"track":167.6100,"speed":0.031,"climb":0.000,"mode":3} +$GPVTG,167.61,T,,M,0.06,N,0.1,K*60 +$GPZDA,153432.000,23,04,2010,,*52 +$GPGGA,153432.000,3940.6986,N,07544.9362,W,1,09,1.3,68.9,M,-33.8,M,,0000*56 +{"class":"TPV","tag":"GGA","time":1272036872.000,"ept":0.005,"lat":39.678310000,"lon":-75.748936667,"alt":68.900,"epx":12.276,"epy":19.848,"epv":32.200,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,29,,,,1.9,1.3,1.4*33 +$GPRMC,153432.000,A,3940.6986,N,07544.9362,W,0.15,61.34,230410,,*20 +{"class":"TPV","tag":"RMC","time":1272036872.000,"ept":0.005,"lat":39.678310000,"lon":-75.748936667,"alt":68.900,"epx":12.276,"epy":19.848,"epv":32.200,"track":61.3400,"speed":0.077,"climb":0.000,"mode":3} +$GPVTG,61.34,T,,M,0.15,N,0.3,K*57 +$GPZDA,153433.000,23,04,2010,,*53 +$GPGGA,153433.000,3940.6987,N,07544.9362,W,1,08,1.9,69.0,M,-33.8,M,,0000*55 +{"class":"TPV","tag":"GGA","time":1272036873.000,"ept":0.005,"lat":39.678311667,"lon":-75.748936667,"alt":69.000,"epx":12.276,"epy":19.848,"epv":32.200,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPRMC,153433.000,A,3940.6987,N,07544.9362,W,0.06,83.09,230410,,*20 +{"class":"TPV","tag":"RMC","time":1272036873.000,"ept":0.005,"lat":39.678311667,"lon":-75.748936667,"alt":69.000,"epx":12.276,"epy":19.848,"epv":32.200,"track":83.0900,"speed":0.031,"climb":0.000,"mode":3} +$GPVTG,83.09,T,,M,0.06,N,0.1,K*55 +$GPZDA,153434.000,23,04,2010,,*54 +$GPGGA,153434.000,3940.6987,N,07544.9361,W,1,08,1.9,69.2,M,-33.8,M,,0000*53 +{"class":"TPV","tag":"GGA","time":1272036874.000,"ept":0.005,"lat":39.678311667,"lon":-75.748935000,"alt":69.200,"epx":12.276,"epy":19.848,"epv":55.200,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPRMC,153434.000,A,3940.6987,N,07544.9361,W,0.09,68.77,230410,,*27 +{"class":"TPV","tag":"RMC","time":1272036874.000,"ept":0.005,"lat":39.678311667,"lon":-75.748935000,"alt":69.200,"epx":12.276,"epy":19.848,"epv":55.200,"track":68.7700,"speed":0.046,"climb":0.000,"mode":3} +$GPVTG,68.77,T,,M,0.09,N,0.2,K*55 +$GPZDA,153435.000,23,04,2010,,*55 +$GPGGA,153435.000,3940.6987,N,07544.9361,W,1,08,1.9,69.5,M,-33.8,M,,0000*55 +{"class":"TPV","tag":"GGA","time":1272036875.000,"ept":0.005,"lat":39.678311667,"lon":-75.748935000,"alt":69.500,"epx":12.276,"epy":19.848,"epv":55.200,"speed":0.000,"climb":0.000,"mode":3} +$GPGSA,A,3,26,15,21,27,24,09,18,05,,,,,3.0,1.9,2.4*3A +$GPGSV,3,1,12,26,82,272,39,21,73,256,37,24,67,288,38,18,59,312,42*74 +$GPGSV,3,2,12,27,51,115,42,15,47,048,39,09,46,136,43,22,26,291,*7E +$GPGSV,3,3,12,06,13,303,27,03,06,312,12,29,06,199,,14,05,232,*72 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.33,"vdop":2.17,"tdop":1.78,"hdop":1.57,"gdop":3.21,"pdop":2.68,"satellites":[{"PRN":26,"el":82,"az":272,"ss":39,"used":true},{"PRN":21,"el":73,"az":256,"ss":37,"used":true},{"PRN":24,"el":67,"az":288,"ss":38,"used":true},{"PRN":18,"el":59,"az":312,"ss":42,"used":true},{"PRN":27,"el":51,"az":115,"ss":42,"used":true},{"PRN":15,"el":47,"az":48,"ss":39,"used":true},{"PRN":9,"el":46,"az":136,"ss":43,"used":true},{"PRN":22,"el":26,"az":291,"ss":0,"used":false},{"PRN":6,"el":13,"az":303,"ss":27,"used":false},{"PRN":3,"el":6,"az":312,"ss":12,"used":false},{"PRN":29,"el":6,"az":199,"ss":0,"used":false},{"PRN":14,"el":5,"az":232,"ss":0,"used":false}]} diff --git a/test/daemon/firefly-II.log b/test/daemon/firefly-II.log new file mode 100644 index 0000000..4f758ec --- /dev/null +++ b/test/daemon/firefly-II.log @@ -0,0 +1,248 @@ +# Name: Firefly-IIa +# Chipset: UBLOX NEO-5Q +# Submitted-by: Said Jackson +# Date: July 7th, 2010 +# Location: Los Gatos, CA, 170 Knowles Drive +$GPGGA,005947.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*54 +$GPRMC,005947.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2F +$GPZDA,005947.00,08,07,2010,+00,00*4E +$GPGGA,005948.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*5B +$GPRMC,005948.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*20 +$GPZDA,005948.00,08,07,2010,+00,00*41 +$GPGGA,005949.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*5A +$GPRMC,005949.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*21 +$GPZDA,005949.00,08,07,2010,+00,00*40 +$GPGGA,005950.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*52 +$GPRMC,005950.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*29 +$GPZDA,005950.00,08,07,2010,+00,00*48 +$GPGGA,005951.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*53 +$GPRMC,005951.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*28 +$GPZDA,005951.00,08,07,2010,+00,00*49 +$GPGGA,005952.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*50 +$GPRMC,005952.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2B +$GPZDA,005952.00,08,07,2010,+00,00*4A +$GPGGA,005953.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*51 +$GPRMC,005953.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2A +$GPZDA,005953.00,08,07,2010,+00,00*4B +$GPGGA,005954.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*56 +$GPRMC,005954.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2D +$GPZDA,005954.00,08,07,2010,+00,00*4C +$GPGGA,005955.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*57 +$GPRMC,005955.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2C +$GPZDA,005955.00,08,07,2010,+00,00*4D +$GPGGA,005956.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*54 +$GPRMC,005956.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2F +$GPZDA,005956.00,08,07,2010,+00,00*4E +$GPGGA,005957.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*55 +$GPRMC,005957.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2E +$GPZDA,005957.00,08,07,2010,+00,00*4F +$GPGGA,005958.00,3715.6616,N,12157.6709,W,,11,0.8,86.0,M,-30.1,M,,*5A +$GPRMC,005958.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*21 +$GPZDA,005958.00,08,07,2010,+00,00*40 +$GPGGA,005959.00,3715.6614,N,12157.6699,W,,11,0.8,85.9,M,-30.1,M,,*5B +$GPRMC,005959.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2A +$GPZDA,005959.00,08,07,2010,+00,00*41 +$GPGGA,010000.00,3715.6614,N,12157.6699,W,,11,0.8,85.7,M,-30.1,M,,*54 +$GPRMC,010000.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2B +$GPZDA,010000.00,08,07,2010,+00,00*40 +$GPGGA,010001.00,3715.6614,N,12157.6699,W,,11,0.8,85.7,M,-30.1,M,,*55 +$GPRMC,010001.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2A +$GPZDA,010001.00,08,07,2010,+00,00*41 +$GPGGA,010002.00,3715.6614,N,12157.6699,W,,11,0.8,85.7,M,-30.1,M,,*56 +$GPRMC,010002.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*29 +$GPZDA,010002.00,08,07,2010,+00,00*42 +$GPGGA,010003.00,3715.6614,N,12157.6699,W,,11,0.8,85.7,M,-30.1,M,,*57 +$GPRMC,010003.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*28 +$GPZDA,010003.00,08,07,2010,+00,00*43 +$GPGGA,010004.00,3715.6614,N,12157.6699,W,,11,0.8,85.7,M,-30.1,M,,*50 +$GPRMC,010004.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2F +$GPZDA,010004.00,08,07,2010,+00,00*44 +$GPGGA,010005.00,3715.6614,N,12157.6699,W,,11,0.8,85.7,M,-30.1,M,,*51 +$GPRMC,010005.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2E +$GPZDA,010005.00,08,07,2010,+00,00*45 +$GPGGA,010006.00,3715.6614,N,12157.6699,W,,11,0.8,85.7,M,-30.1,M,,*52 +$GPRMC,010006.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2D +$GPZDA,010006.00,08,07,2010,+00,00*46 +$GPGGA,010007.00,3715.6614,N,12157.6699,W,,11,0.8,85.7,M,-30.1,M,,*53 +$GPRMC,010007.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2C +$GPZDA,010007.00,08,07,2010,+00,00*47 +$GPGGA,010008.00,3715.6611,N,12157.6699,W,,11,0.8,85.4,M,-30.1,M,,*5A +$GPRMC,010008.00,A,3715.6611,N,12157.6699,W,0.0,0.0,080710,,*26 +$GPZDA,010008.00,08,07,2010,+00,00*48 +$GPGGA,010009.00,3715.6609,N,12157.6699,W,,11,0.8,85.4,M,-30.1,M,,*52 +$GPRMC,010009.00,A,3715.6609,N,12157.6699,W,0.0,0.0,080710,,*2E +$GPZDA,010009.00,08,07,2010,+00,00*49 +$GPGGA,010010.00,3715.6609,N,12157.6699,W,,11,0.8,85.3,M,-30.1,M,,*5D +$GPRMC,010010.00,A,3715.6609,N,12157.6699,W,0.0,0.0,080710,,*26 +$GPZDA,010010.00,08,07,2010,+00,00*41 +$GPGGA,010011.00,3715.6606,N,12157.6699,W,,11,0.8,85.2,M,-30.1,M,,*52 +$GPRMC,010011.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*28 +$GPZDA,010011.00,08,07,2010,+00,00*40 +$GPGGA,010012.00,3715.6606,N,12157.6699,W,,11,0.8,85.1,M,-30.1,M,,*52 +$GPRMC,010012.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*2B +$GPZDA,010012.00,08,07,2010,+00,00*43 +$GPGGA,010013.00,3715.6606,N,12157.6699,W,,11,0.8,85.1,M,-30.1,M,,*53 +$GPRMC,010013.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*2A +$GPZDA,010013.00,08,07,2010,+00,00*42 +$GPGGA,010014.00,3715.6606,N,12157.6699,W,,11,0.8,85.1,M,-30.1,M,,*54 +$GPRMC,010014.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*2D +$GPZDA,010014.00,08,07,2010,+00,00*45 +$GPGGA,010015.00,3715.6606,N,12157.6699,W,,11,0.8,85.0,M,-30.1,M,,*54 +$GPRMC,010015.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*2C +$GPZDA,010015.00,08,07,2010,+00,00*44 +$GPGGA,010016.00,3715.6606,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*5F +$GPRMC,010016.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*2F +$GPZDA,010016.00,08,07,2010,+00,00*47 +$GPGGA,010017.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*5C +$GPRMC,010017.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2C +$GPZDA,010017.00,08,07,2010,+00,00*46 +$GPGGA,010018.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*53 +$GPRMC,010018.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*23 +$GPZDA,010018.00,08,07,2010,+00,00*49 +$GPGGA,010019.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*52 +$GPRMC,010019.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*22 +$GPZDA,010019.00,08,07,2010,+00,00*48 +$GPGGA,010020.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*58 +$GPRMC,010020.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*28 +$GPZDA,010020.00,08,07,2010,+00,00*42 +$GPGGA,010021.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*59 +$GPRMC,010021.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*29 +$GPZDA,010021.00,08,07,2010,+00,00*43 +$GPGGA,010022.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*5A +$GPRMC,010022.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2A +$GPZDA,010022.00,08,07,2010,+00,00*40 +$GPGGA,010023.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*5B +$GPRMC,010023.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2B +$GPZDA,010023.00,08,07,2010,+00,00*41 +$GPGGA,010024.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*5C +$GPRMC,010024.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2C +$GPZDA,010024.00,08,07,2010,+00,00*46 +$GPGGA,010025.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*5D +$GPRMC,010025.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2D +$GPZDA,010025.00,08,07,2010,+00,00*47 +$GPGGA,010026.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*5E +$GPRMC,010026.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2E +$GPZDA,010026.00,08,07,2010,+00,00*44 +$GPGGA,010027.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*5F +$GPRMC,010027.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2F +$GPZDA,010027.00,08,07,2010,+00,00*45 +$GPGGA,010028.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*50 +$GPRMC,010028.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*20 +$GPZDA,010028.00,08,07,2010,+00,00*4A +$GPGGA,010029.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*51 +$GPRMC,010029.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*21 +$GPZDA,010029.00,08,07,2010,+00,00*4B +$GPGGA,010030.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*59 +$GPRMC,010030.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*29 +$GPZDA,010030.00,08,07,2010,+00,00*43 +$GPGGA,010031.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*58 +$GPRMC,010031.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*28 +$GPZDA,010031.00,08,07,2010,+00,00*42 +$GPGGA,010032.00,3715.6604,N,12157.6699,W,,11,0.8,84.9,M,-30.1,M,,*5B +$GPRMC,010032.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2B +$GPZDA,010032.00,08,07,2010,+00,00*41 +$GPGGA,010033.00,3715.6604,N,12157.6699,W,,11,0.8,85.2,M,-30.1,M,,*50 +$GPRMC,010033.00,A,3715.6604,N,12157.6699,W,0.1,0.0,080710,,*2B +$GPZDA,010033.00,08,07,2010,+00,00*40 +$GPGGA,010034.00,3715.6604,N,12157.6699,W,,11,0.8,85.5,M,-30.1,M,,*50 +$GPRMC,010034.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2D +$GPZDA,010034.00,08,07,2010,+00,00*47 +$GPGGA,010035.00,3715.6604,N,12157.6699,W,,11,0.8,85.6,M,-30.1,M,,*52 +$GPRMC,010035.00,A,3715.6604,N,12157.6699,W,0.1,0.0,080710,,*2D +$GPZDA,010035.00,08,07,2010,+00,00*46 +$GPGGA,010036.00,3715.6604,N,12157.6699,W,,11,0.8,85.7,M,-30.1,M,,*50 +$GPRMC,010036.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2F +$GPZDA,010036.00,08,07,2010,+00,00*45 +$GPGGA,010037.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*5E +$GPRMC,010037.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2E +$GPZDA,010037.00,08,07,2010,+00,00*44 +$GPGGA,010038.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*51 +$GPRMC,010038.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*21 +$GPZDA,010038.00,08,07,2010,+00,00*4B +$GPGGA,010039.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*50 +$GPRMC,010039.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*20 +$GPZDA,010039.00,08,07,2010,+00,00*4A +$GPGGA,010040.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*5E +$GPRMC,010040.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2E +$GPZDA,010040.00,08,07,2010,+00,00*44 +$GPGGA,010041.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*5F +$GPRMC,010041.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2F +$GPZDA,010041.00,08,07,2010,+00,00*45 +$GPGGA,010042.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*5C +$GPRMC,010042.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2C +$GPZDA,010042.00,08,07,2010,+00,00*46 +$GPGGA,010043.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*5D +$GPRMC,010043.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2D +$GPZDA,010043.00,08,07,2010,+00,00*47 +$GPGGA,010044.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*5A +$GPRMC,010044.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2A +$GPZDA,010044.00,08,07,2010,+00,00*40 +$GPGGA,010045.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*5B +$GPRMC,010045.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2B +$GPZDA,010045.00,08,07,2010,+00,00*41 +$GPGGA,010046.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*58 +$GPRMC,010046.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*28 +$GPZDA,010046.00,08,07,2010,+00,00*42 +$GPGGA,010047.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*59 +$GPRMC,010047.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*29 +$GPZDA,010047.00,08,07,2010,+00,00*43 +$GPGGA,010048.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*56 +$GPRMC,010048.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*26 +$GPZDA,010048.00,08,07,2010,+00,00*4C +$GPGGA,010049.00,3715.6604,N,12157.6699,W,,11,0.8,85.8,M,-30.1,M,,*57 +$GPRMC,010049.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*27 +$GPZDA,010049.00,08,07,2010,+00,00*4D +$GPGGA,010050.00,3715.6609,N,12157.6699,W,,11,0.8,86.0,M,-30.1,M,,*59 +$GPRMC,010050.00,A,3715.6609,N,12157.6699,W,0.0,0.0,080710,,*22 +$GPZDA,010050.00,08,07,2010,+00,00*45 +$GPGGA,010051.00,3715.6609,N,12157.6699,W,,11,0.8,86.0,M,-30.1,M,,*58 +$GPRMC,010051.00,A,3715.6609,N,12157.6699,W,0.0,0.0,080710,,*23 +$GPZDA,010051.00,08,07,2010,+00,00*44 +$GPGGA,010052.00,3715.6611,N,12157.6699,W,,11,0.8,86.1,M,-30.1,M,,*53 +$GPRMC,010052.00,A,3715.6611,N,12157.6699,W,0.0,0.0,080710,,*29 +$GPZDA,010052.00,08,07,2010,+00,00*47 +$GPGGA,010053.00,3715.6611,N,12157.6699,W,,11,0.8,86.1,M,-30.1,M,,*52 +$GPRMC,010053.00,A,3715.6611,N,12157.6699,W,0.0,0.0,080710,,*28 +$GPZDA,010053.00,08,07,2010,+00,00*46 +$GPGGA,010054.00,3715.6611,N,12157.6699,W,,11,0.8,86.0,M,-30.1,M,,*54 +$GPRMC,010054.00,A,3715.6611,N,12157.6699,W,0.1,0.0,080710,,*2E +$GPZDA,010054.00,08,07,2010,+00,00*41 +$GPGGA,010055.00,3715.6611,N,12157.6689,W,,11,0.8,86.2,M,-30.1,M,,*56 +$GPRMC,010055.00,A,3715.6611,N,12157.6689,W,0.1,0.0,080710,,*2E +$GPZDA,010055.00,08,07,2010,+00,00*40 +$GPGGA,010056.00,3715.6611,N,12157.6689,W,,11,0.8,86.4,M,-30.1,M,,*53 +$GPRMC,010056.00,A,3715.6611,N,12157.6689,W,0.1,0.0,080710,,*2D +$GPZDA,010056.00,08,07,2010,+00,00*43 +$GPGGA,010057.00,3715.6614,N,12157.6689,W,,11,0.8,86.6,M,-30.1,M,,*55 +$GPRMC,010057.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*28 +$GPZDA,010057.00,08,07,2010,+00,00*42 +$GPGGA,010058.00,3715.6614,N,12157.6689,W,,11,0.8,86.7,M,-30.1,M,,*5B +$GPRMC,010058.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*27 +$GPZDA,010058.00,08,07,2010,+00,00*4D +$GPGGA,010059.00,3715.6614,N,12157.6689,W,,11,0.8,86.7,M,-30.1,M,,*5A +$GPRMC,010059.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*26 +$GPZDA,010059.00,08,07,2010,+00,00*4C +$GPGGA,010100.00,3715.6614,N,12157.6689,W,,11,0.8,86.7,M,-30.1,M,,*57 +$GPRMC,010100.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2B +$GPZDA,010100.00,08,07,2010,+00,00*41 +$GPGGA,010101.00,3715.6614,N,12157.6689,W,,11,0.8,86.7,M,-30.1,M,,*56 +$GPRMC,010101.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2A +$GPZDA,010101.00,08,07,2010,+00,00*40 +$GPGGA,010102.00,3715.6614,N,12157.6689,W,,11,0.8,86.7,M,-30.1,M,,*55 +$GPRMC,010102.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*29 +$GPZDA,010102.00,08,07,2010,+00,00*43 +$GPGGA,010103.00,3715.6614,N,12157.6689,W,,11,0.8,86.7,M,-30.1,M,,*54 +$GPRMC,010103.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*28 +$GPZDA,010103.00,08,07,2010,+00,00*42 +$GPGGA,010104.00,3715.6614,N,12157.6689,W,,11,0.8,86.7,M,-30.1,M,,*53 +$GPRMC,010104.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2F +$GPZDA,010104.00,08,07,2010,+00,00*45 +$GPGGA,010105.00,3715.6614,N,12157.6689,W,,11,0.8,86.7,M,-30.1,M,,*52 +$GPRMC,010105.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2E +$GPZDA,010105.00,08,07,2010,+00,00*44 +$GPGGA,010106.00,3715.6614,N,12157.6689,W,,11,0.8,86.7,M,-30.1,M,,*51 +$GPRMC,010106.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2D +$GPZDA,010106.00,08,07,2010,+00,00*47 +$GPGGA,010107.00,3715.6614,N,12157.6689,W,,11,0.8,86.7,M,-30.1,M,,*50 +$GPRMC,010107.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2C +$GPZDA,010107.00,08,07,2010,+00,00*46 diff --git a/test/daemon/firefly-II.log.chk b/test/daemon/firefly-II.log.chk new file mode 100644 index 0000000..7114311 --- /dev/null +++ b/test/daemon/firefly-II.log.chk @@ -0,0 +1,243 @@ +$GPRMC,005947.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2F +{"class":"TPV","tag":"RMC","time":1278550787.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005947.00,08,07,2010,+00,00*4E +$GPRMC,005948.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*20 +{"class":"TPV","tag":"RMC","time":1278550788.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005948.00,08,07,2010,+00,00*41 +$GPRMC,005949.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*21 +{"class":"TPV","tag":"RMC","time":1278550789.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005949.00,08,07,2010,+00,00*40 +$GPRMC,005950.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*29 +{"class":"TPV","tag":"RMC","time":1278550790.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005950.00,08,07,2010,+00,00*48 +$GPRMC,005951.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*28 +{"class":"TPV","tag":"RMC","time":1278550791.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005951.00,08,07,2010,+00,00*49 +$GPRMC,005952.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2B +{"class":"TPV","tag":"RMC","time":1278550792.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005952.00,08,07,2010,+00,00*4A +$GPRMC,005953.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2A +{"class":"TPV","tag":"RMC","time":1278550793.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005953.00,08,07,2010,+00,00*4B +$GPRMC,005954.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2D +{"class":"TPV","tag":"RMC","time":1278550794.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005954.00,08,07,2010,+00,00*4C +$GPRMC,005955.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2C +{"class":"TPV","tag":"RMC","time":1278550795.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005955.00,08,07,2010,+00,00*4D +$GPRMC,005956.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2F +{"class":"TPV","tag":"RMC","time":1278550796.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005956.00,08,07,2010,+00,00*4E +$GPRMC,005957.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*2E +{"class":"TPV","tag":"RMC","time":1278550797.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005957.00,08,07,2010,+00,00*4F +$GPRMC,005958.00,A,3715.6616,N,12157.6709,W,0.0,0.0,080710,,*21 +{"class":"TPV","tag":"RMC","time":1278550798.000,"ept":0.005,"lat":37.261026667,"lon":-121.961181667,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005958.00,08,07,2010,+00,00*40 +$GPRMC,005959.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2A +{"class":"TPV","tag":"RMC","time":1278550799.000,"ept":0.005,"lat":37.261023333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,005959.00,08,07,2010,+00,00*41 +$GPRMC,010000.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2B +{"class":"TPV","tag":"RMC","time":1278550800.000,"ept":0.005,"lat":37.261023333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010000.00,08,07,2010,+00,00*40 +$GPRMC,010001.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2A +{"class":"TPV","tag":"RMC","time":1278550801.000,"ept":0.005,"lat":37.261023333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010001.00,08,07,2010,+00,00*41 +$GPRMC,010002.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*29 +{"class":"TPV","tag":"RMC","time":1278550802.000,"ept":0.005,"lat":37.261023333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010002.00,08,07,2010,+00,00*42 +$GPRMC,010003.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*28 +{"class":"TPV","tag":"RMC","time":1278550803.000,"ept":0.005,"lat":37.261023333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010003.00,08,07,2010,+00,00*43 +$GPRMC,010004.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2F +{"class":"TPV","tag":"RMC","time":1278550804.000,"ept":0.005,"lat":37.261023333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010004.00,08,07,2010,+00,00*44 +$GPRMC,010005.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2E +{"class":"TPV","tag":"RMC","time":1278550805.000,"ept":0.005,"lat":37.261023333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010005.00,08,07,2010,+00,00*45 +$GPRMC,010006.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2D +{"class":"TPV","tag":"RMC","time":1278550806.000,"ept":0.005,"lat":37.261023333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010006.00,08,07,2010,+00,00*46 +$GPRMC,010007.00,A,3715.6614,N,12157.6699,W,0.0,0.0,080710,,*2C +{"class":"TPV","tag":"RMC","time":1278550807.000,"ept":0.005,"lat":37.261023333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010007.00,08,07,2010,+00,00*47 +$GPRMC,010008.00,A,3715.6611,N,12157.6699,W,0.0,0.0,080710,,*26 +{"class":"TPV","tag":"RMC","time":1278550808.000,"ept":0.005,"lat":37.261018333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010008.00,08,07,2010,+00,00*48 +$GPRMC,010009.00,A,3715.6609,N,12157.6699,W,0.0,0.0,080710,,*2E +{"class":"TPV","tag":"RMC","time":1278550809.000,"ept":0.005,"lat":37.261015000,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010009.00,08,07,2010,+00,00*49 +$GPRMC,010010.00,A,3715.6609,N,12157.6699,W,0.0,0.0,080710,,*26 +{"class":"TPV","tag":"RMC","time":1278550810.000,"ept":0.005,"lat":37.261015000,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010010.00,08,07,2010,+00,00*41 +$GPRMC,010011.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*28 +{"class":"TPV","tag":"RMC","time":1278550811.000,"ept":0.005,"lat":37.261010000,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010011.00,08,07,2010,+00,00*40 +$GPRMC,010012.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*2B +{"class":"TPV","tag":"RMC","time":1278550812.000,"ept":0.005,"lat":37.261010000,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010012.00,08,07,2010,+00,00*43 +$GPRMC,010013.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*2A +{"class":"TPV","tag":"RMC","time":1278550813.000,"ept":0.005,"lat":37.261010000,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010013.00,08,07,2010,+00,00*42 +$GPRMC,010014.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*2D +{"class":"TPV","tag":"RMC","time":1278550814.000,"ept":0.005,"lat":37.261010000,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010014.00,08,07,2010,+00,00*45 +$GPRMC,010015.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*2C +{"class":"TPV","tag":"RMC","time":1278550815.000,"ept":0.005,"lat":37.261010000,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010015.00,08,07,2010,+00,00*44 +$GPRMC,010016.00,A,3715.6606,N,12157.6699,W,0.0,0.0,080710,,*2F +{"class":"TPV","tag":"RMC","time":1278550816.000,"ept":0.005,"lat":37.261010000,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010016.00,08,07,2010,+00,00*47 +$GPRMC,010017.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2C +{"class":"TPV","tag":"RMC","time":1278550817.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010017.00,08,07,2010,+00,00*46 +$GPRMC,010018.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*23 +{"class":"TPV","tag":"RMC","time":1278550818.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010018.00,08,07,2010,+00,00*49 +$GPRMC,010019.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*22 +{"class":"TPV","tag":"RMC","time":1278550819.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010019.00,08,07,2010,+00,00*48 +$GPRMC,010020.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*28 +{"class":"TPV","tag":"RMC","time":1278550820.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010020.00,08,07,2010,+00,00*42 +$GPRMC,010021.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*29 +{"class":"TPV","tag":"RMC","time":1278550821.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010021.00,08,07,2010,+00,00*43 +$GPRMC,010022.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2A +{"class":"TPV","tag":"RMC","time":1278550822.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010022.00,08,07,2010,+00,00*40 +$GPRMC,010023.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2B +{"class":"TPV","tag":"RMC","time":1278550823.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010023.00,08,07,2010,+00,00*41 +$GPRMC,010024.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2C +{"class":"TPV","tag":"RMC","time":1278550824.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010024.00,08,07,2010,+00,00*46 +$GPRMC,010025.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2D +{"class":"TPV","tag":"RMC","time":1278550825.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010025.00,08,07,2010,+00,00*47 +$GPRMC,010026.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2E +{"class":"TPV","tag":"RMC","time":1278550826.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010026.00,08,07,2010,+00,00*44 +$GPRMC,010027.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2F +{"class":"TPV","tag":"RMC","time":1278550827.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010027.00,08,07,2010,+00,00*45 +$GPRMC,010028.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*20 +{"class":"TPV","tag":"RMC","time":1278550828.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010028.00,08,07,2010,+00,00*4A +$GPRMC,010029.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*21 +{"class":"TPV","tag":"RMC","time":1278550829.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010029.00,08,07,2010,+00,00*4B +$GPRMC,010030.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*29 +{"class":"TPV","tag":"RMC","time":1278550830.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010030.00,08,07,2010,+00,00*43 +$GPRMC,010031.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*28 +{"class":"TPV","tag":"RMC","time":1278550831.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010031.00,08,07,2010,+00,00*42 +$GPRMC,010032.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2B +{"class":"TPV","tag":"RMC","time":1278550832.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010032.00,08,07,2010,+00,00*41 +$GPRMC,010033.00,A,3715.6604,N,12157.6699,W,0.1,0.0,080710,,*2B +{"class":"TPV","tag":"RMC","time":1278550833.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.051,"mode":2} +$GPZDA,010033.00,08,07,2010,+00,00*40 +$GPRMC,010034.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2D +{"class":"TPV","tag":"RMC","time":1278550834.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010034.00,08,07,2010,+00,00*47 +$GPRMC,010035.00,A,3715.6604,N,12157.6699,W,0.1,0.0,080710,,*2D +{"class":"TPV","tag":"RMC","time":1278550835.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.051,"mode":2} +$GPZDA,010035.00,08,07,2010,+00,00*46 +$GPRMC,010036.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2F +{"class":"TPV","tag":"RMC","time":1278550836.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010036.00,08,07,2010,+00,00*45 +$GPRMC,010037.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2E +{"class":"TPV","tag":"RMC","time":1278550837.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010037.00,08,07,2010,+00,00*44 +$GPRMC,010038.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*21 +{"class":"TPV","tag":"RMC","time":1278550838.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010038.00,08,07,2010,+00,00*4B +$GPRMC,010039.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*20 +{"class":"TPV","tag":"RMC","time":1278550839.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010039.00,08,07,2010,+00,00*4A +$GPRMC,010040.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2E +{"class":"TPV","tag":"RMC","time":1278550840.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010040.00,08,07,2010,+00,00*44 +$GPRMC,010041.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2F +{"class":"TPV","tag":"RMC","time":1278550841.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010041.00,08,07,2010,+00,00*45 +$GPRMC,010042.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2C +{"class":"TPV","tag":"RMC","time":1278550842.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010042.00,08,07,2010,+00,00*46 +$GPRMC,010043.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2D +{"class":"TPV","tag":"RMC","time":1278550843.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010043.00,08,07,2010,+00,00*47 +$GPRMC,010044.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2A +{"class":"TPV","tag":"RMC","time":1278550844.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010044.00,08,07,2010,+00,00*40 +$GPRMC,010045.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*2B +{"class":"TPV","tag":"RMC","time":1278550845.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010045.00,08,07,2010,+00,00*41 +$GPRMC,010046.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*28 +{"class":"TPV","tag":"RMC","time":1278550846.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010046.00,08,07,2010,+00,00*42 +$GPRMC,010047.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*29 +{"class":"TPV","tag":"RMC","time":1278550847.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010047.00,08,07,2010,+00,00*43 +$GPRMC,010048.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*26 +{"class":"TPV","tag":"RMC","time":1278550848.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010048.00,08,07,2010,+00,00*4C +$GPRMC,010049.00,A,3715.6604,N,12157.6699,W,0.0,0.0,080710,,*27 +{"class":"TPV","tag":"RMC","time":1278550849.000,"ept":0.005,"lat":37.261006667,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010049.00,08,07,2010,+00,00*4D +$GPRMC,010050.00,A,3715.6609,N,12157.6699,W,0.0,0.0,080710,,*22 +{"class":"TPV","tag":"RMC","time":1278550850.000,"ept":0.005,"lat":37.261015000,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010050.00,08,07,2010,+00,00*45 +$GPRMC,010051.00,A,3715.6609,N,12157.6699,W,0.0,0.0,080710,,*23 +{"class":"TPV","tag":"RMC","time":1278550851.000,"ept":0.005,"lat":37.261015000,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010051.00,08,07,2010,+00,00*44 +$GPRMC,010052.00,A,3715.6611,N,12157.6699,W,0.0,0.0,080710,,*29 +{"class":"TPV","tag":"RMC","time":1278550852.000,"ept":0.005,"lat":37.261018333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010052.00,08,07,2010,+00,00*47 +$GPRMC,010053.00,A,3715.6611,N,12157.6699,W,0.0,0.0,080710,,*28 +{"class":"TPV","tag":"RMC","time":1278550853.000,"ept":0.005,"lat":37.261018333,"lon":-121.961165000,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010053.00,08,07,2010,+00,00*46 +$GPRMC,010054.00,A,3715.6611,N,12157.6699,W,0.1,0.0,080710,,*2E +{"class":"TPV","tag":"RMC","time":1278550854.000,"ept":0.005,"lat":37.261018333,"lon":-121.961165000,"track":0.0000,"speed":0.051,"mode":2} +$GPZDA,010054.00,08,07,2010,+00,00*41 +$GPRMC,010055.00,A,3715.6611,N,12157.6689,W,0.1,0.0,080710,,*2E +{"class":"TPV","tag":"RMC","time":1278550855.000,"ept":0.005,"lat":37.261018333,"lon":-121.961148333,"track":0.0000,"speed":0.051,"mode":2} +$GPZDA,010055.00,08,07,2010,+00,00*40 +$GPRMC,010056.00,A,3715.6611,N,12157.6689,W,0.1,0.0,080710,,*2D +{"class":"TPV","tag":"RMC","time":1278550856.000,"ept":0.005,"lat":37.261018333,"lon":-121.961148333,"track":0.0000,"speed":0.051,"mode":2} +$GPZDA,010056.00,08,07,2010,+00,00*43 +$GPRMC,010057.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*28 +{"class":"TPV","tag":"RMC","time":1278550857.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010057.00,08,07,2010,+00,00*42 +$GPRMC,010058.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*27 +{"class":"TPV","tag":"RMC","time":1278550858.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010058.00,08,07,2010,+00,00*4D +$GPRMC,010059.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*26 +{"class":"TPV","tag":"RMC","time":1278550859.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010059.00,08,07,2010,+00,00*4C +$GPRMC,010100.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2B +{"class":"TPV","tag":"RMC","time":1278550860.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010100.00,08,07,2010,+00,00*41 +$GPRMC,010101.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2A +{"class":"TPV","tag":"RMC","time":1278550861.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010101.00,08,07,2010,+00,00*40 +$GPRMC,010102.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*29 +{"class":"TPV","tag":"RMC","time":1278550862.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010102.00,08,07,2010,+00,00*43 +$GPRMC,010103.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*28 +{"class":"TPV","tag":"RMC","time":1278550863.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010103.00,08,07,2010,+00,00*42 +$GPRMC,010104.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2F +{"class":"TPV","tag":"RMC","time":1278550864.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010104.00,08,07,2010,+00,00*45 +$GPRMC,010105.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2E +{"class":"TPV","tag":"RMC","time":1278550865.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010105.00,08,07,2010,+00,00*44 +$GPRMC,010106.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2D +{"class":"TPV","tag":"RMC","time":1278550866.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010106.00,08,07,2010,+00,00*47 +$GPRMC,010107.00,A,3715.6614,N,12157.6689,W,0.0,0.0,080710,,*2C +{"class":"TPV","tag":"RMC","time":1278550867.000,"ept":0.005,"lat":37.261023333,"lon":-121.961148333,"track":0.0000,"speed":0.000,"mode":2} +$GPZDA,010107.00,08,07,2010,+00,00*46 diff --git a/test/daemon/garmin-geko201.log b/test/daemon/garmin-geko201.log new file mode 100644 index 0000000..66217d2 --- /dev/null +++ b/test/daemon/garmin-geko201.log @@ -0,0 +1,223 @@ +# Name: Garmin Geko 201 +# Chipset: Garmin proprietary +# Submitted-by: "Jose Luis Domingo Lopez" +# Date: 14 Jun 2005 +# Location: Madrid, Madrid, Spain (ES), 40.39N 03.64E +# Comments: This is demo-mode data, with no actual fixes. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPRMC,214350,V,4023.8600,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*21 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214350,4023.8600,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5A +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,36*71 +$GPGSV,3,3,09,30,67,294,50*48 +$GPGLL,4023.8600,N,00339.1630,W,214350,V,S*57 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214352,V,4023.8660,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*25 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214352,4023.8660,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5E +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,45,09,40,115,46,14,48,286,47,25,09,307,37*73 +$GPGSV,3,3,09,30,67,294,49*40 +$GPGLL,4023.8660,N,00339.1630,W,214352,V,S*53 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214354,V,4023.8720,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*26 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214354,4023.8720,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5D +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,45,09,40,115,46,14,48,286,47,25,09,307,37*73 +$GPGSV,3,3,09,30,67,294,50*48 +$GPGLL,4023.8720,N,00339.1630,W,214354,V,S*50 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214356,V,4023.8780,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*2E +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214356,4023.8780,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*55 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,294,50*48 +$GPGLL,4023.8780,N,00339.1630,W,214356,V,S*58 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214358,V,4023.8840,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*23 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214358,4023.8840,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*58 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,48*76 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,294,50*48 +$GPGLL,4023.8840,N,00339.1630,W,214358,V,S*55 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214400,V,4023.8900,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*2C +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214400,4023.8900,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*57 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,40,02,17,093,40,04,09,049,37,05,60,046,48*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,294,50*48 +$GPGLL,4023.8900,N,00339.1630,W,214400,V,S*5A +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214402,V,4023.8960,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*28 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214402,4023.8960,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*53 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,294,50*48 +$GPGLL,4023.8960,N,00339.1630,W,214402,V,S*5E +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214404,V,4023.9021,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*23 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214404,4023.9021,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*58 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,40,02,17,093,40,04,09,049,37,05,60,046,49*76 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,294,50*48 +$GPGLL,4023.9021,N,00339.1630,W,214404,V,S*55 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214406,V,4023.9081,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*2B +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214406,4023.9081,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*50 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,48*76 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +$GPGLL,4023.9081,N,00339.1630,W,214406,V,S*5D +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214408,V,4023.9141,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*28 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214408,4023.9141,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*53 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +$GPGLL,4023.9141,N,00339.1630,W,214408,V,S*5E +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214410,V,4023.9201,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*26 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214410,4023.9201,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5D +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,49*41 +$GPGLL,4023.9201,N,00339.1630,W,214410,V,S*50 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214412,V,4023.9261,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*22 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214412,4023.9261,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*59 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,48*76 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,36*71 +$GPGSV,3,3,09,30,67,295,50*49 +$GPGLL,4023.9261,N,00339.1630,W,214412,V,S*54 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214414,V,4023.9321,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*21 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214414,4023.9321,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5A +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,36*71 +$GPGSV,3,3,09,30,67,295,50*49 +$GPGLL,4023.9321,N,00339.1630,W,214414,V,S*57 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214416,V,4023.9381,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*29 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214416,4023.9381,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*52 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,20,319,41,02,17,093,40,04,09,049,36,05,60,046,48*7D +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +$GPGLL,4023.9381,N,00339.1630,W,214416,V,S*5F +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214418,V,4023.9441,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*2C +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214418,4023.9441,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*57 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,20,319,41,02,17,093,40,04,09,049,36,05,60,046,49*7C +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +$GPGLL,4023.9441,N,00339.1630,W,214418,V,S*5A +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214420,V,4023.9501,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*22 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214420,4023.9501,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*59 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,20,319,41,02,18,092,40,04,09,049,35,05,60,046,48*70 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +$GPGLL,4023.9501,N,00339.1630,W,214420,V,S*54 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214422,V,4023.9561,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*26 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214422,4023.9561,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5D +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,20,319,41,02,18,092,40,04,09,049,36,05,60,046,49*72 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +$GPGLL,4023.9561,N,00339.1630,W,214422,V,S*50 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214424,V,4023.9621,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*27 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214424,4023.9621,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5C +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,20,319,41,02,18,092,40,04,09,049,36,05,60,046,48*73 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,36*71 +$GPGSV,3,3,09,30,67,295,50*49 +$GPGLL,4023.9621,N,00339.1630,W,214424,V,S*51 +$GPBOD,,T,,M,,* diff --git a/test/daemon/garmin-geko201.log.chk b/test/daemon/garmin-geko201.log.chk new file mode 100644 index 0000000..c14bdb2 --- /dev/null +++ b/test/daemon/garmin-geko201.log.chk @@ -0,0 +1,232 @@ +$GPRMC,214350,V,4023.8600,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*21 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214350,4023.8600,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5A +{"class":"TPV","tag":"GGA","lat":40.397666667,"lon":-3.652716667,"alt":695.700,"mode":3} +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +{"class":"TPV","tag":"GSA","lat":40.397666667,"lon":-3.652716667,"alt":695.700,"epv":69.000,"mode":3} +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,36*71 +$GPGSV,3,3,09,30,67,294,50*48 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.35,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.69,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":36,"used":true},{"PRN":30,"el":67,"az":294,"ss":50,"used":true}]} +$GPGLL,4023.8600,N,00339.1630,W,214350,V,S*57 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214352,V,4023.8660,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*25 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214352,4023.8660,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5E +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,45,09,40,115,46,14,48,286,47,25,09,307,37*73 +$GPGSV,3,3,09,30,67,294,49*40 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.35,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.69,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":45,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":294,"ss":49,"used":true}]} +$GPGLL,4023.8660,N,00339.1630,W,214352,V,S*53 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214354,V,4023.8720,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*26 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214354,4023.8720,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5D +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,45,09,40,115,46,14,48,286,47,25,09,307,37*73 +$GPGSV,3,3,09,30,67,294,50*48 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.35,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.69,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":45,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":294,"ss":50,"used":true}]} +$GPGLL,4023.8720,N,00339.1630,W,214354,V,S*50 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214356,V,4023.8780,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*2E +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214356,4023.8780,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*55 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,294,50*48 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.35,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.69,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":294,"ss":50,"used":true}]} +$GPGLL,4023.8780,N,00339.1630,W,214356,V,S*58 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214358,V,4023.8840,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*23 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214358,4023.8840,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*58 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,48*76 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,294,50*48 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.35,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.69,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":48,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":294,"ss":50,"used":true}]} +$GPGLL,4023.8840,N,00339.1630,W,214358,V,S*55 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214400,V,4023.8900,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*2C +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214400,4023.8900,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*57 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,40,02,17,093,40,04,09,049,37,05,60,046,48*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,294,50*48 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.35,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.69,"satellites":[{"PRN":1,"el":19,"az":319,"ss":40,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":48,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":294,"ss":50,"used":true}]} +$GPGLL,4023.8900,N,00339.1630,W,214400,V,S*5A +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214402,V,4023.8960,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*28 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214402,4023.8960,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*53 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,294,50*48 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.35,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.69,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":294,"ss":50,"used":true}]} +$GPGLL,4023.8960,N,00339.1630,W,214402,V,S*5E +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214404,V,4023.9021,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*23 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214404,4023.9021,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*58 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,40,02,17,093,40,04,09,049,37,05,60,046,49*76 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,294,50*48 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.35,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.69,"satellites":[{"PRN":1,"el":19,"az":319,"ss":40,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":294,"ss":50,"used":true}]} +$GPGLL,4023.9021,N,00339.1630,W,214404,V,S*55 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214406,V,4023.9081,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*2B +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214406,4023.9081,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*50 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,48*76 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.34,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.68,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":48,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":295,"ss":50,"used":true}]} +$GPGLL,4023.9081,N,00339.1630,W,214406,V,S*5D +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214408,V,4023.9141,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*28 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214408,4023.9141,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*53 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.34,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.68,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":295,"ss":50,"used":true}]} +$GPGLL,4023.9141,N,00339.1630,W,214408,V,S*5E +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214410,V,4023.9201,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*26 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214410,4023.9201,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5D +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,49*41 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.34,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.68,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":295,"ss":49,"used":true}]} +$GPGLL,4023.9201,N,00339.1630,W,214410,V,S*50 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214412,V,4023.9261,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*22 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214412,4023.9261,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*59 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,48*76 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,36*71 +$GPGSV,3,3,09,30,67,295,50*49 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.34,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.68,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":48,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":36,"used":true},{"PRN":30,"el":67,"az":295,"ss":50,"used":true}]} +$GPGLL,4023.9261,N,00339.1630,W,214412,V,S*54 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214414,V,4023.9321,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*21 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214414,4023.9321,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5A +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,19,319,41,02,17,093,40,04,09,049,37,05,60,046,49*77 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,36*71 +$GPGSV,3,3,09,30,67,295,50*49 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.34,"tdop":0.85,"hdop":1.01,"gdop":1.89,"pdop":1.68,"satellites":[{"PRN":1,"el":19,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":37,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":36,"used":true},{"PRN":30,"el":67,"az":295,"ss":50,"used":true}]} +$GPGLL,4023.9321,N,00339.1630,W,214414,V,S*57 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214416,V,4023.9381,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*29 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214416,4023.9381,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*52 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,20,319,41,02,17,093,40,04,09,049,36,05,60,046,48*7D +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.85,"vdop":1.35,"tdop":0.86,"hdop":1.01,"gdop":1.89,"pdop":1.69,"satellites":[{"PRN":1,"el":20,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":36,"used":true},{"PRN":5,"el":60,"az":46,"ss":48,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":295,"ss":50,"used":true}]} +$GPGLL,4023.9381,N,00339.1630,W,214416,V,S*5F +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214418,V,4023.9441,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*2C +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214418,4023.9441,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*57 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,20,319,41,02,17,093,40,04,09,049,36,05,60,046,49*7C +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +{"class":"SKY","tag":"GSV","xdop":0.56,"ydop":0.85,"vdop":1.35,"tdop":0.86,"hdop":1.01,"gdop":1.89,"pdop":1.69,"satellites":[{"PRN":1,"el":20,"az":319,"ss":41,"used":true},{"PRN":2,"el":17,"az":93,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":36,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":295,"ss":50,"used":true}]} +$GPGLL,4023.9441,N,00339.1630,W,214418,V,S*5A +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214420,V,4023.9501,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*22 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214420,4023.9501,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*59 +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,20,319,41,02,18,092,40,04,09,049,35,05,60,046,48*70 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.36,"tdop":0.87,"hdop":1.01,"gdop":1.90,"pdop":1.70,"satellites":[{"PRN":1,"el":20,"az":319,"ss":41,"used":true},{"PRN":2,"el":18,"az":92,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":35,"used":true},{"PRN":5,"el":60,"az":46,"ss":48,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":295,"ss":50,"used":true}]} +$GPGLL,4023.9501,N,00339.1630,W,214420,V,S*54 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214422,V,4023.9561,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*26 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214422,4023.9561,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5D +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,20,319,41,02,18,092,40,04,09,049,36,05,60,046,49*72 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,37*70 +$GPGSV,3,3,09,30,67,295,50*49 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.36,"tdop":0.87,"hdop":1.01,"gdop":1.90,"pdop":1.70,"satellites":[{"PRN":1,"el":20,"az":319,"ss":41,"used":true},{"PRN":2,"el":18,"az":92,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":36,"used":true},{"PRN":5,"el":60,"az":46,"ss":49,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":37,"used":true},{"PRN":30,"el":67,"az":295,"ss":50,"used":true}]} +$GPGLL,4023.9561,N,00339.1630,W,214422,V,S*50 +$GPBOD,,T,,M,,*47 +$PGRME,15.0,M,22.5,M,27.0,M*1A +$PGRMZ,2282,f,3*21 +$GPRTE,1,1,c,*37 +$GPRMC,214424,V,4023.9621,N,00339.1630,W,10.8,0.0,140605,2.5,W,S*27 +$GPRMB,V,,,,,,,,,,,,A,S*0E +$GPGGA,214424,4023.9621,N,00339.1630,W,8,09,2.0,695.7,M,51.6,M,,*5C +$GPGSA,A,3,01,02,04,05,06,09,14,25,30,,,,3.6,2.0,3.0*3A +$GPGSV,3,1,09,01,20,319,41,02,18,092,40,04,09,049,36,05,60,046,48*73 +$GPGSV,3,2,09,06,39,195,46,09,40,115,46,14,48,286,47,25,09,307,36*71 +$GPGSV,3,3,09,30,67,295,50*49 +{"class":"SKY","tag":"GSV","xdop":0.55,"ydop":0.85,"vdop":1.36,"tdop":0.87,"hdop":1.01,"gdop":1.90,"pdop":1.70,"satellites":[{"PRN":1,"el":20,"az":319,"ss":41,"used":true},{"PRN":2,"el":18,"az":92,"ss":40,"used":true},{"PRN":4,"el":9,"az":49,"ss":36,"used":true},{"PRN":5,"el":60,"az":46,"ss":48,"used":true},{"PRN":6,"el":39,"az":195,"ss":46,"used":true},{"PRN":9,"el":40,"az":115,"ss":46,"used":true},{"PRN":14,"el":48,"az":286,"ss":47,"used":true},{"PRN":25,"el":9,"az":307,"ss":36,"used":true},{"PRN":30,"el":67,"az":295,"ss":50,"used":true}]} +$GPGLL,4023.9621,N,00339.1630,W,214424,V,S*51 diff --git a/test/daemon/garmin17n.log b/test/daemon/garmin17n.log new file mode 100644 index 0000000..ae1f2f8 --- /dev/null +++ b/test/daemon/garmin17n.log @@ -0,0 +1,31 @@ +# Name: Garmin 17N +# Chipset: +# Submitted-by: Wojciech Kazubski +# Comment: Only emits GPRMC when it has a fix. +# Date: 12 Mar 2005 +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPRMC,093802,A,5213.1439,N,02100.6511,E,000.0,226.0,160305,004.2,E,D*15 +$GPGGA,093802,5213.1439,N,02100.6511,E,2,10,0.9,137.2,M,36.2,M,,*43 +$GPGSA,A,3,03,06,15,16,18,19,21,22,,27,29,,1.6,0.9,1.3*34 +$GPGSV,3,2,12,18,50,135,50,19,15,291,46,21,59,069,51,22,30,169,49*75 +$PGRME,1.7,M,2.4,M,3.0,M*2D +$GPGLL,5213.1439,N,02100.6511,E,093802,A,D*48 +$GPVTG,226,T,222,M,000.0,N,0000.0,K,D*12 +$PGRMV,0.0,0.0,0.0*5C +$PGRMF,290,293895,160305,093802,13,5213.1439,N,02100.6511,E,A,2,0,226,2,1*11 +$PGRMB,0.0,200,,,,K,,W,W*31 +$PGRMM,WGS 84*06 +$GPRMC,093803,A,5213.1439,N,02100.6511,E,000.0,226.0,160305,004.2,E,D*14 +$GPGGA,093803,5213.1439,N,02100.6511,E,2,10,0.9,137.2,M,36.2,M,,*42 +$GPGSA,A,3,03,06,15,16,18,19,21,22,,27,29,,1.6,0.9,1.3*34 +$GPGSV,3,3,12,26,14,065,48,27,08,336,38,29,14,048,44,44,18,130,41*78 +$PGRME,1.7,M,2.4,M,3.0,M*2D +$GPGLL,5213.1439,N,02100.6511,E,093803,A,D*49 +$GPVTG,226,T,222,M,000.0,N,0000.0,K,D*12 +$PGRMV,0.0,0.0,0.0*5C +$PGRMF,290,293896,160305,093803,13,5213.1439,N,02100.6511,E,A,2,0,226,2,1*13 +$PGRMB,0.0,200,,,,K,,W,W*31 +$PGRMM,WGS 84*06 diff --git a/test/daemon/garmin17n.log.chk b/test/daemon/garmin17n.log.chk new file mode 100644 index 0000000..9c759a1 --- /dev/null +++ b/test/daemon/garmin17n.log.chk @@ -0,0 +1,28 @@ +$GPRMC,093802,A,5213.1439,N,02100.6511,E,000.0,226.0,160305,004.2,E,D*15 +{"class":"TPV","tag":"RMC","time":1110965882.000,"ept":0.005,"lat":52.219065000,"lon":21.010851667,"track":226.0000,"speed":0.000,"mode":2} +$GPGGA,093802,5213.1439,N,02100.6511,E,2,10,0.9,137.2,M,36.2,M,,*43 +{"class":"TPV","tag":"GGA","time":1110965882.000,"ept":0.005,"lat":52.219065000,"lon":21.010851667,"alt":137.200,"track":226.0000,"speed":0.000,"mode":3} +$GPGSA,A,3,03,06,15,16,18,19,21,22,,27,29,,1.6,0.9,1.3*34 +{"class":"TPV","tag":"GSA","time":1110965882.000,"ept":0.005,"lat":52.219065000,"lon":21.010851667,"alt":137.200,"epv":7.475,"track":226.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,3,2,12,18,50,135,50,19,15,291,46,21,59,069,51,22,30,169,49*75 +$PGRME,1.7,M,2.4,M,3.0,M*2D +$GPGLL,5213.1439,N,02100.6511,E,093802,A,D*48 +{"class":"TPV","tag":"GLL","time":1110965882.000,"ept":0.005,"lat":52.219065000,"lon":21.010851667,"alt":137.200,"epx":2.496,"epy":2.496,"epv":4.983,"track":226.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPVTG,226,T,222,M,000.0,N,0000.0,K,D*12 +$PGRMV,0.0,0.0,0.0*5C +$PGRMF,290,293895,160305,093802,13,5213.1439,N,02100.6511,E,A,2,0,226,2,1*11 +$PGRMB,0.0,200,,,,K,,W,W*31 +$PGRMM,WGS 84*06 +$GPRMC,093803,A,5213.1439,N,02100.6511,E,000.0,226.0,160305,004.2,E,D*14 +$GPGGA,093803,5213.1439,N,02100.6511,E,2,10,0.9,137.2,M,36.2,M,,*42 +$GPGSA,A,3,03,06,15,16,18,19,21,22,,27,29,,1.6,0.9,1.3*34 +$GPGSV,3,3,12,26,14,065,48,27,08,336,38,29,14,048,44,44,18,130,41*78 +{"class":"SKY","tag":"GSV","xdop":0.64,"ydop":0.66,"vdop":1.30,"tdop":0.71,"hdop":0.90,"gdop":1.92,"pdop":1.60,"satellites":[{"PRN":18,"el":50,"az":135,"ss":50,"used":true},{"PRN":19,"el":15,"az":291,"ss":46,"used":true},{"PRN":21,"el":59,"az":69,"ss":51,"used":true},{"PRN":22,"el":30,"az":169,"ss":49,"used":true},{"PRN":26,"el":14,"az":65,"ss":48,"used":false},{"PRN":27,"el":8,"az":336,"ss":38,"used":true},{"PRN":29,"el":14,"az":48,"ss":44,"used":true},{"PRN":44,"el":18,"az":130,"ss":41,"used":false}]} +$PGRME,1.7,M,2.4,M,3.0,M*2D +$GPGLL,5213.1439,N,02100.6511,E,093803,A,D*49 +{"class":"TPV","tag":"GLL","time":1110965883.000,"ept":0.005,"lat":52.219065000,"lon":21.010851667,"alt":137.200,"epx":2.496,"epy":2.496,"epv":4.983,"track":226.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPVTG,226,T,222,M,000.0,N,0000.0,K,D*12 +$PGRMV,0.0,0.0,0.0*5C +$PGRMF,290,293896,160305,093803,13,5213.1439,N,02100.6511,E,A,2,0,226,2,1*13 +$PGRMB,0.0,200,,,,K,,W,W*31 +$PGRMM,WGS 84*06 diff --git a/test/daemon/garmin25lp.log b/test/daemon/garmin25lp.log new file mode 100644 index 0000000..673a21d --- /dev/null +++ b/test/daemon/garmin25lp.log @@ -0,0 +1,114 @@ +# Name: Garmin 25LP +# Chipset: Garmin proprietary, emits NMEA 2.0 +# Submitted-by: Daniele Giangrazi +# Date: 22 Mar 2005 +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPRMC,120316,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*63 +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,40,16,05,184,,18,20,046,,19,73,304,*7B +$GPRMC,120317,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*62 +$GPGGA,120317,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*59 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,40,16,05,184,,18,20,046,,19,73,304,*7B +$GPRMC,120318,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*6D +$GPGGA,120318,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*56 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,40,16,05,184,,18,20,046,,19,73,304,*7B +$GPRMC,120319,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*6C +$GPGGA,120319,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*57 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,40,16,05,184,,18,20,046,,19,73,304,*7B +$GPRMC,120320,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*66 +$GPGGA,120320,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*5D +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,40,16,05,184,,18,20,046,,19,73,304,*7B +$GPRMC,120321,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*67 +$GPGGA,120321,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*5C +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPRMC,120322,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*64 +$GPGGA,120322,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*5F +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,2,1,08,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPRMC,120323,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*65 +$GPGGA,120323,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*5E +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,2,1,08,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPRMC,120324,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*62 +$GPGGA,120324,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*59 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,2,1,08,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPRMC,120325,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*63 +$GPGGA,120325,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*58 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,2,1,08,01,10,158,44,03,72,164,42,11,24,279,,14,30,119,48*74 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPRMC,120326,A,4221.3871,N,01322.0800,E,000.0,000.0,150305,001.4,E*77 +$GPGGA,120326,4221.3871,N,01322.0800,E,1,00,3.1,746.1,M,44.2,M,,*40 +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,2,1,08,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPRMC,120327,A,4221.3872,N,01322.0800,E,000.0,000.0,150305,001.4,E*75 +$GPGGA,120327,4221.3872,N,01322.0800,E,1,03,3.1,746.1,M,44.2,M,,*41 +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,2,1,08,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPRMC,120328,A,4221.3873,N,01322.0800,E,000.0,000.0,150305,001.4,E*7B +$GPGGA,120328,4221.3873,N,01322.0800,E,1,03,3.1,746.1,M,44.2,M,,*4F +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +$GPRMC,120329,A,4221.3874,N,01322.0805,E,000.0,000.0,150305,001.4,E*78 +$GPGGA,120329,4221.3874,N,01322.0805,E,1,03,3.1,746.1,M,44.2,M,,*4C +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +$GPRMC,120330,A,4221.3875,N,01322.0807,E,000.0,000.0,150305,001.4,E*73 +$GPGGA,120330,4221.3875,N,01322.0807,E,1,03,3.1,746.1,M,44.2,M,,*47 +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +$GPRMC,120331,A,4221.3880,N,01322.0808,E,000.0,000.0,150305,001.4,E*77 +$GPGGA,120331,4221.3880,N,01322.0808,E,1,03,3.1,746.1,M,44.2,M,,*43 +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +$GPRMC,120332,A,4221.3884,N,01322.0802,E,000.0,000.0,150305,001.4,E*7A +$GPGGA,120332,4221.3884,N,01322.0802,E,1,03,3.1,746.1,M,44.2,M,,*4E +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +$GPRMC,120333,A,4221.3889,N,01322.0794,E,000.0,000.0,150305,001.4,E*76 +$GPGGA,120333,4221.3889,N,01322.0794,E,1,03,3.1,746.1,M,44.2,M,,*42 +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +$GPRMC,120334,A,4221.3893,N,01322.0786,E,000.0,000.0,150305,001.4,E*79 +$GPGGA,120334,4221.3893,N,01322.0786,E,1,03,3.1,746.1,M,44.2,M,,*4D +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +$GPRMC,120335,A,4221.3898,N,01322.0780,E,000.0,000.0,150305,001.4,E*75 +$GPGGA,120335,4221.3898,N,01322.0780,E,1,03,3.1,746.1,M,44.2,M,,*41 +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 diff --git a/test/daemon/garmin25lp.log.chk b/test/daemon/garmin25lp.log.chk new file mode 100644 index 0000000..5a8d83a --- /dev/null +++ b/test/daemon/garmin25lp.log.chk @@ -0,0 +1,146 @@ +$GPRMC,120316,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*63 +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,40,16,05,184,,18,20,046,,19,73,304,*7B +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":false},{"PRN":3,"el":72,"az":164,"ss":41,"used":false},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":false},{"PRN":15,"el":33,"az":70,"ss":40,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120317,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*62 +$GPGGA,120317,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*59 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,40,16,05,184,,18,20,046,,19,73,304,*7B +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":false},{"PRN":3,"el":72,"az":164,"ss":41,"used":false},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":false},{"PRN":15,"el":33,"az":70,"ss":40,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120318,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*6D +$GPGGA,120318,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*56 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,40,16,05,184,,18,20,046,,19,73,304,*7B +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":false},{"PRN":3,"el":72,"az":164,"ss":41,"used":false},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":false},{"PRN":15,"el":33,"az":70,"ss":40,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120319,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*6C +$GPGGA,120319,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*57 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,40,16,05,184,,18,20,046,,19,73,304,*7B +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":false},{"PRN":3,"el":72,"az":164,"ss":41,"used":false},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":false},{"PRN":15,"el":33,"az":70,"ss":40,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120320,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*66 +$GPGGA,120320,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*5D +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,40,16,05,184,,18,20,046,,19,73,304,*7B +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":false},{"PRN":3,"el":72,"az":164,"ss":41,"used":false},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":false},{"PRN":15,"el":33,"az":70,"ss":40,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120321,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*67 +$GPGGA,120321,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*5C +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,2,1,08,01,10,158,45,03,72,164,41,11,24,279,,14,30,119,48*76 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":false},{"PRN":3,"el":72,"az":164,"ss":41,"used":false},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":false},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120322,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*64 +$GPGGA,120322,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*5F +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,2,1,08,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":false},{"PRN":3,"el":72,"az":164,"ss":42,"used":false},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":false},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120323,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*65 +$GPGGA,120323,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*5E +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,2,1,08,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":false},{"PRN":3,"el":72,"az":164,"ss":42,"used":false},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":false},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120324,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*62 +$GPGGA,120324,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*59 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,2,1,08,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":false},{"PRN":3,"el":72,"az":164,"ss":42,"used":false},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":false},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120325,V,4221.4394,N,01321.9948,E,000.0,000.0,150305,001.4,E*63 +$GPGGA,120325,4221.4394,N,01321.9948,E,0,00,,,M,,M,,*58 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,2,1,08,01,10,158,44,03,72,164,42,11,24,279,,14,30,119,48*74 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":44,"used":false},{"PRN":3,"el":72,"az":164,"ss":42,"used":false},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":false},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120326,A,4221.3871,N,01322.0800,E,000.0,000.0,150305,001.4,E*77 +{"class":"TPV","tag":"RMC","time":1110888206.000,"ept":0.005,"lat":42.356451667,"lon":13.368000000,"track":0.0000,"speed":0.000,"mode":2} +$GPGGA,120326,4221.3871,N,01322.0800,E,1,00,3.1,746.1,M,44.2,M,,*40 +{"class":"TPV","tag":"GGA","time":1110888206.000,"ept":0.005,"lat":42.356451667,"lon":13.368000000,"alt":746.100,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,2,1,08,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":true},{"PRN":3,"el":72,"az":164,"ss":42,"used":true},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":true},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120327,A,4221.3872,N,01322.0800,E,000.0,000.0,150305,001.4,E*75 +$GPGGA,120327,4221.3872,N,01322.0800,E,1,03,3.1,746.1,M,44.2,M,,*41 +{"class":"TPV","tag":"GGA","time":1110888207.000,"ept":0.005,"lat":42.356453333,"lon":13.368000000,"alt":746.100,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,2,1,08,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,2,2,08,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":true},{"PRN":3,"el":72,"az":164,"ss":42,"used":true},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":true},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false}]} +$GPRMC,120328,A,4221.3873,N,01322.0800,E,000.0,000.0,150305,001.4,E*7B +$GPGGA,120328,4221.3873,N,01322.0800,E,1,03,3.1,746.1,M,44.2,M,,*4F +{"class":"TPV","tag":"GGA","time":1110888208.000,"ept":0.005,"lat":42.356455000,"lon":13.368000000,"alt":746.100,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":true},{"PRN":3,"el":72,"az":164,"ss":42,"used":true},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":true},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false},{"PRN":22,"el":50,"az":54,"ss":0,"used":false}]} +$GPRMC,120329,A,4221.3874,N,01322.0805,E,000.0,000.0,150305,001.4,E*78 +$GPGGA,120329,4221.3874,N,01322.0805,E,1,03,3.1,746.1,M,44.2,M,,*4C +{"class":"TPV","tag":"GGA","time":1110888209.000,"ept":0.005,"lat":42.356456667,"lon":13.368008333,"alt":746.100,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,48*75 +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":true},{"PRN":3,"el":72,"az":164,"ss":42,"used":true},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":48,"used":true},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false},{"PRN":22,"el":50,"az":54,"ss":0,"used":false}]} +$GPRMC,120330,A,4221.3875,N,01322.0807,E,000.0,000.0,150305,001.4,E*73 +$GPGGA,120330,4221.3875,N,01322.0807,E,1,03,3.1,746.1,M,44.2,M,,*47 +{"class":"TPV","tag":"GGA","time":1110888210.000,"ept":0.005,"lat":42.356458333,"lon":13.368011667,"alt":746.100,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":true},{"PRN":3,"el":72,"az":164,"ss":42,"used":true},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":47,"used":true},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false},{"PRN":22,"el":50,"az":54,"ss":0,"used":false}]} +$GPRMC,120331,A,4221.3880,N,01322.0808,E,000.0,000.0,150305,001.4,E*77 +$GPGGA,120331,4221.3880,N,01322.0808,E,1,03,3.1,746.1,M,44.2,M,,*43 +{"class":"TPV","tag":"GGA","time":1110888211.000,"ept":0.005,"lat":42.356466667,"lon":13.368013333,"alt":746.100,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":true},{"PRN":3,"el":72,"az":164,"ss":42,"used":true},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":47,"used":true},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false},{"PRN":22,"el":50,"az":54,"ss":0,"used":false}]} +$GPRMC,120332,A,4221.3884,N,01322.0802,E,000.0,000.0,150305,001.4,E*7A +$GPGGA,120332,4221.3884,N,01322.0802,E,1,03,3.1,746.1,M,44.2,M,,*4E +{"class":"TPV","tag":"GGA","time":1110888212.000,"ept":0.005,"lat":42.356473333,"lon":13.368003333,"alt":746.100,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":true},{"PRN":3,"el":72,"az":164,"ss":42,"used":true},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":47,"used":true},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false},{"PRN":22,"el":50,"az":54,"ss":0,"used":false}]} +$GPRMC,120333,A,4221.3889,N,01322.0794,E,000.0,000.0,150305,001.4,E*76 +$GPGGA,120333,4221.3889,N,01322.0794,E,1,03,3.1,746.1,M,44.2,M,,*42 +{"class":"TPV","tag":"GGA","time":1110888213.000,"ept":0.005,"lat":42.356481667,"lon":13.367990000,"alt":746.100,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":true},{"PRN":3,"el":72,"az":164,"ss":42,"used":true},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":47,"used":true},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false},{"PRN":22,"el":50,"az":54,"ss":0,"used":false}]} +$GPRMC,120334,A,4221.3893,N,01322.0786,E,000.0,000.0,150305,001.4,E*79 +$GPGGA,120334,4221.3893,N,01322.0786,E,1,03,3.1,746.1,M,44.2,M,,*4D +{"class":"TPV","tag":"GGA","time":1110888214.000,"ept":0.005,"lat":42.356488333,"lon":13.367976667,"alt":746.100,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":true},{"PRN":3,"el":72,"az":164,"ss":42,"used":true},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":47,"used":true},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false},{"PRN":22,"el":50,"az":54,"ss":0,"used":false}]} +$GPRMC,120335,A,4221.3898,N,01322.0780,E,000.0,000.0,150305,001.4,E*75 +$GPGGA,120335,4221.3898,N,01322.0780,E,1,03,3.1,746.1,M,44.2,M,,*41 +{"class":"TPV","tag":"GGA","time":1110888215.000,"ept":0.005,"lat":42.356496667,"lon":13.367966667,"alt":746.100,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,2,01,03,,14,,,,,,,,,3.1,3.1,*1A +$GPGSV,3,1,09,01,10,158,45,03,72,164,42,11,24,279,,14,30,119,47*7A +$GPGSV,3,2,09,15,33,070,39,16,05,184,,18,20,046,,19,73,304,*75 +$GPGSV,3,3,09,22,50,054,,,,,,,,,,,,,*44 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":1,"el":10,"az":158,"ss":45,"used":true},{"PRN":3,"el":72,"az":164,"ss":42,"used":true},{"PRN":11,"el":24,"az":279,"ss":0,"used":false},{"PRN":14,"el":30,"az":119,"ss":47,"used":true},{"PRN":15,"el":33,"az":70,"ss":39,"used":false},{"PRN":16,"el":5,"az":184,"ss":0,"used":false},{"PRN":18,"el":20,"az":46,"ss":0,"used":false},{"PRN":19,"el":73,"az":304,"ss":0,"used":false},{"PRN":22,"el":50,"az":54,"ss":0,"used":false}]} diff --git a/test/daemon/garmin38.log b/test/daemon/garmin38.log new file mode 100644 index 0000000..dad6e83 --- /dev/null +++ b/test/daemon/garmin38.log @@ -0,0 +1,70 @@ +# Name: Garmin 38 +# Submitted-by: "Pascal F. Martin" +# Date: 18 Mar 2005 +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$PGRME,19.2,M,28.7,M,34.6,M*18 +$GPGLL,3348.452,N,11821.142,W,142214,A*3B +$PGRMZ,125,f,3*1D +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,142216,A,3348.452,N,11821.143,W,000.0,353.6,081002,013.8,E*66 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,142216,3348.452,N,11821.143,W,1,05,1.8,38.4,M,-32.4,M,,*4B +$GPGSA,A,3,03,,11,14,,,25,31,,,,,3.3,1.8,2.8*32 +$GPGSV,2,1,08,03,23,224,38,09,06,037,00,11,17,314,41,14,75,015,44*72 +$GPGSV,2,2,08,15,18,138,00,18,20,079,00,25,27,172,46,31,27,263,38*7C +$PGRME,19.2,M,28.7,M,34.6,M*18 +$GPGLL,3348.452,N,11821.143,W,142216,A*38 +$PGRMZ,126,f,3*1E +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,142218,A,3348.451,N,11821.144,W,000.0,353.6,081002,013.8,E*6C +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,142218,3348.451,N,11821.144,W,1,05,1.8,38.4,M,-32.4,M,,*41 +$GPGSA,A,3,03,,11,14,,,25,31,,,,,3.3,1.8,2.8*32 +$GPGSV,2,1,08,03,23,224,43,09,06,037,00,11,17,314,38,14,75,015,44*70 +$GPGSV,2,2,08,15,18,138,00,18,20,079,00,25,27,172,39,31,27,263,42*79 +$PGRME,19.2,M,28.7,M,34.6,M*18 +$GPGLL,3348.451,N,11821.144,W,142218,A*32 +$PGRMZ,126,f,3*1E +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,142220,A,3348.451,N,11821.142,W,000.0,353.6,081002,013.8,E*61 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,142220,3348.451,N,11821.142,W,1,05,1.8,37.6,M,-32.4,M,,*41 +$GPGSA,A,3,03,,11,14,,,25,31,,,,,3.3,1.8,2.8*32 +$GPGSV,2,1,08,03,23,224,43,09,06,037,00,11,17,314,38,14,75,015,43*77 +$GPGSV,2,2,08,15,18,138,00,18,20,079,00,25,27,172,39,31,27,263,41*7A +$PGRME,19.2,M,28.7,M,34.6,M*18 +$GPGLL,3348.451,N,11821.142,W,142220,A*3F +$PGRMZ,123,f,3*1B +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,142222,A,3348.451,N,11821.143,W,000.0,353.6,081002,013.8,E*62 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,142222,3348.451,N,11821.143,W,1,05,1.8,38.0,M,-32.4,M,,*4B +$GPGSA,A,3,03,,11,14,,,25,31,,,,,3.3,1.8,2.8*32 +$GPGSV,2,1,08,03,23,224,42,09,06,037,00,11,17,314,38,14,75,015,43*76 +$GPGSV,2,2,08,15,18,138,00,18,20,079,00,25,27,172,40,31,27,263,41*74 +$PGRME,19.2,M,28.9,M,34.7,M*17 +$GPGLL,3348.451,N,11821.143,W,142222,A*3C +$PGRMZ,125,f,3*1D +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,142224,A,3348.451,N,11821.143,W,000.0,353.6,081002,013.8,E*64 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,142224,3348.451,N,11821.143,W,1,05,1.8,38.0,M,-32.4,M,,*4D +$GPGSA,A,3,03,,11,14,,,25,31,,,,,3.3,1.8,2.8*32 +$GPGSV,2,1,08,03,23,224,43,09,06,037,00,11,17,314,39,14,75,015,44*71 +$GPGSV,2,2,08,15,18,138,00,18,20,079,00,25,27,172,39,31,27,263,40*7B +$PGRME,19.2,M,28.9,M,34.7,M*17 +$GPGLL,3348.451,N,11821.143,W,142224,A*3A +$PGRMZ,125,f,3*1D diff --git a/test/daemon/garmin38.log.chk b/test/daemon/garmin38.log.chk new file mode 100644 index 0000000..84e9db0 --- /dev/null +++ b/test/daemon/garmin38.log.chk @@ -0,0 +1,74 @@ +$PGRME,19.2,M,28.7,M,34.6,M*18 +$GPGLL,3348.452,N,11821.142,W,142214,A*3B +{"class":"TPV","tag":"GLL","lat":33.807533333,"lon":-118.352366667,"mode":2} +$PGRMZ,125,f,3*1D +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,142216,A,3348.452,N,11821.143,W,000.0,353.6,081002,013.8,E*66 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,142216,3348.452,N,11821.143,W,1,05,1.8,38.4,M,-32.4,M,,*4B +$GPGSA,A,3,03,,11,14,,,25,31,,,,,3.3,1.8,2.8*32 +$GPGSV,2,1,08,03,23,224,38,09,06,037,00,11,17,314,41,14,75,015,44*72 +$GPGSV,2,2,08,15,18,138,00,18,20,079,00,25,27,172,46,31,27,263,38*7C +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":0.70,"vdop":1.55,"tdop":0.79,"hdop":1.05,"gdop":2.04,"pdop":1.88,"satellites":[{"PRN":3,"el":23,"az":224,"ss":38,"used":true},{"PRN":9,"el":6,"az":37,"ss":0,"used":false},{"PRN":11,"el":17,"az":314,"ss":41,"used":true},{"PRN":14,"el":75,"az":15,"ss":44,"used":true},{"PRN":15,"el":18,"az":138,"ss":0,"used":false},{"PRN":18,"el":20,"az":79,"ss":0,"used":false},{"PRN":25,"el":27,"az":172,"ss":46,"used":true},{"PRN":31,"el":27,"az":263,"ss":38,"used":true}]} +$PGRME,19.2,M,28.7,M,34.6,M*18 +$GPGLL,3348.452,N,11821.143,W,142216,A*38 +{"class":"TPV","tag":"GLL","time":1034086936.000,"ept":0.005,"lat":33.807533333,"lon":-118.352383333,"alt":38.400,"epx":28.188,"epy":28.188,"epv":59.589,"track":353.6000,"speed":0.000,"climb":0.000,"mode":3} +$PGRMZ,126,f,3*1E +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,142218,A,3348.451,N,11821.144,W,000.0,353.6,081002,013.8,E*6C +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,142218,3348.451,N,11821.144,W,1,05,1.8,38.4,M,-32.4,M,,*41 +$GPGSA,A,3,03,,11,14,,,25,31,,,,,3.3,1.8,2.8*32 +$GPGSV,2,1,08,03,23,224,43,09,06,037,00,11,17,314,38,14,75,015,44*70 +$GPGSV,2,2,08,15,18,138,00,18,20,079,00,25,27,172,39,31,27,263,42*79 +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":0.70,"vdop":1.55,"tdop":0.79,"hdop":1.05,"gdop":2.04,"pdop":1.88,"satellites":[{"PRN":3,"el":23,"az":224,"ss":43,"used":true},{"PRN":9,"el":6,"az":37,"ss":0,"used":false},{"PRN":11,"el":17,"az":314,"ss":38,"used":true},{"PRN":14,"el":75,"az":15,"ss":44,"used":true},{"PRN":15,"el":18,"az":138,"ss":0,"used":false},{"PRN":18,"el":20,"az":79,"ss":0,"used":false},{"PRN":25,"el":27,"az":172,"ss":39,"used":true},{"PRN":31,"el":27,"az":263,"ss":42,"used":true}]} +$PGRME,19.2,M,28.7,M,34.6,M*18 +$GPGLL,3348.451,N,11821.144,W,142218,A*32 +{"class":"TPV","tag":"GLL","time":1034086938.000,"ept":0.005,"lat":33.807516667,"lon":-118.352400000,"alt":38.400,"epx":28.188,"epy":28.188,"epv":59.589,"track":353.6000,"speed":0.000,"climb":0.000,"eps":19.99,"mode":3} +$PGRMZ,126,f,3*1E +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,142220,A,3348.451,N,11821.142,W,000.0,353.6,081002,013.8,E*61 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,142220,3348.451,N,11821.142,W,1,05,1.8,37.6,M,-32.4,M,,*41 +$GPGSA,A,3,03,,11,14,,,25,31,,,,,3.3,1.8,2.8*32 +$GPGSV,2,1,08,03,23,224,43,09,06,037,00,11,17,314,38,14,75,015,43*77 +$GPGSV,2,2,08,15,18,138,00,18,20,079,00,25,27,172,39,31,27,263,41*7A +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":0.70,"vdop":1.55,"tdop":0.79,"hdop":1.05,"gdop":2.04,"pdop":1.88,"satellites":[{"PRN":3,"el":23,"az":224,"ss":43,"used":true},{"PRN":9,"el":6,"az":37,"ss":0,"used":false},{"PRN":11,"el":17,"az":314,"ss":38,"used":true},{"PRN":14,"el":75,"az":15,"ss":43,"used":true},{"PRN":15,"el":18,"az":138,"ss":0,"used":false},{"PRN":18,"el":20,"az":79,"ss":0,"used":false},{"PRN":25,"el":27,"az":172,"ss":39,"used":true},{"PRN":31,"el":27,"az":263,"ss":41,"used":true}]} +$PGRME,19.2,M,28.7,M,34.6,M*18 +$GPGLL,3348.451,N,11821.142,W,142220,A*3F +{"class":"TPV","tag":"GLL","time":1034086940.000,"ept":0.005,"lat":33.807516667,"lon":-118.352366667,"alt":37.600,"epx":28.188,"epy":28.188,"epv":59.589,"track":353.6000,"speed":0.000,"climb":0.000,"eps":19.99,"mode":3} +$PGRMZ,123,f,3*1B +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,142222,A,3348.451,N,11821.143,W,000.0,353.6,081002,013.8,E*62 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,142222,3348.451,N,11821.143,W,1,05,1.8,38.0,M,-32.4,M,,*4B +$GPGSA,A,3,03,,11,14,,,25,31,,,,,3.3,1.8,2.8*32 +$GPGSV,2,1,08,03,23,224,42,09,06,037,00,11,17,314,38,14,75,015,43*76 +$GPGSV,2,2,08,15,18,138,00,18,20,079,00,25,27,172,40,31,27,263,41*74 +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":0.70,"vdop":1.55,"tdop":0.79,"hdop":1.05,"gdop":2.04,"pdop":1.88,"satellites":[{"PRN":3,"el":23,"az":224,"ss":42,"used":true},{"PRN":9,"el":6,"az":37,"ss":0,"used":false},{"PRN":11,"el":17,"az":314,"ss":38,"used":true},{"PRN":14,"el":75,"az":15,"ss":43,"used":true},{"PRN":15,"el":18,"az":138,"ss":0,"used":false},{"PRN":18,"el":20,"az":79,"ss":0,"used":false},{"PRN":25,"el":27,"az":172,"ss":40,"used":true},{"PRN":31,"el":27,"az":263,"ss":41,"used":true}]} +$PGRME,19.2,M,28.9,M,34.7,M*17 +$GPGLL,3348.451,N,11821.143,W,142222,A*3C +{"class":"TPV","tag":"GLL","time":1034086942.000,"ept":0.005,"lat":33.807516667,"lon":-118.352383333,"alt":38.000,"epx":28.188,"epy":28.188,"epv":60.004,"track":353.6000,"speed":0.000,"climb":0.000,"eps":19.99,"mode":3} +$PGRMZ,125,f,3*1D +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,142224,A,3348.451,N,11821.143,W,000.0,353.6,081002,013.8,E*64 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,142224,3348.451,N,11821.143,W,1,05,1.8,38.0,M,-32.4,M,,*4D +$GPGSA,A,3,03,,11,14,,,25,31,,,,,3.3,1.8,2.8*32 +$GPGSV,2,1,08,03,23,224,43,09,06,037,00,11,17,314,39,14,75,015,44*71 +$GPGSV,2,2,08,15,18,138,00,18,20,079,00,25,27,172,39,31,27,263,40*7B +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":0.70,"vdop":1.55,"tdop":0.79,"hdop":1.05,"gdop":2.04,"pdop":1.88,"satellites":[{"PRN":3,"el":23,"az":224,"ss":43,"used":true},{"PRN":9,"el":6,"az":37,"ss":0,"used":false},{"PRN":11,"el":17,"az":314,"ss":39,"used":true},{"PRN":14,"el":75,"az":15,"ss":44,"used":true},{"PRN":15,"el":18,"az":138,"ss":0,"used":false},{"PRN":18,"el":20,"az":79,"ss":0,"used":false},{"PRN":25,"el":27,"az":172,"ss":39,"used":true},{"PRN":31,"el":27,"az":263,"ss":40,"used":true}]} +$PGRME,19.2,M,28.9,M,34.7,M*17 +$GPGLL,3348.451,N,11821.143,W,142224,A*3A +{"class":"TPV","tag":"GLL","time":1034086944.000,"ept":0.005,"lat":33.807516667,"lon":-118.352383333,"alt":38.000,"epx":28.188,"epy":28.188,"epv":60.004,"track":353.6000,"speed":0.000,"climb":0.000,"eps":19.99,"mode":3} +$PGRMZ,125,f,3*1D diff --git a/test/daemon/garmin48.log b/test/daemon/garmin48.log new file mode 100644 index 0000000..c4a32bb --- /dev/null +++ b/test/daemon/garmin48.log @@ -0,0 +1,106 @@ +# Name: Garmin 48 +# Chipset: Garmin proprietary +# Description: a handheld from about 2000. +# +# Note that the GPGLL timestamp has a 1-second offset +# from the GPRMC and GPGGA timestamps. Appears to take 2 fixes +# per cycle, GLL can include a fix update! +# +# Submitted-by: Hamish +# Date: 11 Mar 2005 +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPRMC,225308,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*6D +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225308,4527.458,S,16709.165,E,1,05,2.1,14.7,M,1.1,M,,*53 +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.1,2.1,2.0*3A +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,48,20,41,333,46,22,65,081,46,24,02,205,00*7B +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,39,,,,*4C +$PGRME,9.1,M,15.0,M,12.0,M*21 +$GPGLL,4527.458,S,16709.165,E,225309,A*3E +$PGRMZ,48,f,3*27 +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225310,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*64 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225310,4527.458,S,16709.165,E,1,05,2.1,14.6,M,1.1,M,,*5B +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.1,2.1,2.0*3A +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,48,20,41,333,46,22,65,081,46,24,02,205,00*7B +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,39,,,,*4C +$PGRME,9.1,M,15.0,M,12.0,M*21 +$GPGLL,4527.458,S,16709.165,E,225311,A*37 +$PGRMZ,48,f,3*27 +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225312,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*66 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225312,4527.458,S,16709.165,E,1,05,2.2,14.7,M,1.1,M,,*5B +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.2,2.2,2.1*3B +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,49,20,41,333,46,22,65,081,46,24,02,205,00*7A +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,39,,,,*4C +$PGRME,9.2,M,15.0,M,12.6,M*24 +$GPGLL,4527.458,S,16709.165,E,225313,A*35 +$PGRMZ,48,f,3*27 +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225314,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*60 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225314,4527.458,S,16709.165,E,1,05,2.2,14.6,M,1.1,M,,*5C +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.2,2.2,2.1*3B +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,49,20,41,333,46,22,65,081,46,24,02,205,00*7A +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,39,,,,*4C +$PGRME,9.2,M,15.0,M,12.6,M*24 +$GPGLL,4527.458,S,16709.165,E,225315,A*33 +$PGRMZ,48,f,3*27 +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225316,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*62 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225316,4527.458,S,16709.165,E,1,05,2.2,14.4,M,1.1,M,,*5C +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.2,2.2,2.1*3B +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,49,20,40,333,46,22,65,081,46,24,02,205,00*7B +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,39,,,,*4C +$PGRME,9.2,M,15.0,M,12.6,M*24 +$GPGLL,4527.458,S,16709.165,E,225317,A*31 +$PGRMZ,46,f,3*29 +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225318,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*6C +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225318,4527.458,S,16709.165,E,1,05,2.2,14.0,M,1.1,M,,*56 +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.2,2.2,2.1*3B +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*7 +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,49,20,40,333,46,22,65,083,46,24,02,205,00*79 +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,40,,,,*42 +$PGRME,10.3,M,15.2,M,16.7,M*1A +$GPGLL,4527.458,S,16709.165,E,225333,A*37 +$PGRMZ,41,f,3*2E +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225334,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*62 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225334,4527.458,S,16709.165,E,1,05,2.4,12.5,M,1.1,M,,*5D +$GPGSA,A,3,01,,,,13,20,22,,,,28,,4.1,2.4,3.0*39 +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,49,20,40,333,46,22,65,083,46,24,02,205,00*79 +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,41,,,,*43 +$PGRME,10.3,M,15.2,M,16.7,M*1A +$GPGLL,4527.458,S,16709.165,E,225335,A*31 +$PGRMZ,41,f,3*2E +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 diff --git a/test/daemon/garmin48.log.chk b/test/daemon/garmin48.log.chk new file mode 100644 index 0000000..1ecc706 --- /dev/null +++ b/test/daemon/garmin48.log.chk @@ -0,0 +1,113 @@ +$GPRMC,225308,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*6D +{"class":"TPV","tag":"RMC","time":991867988.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"track":94.5000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225308,4527.458,S,16709.165,E,1,05,2.1,14.7,M,1.1,M,,*53 +{"class":"TPV","tag":"GGA","time":991867988.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"alt":14.700,"track":94.5000,"speed":0.000,"mode":3} +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.1,2.1,2.0*3A +{"class":"TPV","tag":"GSA","time":991867988.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"alt":14.700,"epv":46.000,"track":94.5000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,48,20,41,333,46,22,65,081,46,24,02,205,00*7B +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,39,,,,*4C +{"class":"SKY","tag":"GSV","xdop":0.84,"ydop":0.92,"vdop":1.31,"tdop":0.71,"hdop":1.25,"gdop":1.94,"pdop":1.81,"satellites":[{"PRN":1,"el":78,"az":221,"ss":47,"used":true},{"PRN":3,"el":9,"az":42,"ss":0,"used":false},{"PRN":4,"el":5,"az":242,"ss":0,"used":false},{"PRN":6,"el":4,"az":149,"ss":0,"used":false},{"PRN":13,"el":37,"az":235,"ss":48,"used":true},{"PRN":20,"el":41,"az":333,"ss":46,"used":true},{"PRN":22,"el":65,"az":81,"ss":46,"used":true},{"PRN":24,"el":2,"az":205,"ss":0,"used":false},{"PRN":25,"el":20,"az":108,"ss":0,"used":false},{"PRN":27,"el":8,"az":281,"ss":0,"used":false},{"PRN":28,"el":17,"az":339,"ss":39,"used":true}]} +$PGRME,9.1,M,15.0,M,12.0,M*21 +$GPGLL,4527.458,S,16709.165,E,225309,A*3E +$PGRMZ,48,f,3*27 +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225310,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*64 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225310,4527.458,S,16709.165,E,1,05,2.1,14.6,M,1.1,M,,*5B +{"class":"TPV","tag":"GGA","time":991867990.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"alt":14.600,"epx":12.536,"epy":13.872,"epv":30.148,"track":94.5000,"speed":0.000,"eps":27.74,"mode":3} +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.1,2.1,2.0*3A +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,48,20,41,333,46,22,65,081,46,24,02,205,00*7B +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,39,,,,*4C +{"class":"SKY","tag":"GSV","xdop":0.84,"ydop":0.92,"vdop":1.31,"tdop":0.71,"hdop":1.25,"gdop":1.94,"pdop":1.81,"satellites":[{"PRN":1,"el":78,"az":221,"ss":47,"used":true},{"PRN":3,"el":9,"az":42,"ss":0,"used":false},{"PRN":4,"el":5,"az":242,"ss":0,"used":false},{"PRN":6,"el":4,"az":149,"ss":0,"used":false},{"PRN":13,"el":37,"az":235,"ss":48,"used":true},{"PRN":20,"el":41,"az":333,"ss":46,"used":true},{"PRN":22,"el":65,"az":81,"ss":46,"used":true},{"PRN":24,"el":2,"az":205,"ss":0,"used":false},{"PRN":25,"el":20,"az":108,"ss":0,"used":false},{"PRN":27,"el":8,"az":281,"ss":0,"used":false},{"PRN":28,"el":17,"az":339,"ss":39,"used":true}]} +$PGRME,9.1,M,15.0,M,12.0,M*21 +$GPGLL,4527.458,S,16709.165,E,225311,A*37 +{"class":"TPV","tag":"GLL","time":991867991.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"epx":12.536,"epy":13.872,"speed":0.000,"eps":27.23,"mode":2} +$PGRMZ,48,f,3*27 +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225312,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*66 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225312,4527.458,S,16709.165,E,1,05,2.2,14.7,M,1.1,M,,*5B +{"class":"TPV","tag":"GGA","time":991867992.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"alt":14.700,"epx":12.536,"epy":13.872,"epv":30.148,"track":94.5000,"speed":0.000,"eps":27.74,"mode":3} +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.2,2.2,2.1*3B +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,49,20,41,333,46,22,65,081,46,24,02,205,00*7A +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,39,,,,*4C +{"class":"SKY","tag":"GSV","xdop":0.84,"ydop":0.92,"vdop":1.31,"tdop":0.71,"hdop":1.25,"gdop":1.94,"pdop":1.81,"satellites":[{"PRN":1,"el":78,"az":221,"ss":47,"used":true},{"PRN":3,"el":9,"az":42,"ss":0,"used":false},{"PRN":4,"el":5,"az":242,"ss":0,"used":false},{"PRN":6,"el":4,"az":149,"ss":0,"used":false},{"PRN":13,"el":37,"az":235,"ss":49,"used":true},{"PRN":20,"el":41,"az":333,"ss":46,"used":true},{"PRN":22,"el":65,"az":81,"ss":46,"used":true},{"PRN":24,"el":2,"az":205,"ss":0,"used":false},{"PRN":25,"el":20,"az":108,"ss":0,"used":false},{"PRN":27,"el":8,"az":281,"ss":0,"used":false},{"PRN":28,"el":17,"az":339,"ss":39,"used":true}]} +$PGRME,9.2,M,15.0,M,12.6,M*24 +$GPGLL,4527.458,S,16709.165,E,225313,A*35 +{"class":"TPV","tag":"GLL","time":991867993.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"epx":12.536,"epy":13.872,"speed":0.000,"eps":27.38,"mode":2} +$PGRMZ,48,f,3*27 +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225314,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*60 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225314,4527.458,S,16709.165,E,1,05,2.2,14.6,M,1.1,M,,*5C +{"class":"TPV","tag":"GGA","time":991867994.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"alt":14.600,"epx":12.536,"epy":13.872,"epv":30.148,"track":94.5000,"speed":0.000,"eps":27.74,"mode":3} +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.2,2.2,2.1*3B +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,49,20,41,333,46,22,65,081,46,24,02,205,00*7A +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,39,,,,*4C +{"class":"SKY","tag":"GSV","xdop":0.84,"ydop":0.92,"vdop":1.31,"tdop":0.71,"hdop":1.25,"gdop":1.94,"pdop":1.81,"satellites":[{"PRN":1,"el":78,"az":221,"ss":47,"used":true},{"PRN":3,"el":9,"az":42,"ss":0,"used":false},{"PRN":4,"el":5,"az":242,"ss":0,"used":false},{"PRN":6,"el":4,"az":149,"ss":0,"used":false},{"PRN":13,"el":37,"az":235,"ss":49,"used":true},{"PRN":20,"el":41,"az":333,"ss":46,"used":true},{"PRN":22,"el":65,"az":81,"ss":46,"used":true},{"PRN":24,"el":2,"az":205,"ss":0,"used":false},{"PRN":25,"el":20,"az":108,"ss":0,"used":false},{"PRN":27,"el":8,"az":281,"ss":0,"used":false},{"PRN":28,"el":17,"az":339,"ss":39,"used":true}]} +$PGRME,9.2,M,15.0,M,12.6,M*24 +$GPGLL,4527.458,S,16709.165,E,225315,A*33 +{"class":"TPV","tag":"GLL","time":991867995.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"epx":12.536,"epy":13.872,"speed":0.000,"eps":27.38,"mode":2} +$PGRMZ,48,f,3*27 +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225316,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*62 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225316,4527.458,S,16709.165,E,1,05,2.2,14.4,M,1.1,M,,*5C +{"class":"TPV","tag":"GGA","time":991867996.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"alt":14.400,"epx":12.536,"epy":13.872,"epv":30.148,"track":94.5000,"speed":0.000,"eps":27.74,"mode":3} +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.2,2.2,2.1*3B +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,49,20,40,333,46,22,65,081,46,24,02,205,00*7B +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,39,,,,*4C +{"class":"SKY","tag":"GSV","xdop":0.84,"ydop":0.92,"vdop":1.31,"tdop":0.71,"hdop":1.25,"gdop":1.94,"pdop":1.81,"satellites":[{"PRN":1,"el":78,"az":221,"ss":47,"used":true},{"PRN":3,"el":9,"az":42,"ss":0,"used":false},{"PRN":4,"el":5,"az":242,"ss":0,"used":false},{"PRN":6,"el":4,"az":149,"ss":0,"used":false},{"PRN":13,"el":37,"az":235,"ss":49,"used":true},{"PRN":20,"el":40,"az":333,"ss":46,"used":true},{"PRN":22,"el":65,"az":81,"ss":46,"used":true},{"PRN":24,"el":2,"az":205,"ss":0,"used":false},{"PRN":25,"el":20,"az":108,"ss":0,"used":false},{"PRN":27,"el":8,"az":281,"ss":0,"used":false},{"PRN":28,"el":17,"az":339,"ss":39,"used":true}]} +$PGRME,9.2,M,15.0,M,12.6,M*24 +$GPGLL,4527.458,S,16709.165,E,225317,A*31 +{"class":"TPV","tag":"GLL","time":991867997.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"epx":12.536,"epy":13.872,"speed":0.000,"eps":27.38,"mode":2} +$PGRMZ,46,f,3*29 +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225318,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*6C +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225318,4527.458,S,16709.165,E,1,05,2.2,14.0,M,1.1,M,,*56 +{"class":"TPV","tag":"GGA","time":991867998.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"alt":14.000,"epx":12.536,"epy":13.872,"epv":30.148,"track":94.5000,"speed":0.000,"eps":27.74,"mode":3} +$GPGSA,A,3,01,,,,13,20,22,,,,28,,3.2,2.2,2.1*3B +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,49,20,40,333,46,22,65,083,46,24,02,205,00*79 +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,40,,,,*42 +{"class":"SKY","tag":"GSV","xdop":0.84,"ydop":0.92,"vdop":1.31,"tdop":0.71,"hdop":1.25,"gdop":1.94,"pdop":1.81,"satellites":[{"PRN":1,"el":78,"az":221,"ss":47,"used":true},{"PRN":3,"el":9,"az":42,"ss":0,"used":false},{"PRN":4,"el":5,"az":242,"ss":0,"used":false},{"PRN":6,"el":4,"az":149,"ss":0,"used":false},{"PRN":13,"el":37,"az":235,"ss":49,"used":true},{"PRN":20,"el":40,"az":333,"ss":46,"used":true},{"PRN":22,"el":65,"az":83,"ss":46,"used":true},{"PRN":24,"el":2,"az":205,"ss":0,"used":false},{"PRN":25,"el":20,"az":108,"ss":0,"used":false},{"PRN":27,"el":8,"az":281,"ss":0,"used":false},{"PRN":28,"el":17,"az":339,"ss":40,"used":true}]} +$PGRME,10.3,M,15.2,M,16.7,M*1A +$GPGLL,4527.458,S,16709.165,E,225333,A*37 +{"class":"TPV","tag":"GLL","time":991868013.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"epx":12.536,"epy":13.872,"speed":0.000,"eps":1.93,"mode":2} +$PGRMZ,41,f,3*2E +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,225334,A,4527.458,S,16709.165,E,000.0,094.5,060601,024.1,E*62 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,225334,4527.458,S,16709.165,E,1,05,2.4,12.5,M,1.1,M,,*5D +{"class":"TPV","tag":"GGA","time":991868014.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"alt":12.500,"epx":12.536,"epy":13.872,"epv":30.148,"track":94.5000,"speed":0.000,"eps":27.74,"mode":3} +$GPGSA,A,3,01,,,,13,20,22,,,,28,,4.1,2.4,3.0*39 +$GPGSV,3,1,11,01,78,221,47,03,09,042,00,04,05,242,00,06,04,149,00*70 +$GPGSV,3,2,11,13,37,235,49,20,40,333,46,22,65,083,46,24,02,205,00*79 +$GPGSV,3,3,11,25,20,108,00,27,08,281,00,28,17,339,41,,,,*43 +{"class":"SKY","tag":"GSV","xdop":0.84,"ydop":0.92,"vdop":1.31,"tdop":0.71,"hdop":1.25,"gdop":1.94,"pdop":1.81,"satellites":[{"PRN":1,"el":78,"az":221,"ss":47,"used":true},{"PRN":3,"el":9,"az":42,"ss":0,"used":false},{"PRN":4,"el":5,"az":242,"ss":0,"used":false},{"PRN":6,"el":4,"az":149,"ss":0,"used":false},{"PRN":13,"el":37,"az":235,"ss":49,"used":true},{"PRN":20,"el":40,"az":333,"ss":46,"used":true},{"PRN":22,"el":65,"az":83,"ss":46,"used":true},{"PRN":24,"el":2,"az":205,"ss":0,"used":false},{"PRN":25,"el":20,"az":108,"ss":0,"used":false},{"PRN":27,"el":8,"az":281,"ss":0,"used":false},{"PRN":28,"el":17,"az":339,"ss":41,"used":true}]} +$PGRME,10.3,M,15.2,M,16.7,M*1A +$GPGLL,4527.458,S,16709.165,E,225335,A*31 +{"class":"TPV","tag":"GLL","time":991868015.000,"ept":0.005,"lat":-45.457633333,"lon":167.152750000,"epx":12.536,"epy":13.872,"speed":0.000,"eps":28.99,"mode":2} +$PGRMZ,41,f,3*2E +$PGRMM,WGS 84*06 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 diff --git a/test/daemon/gps-360.log b/test/daemon/gps-360.log new file mode 100644 index 0000000..8224655 --- /dev/null +++ b/test/daemon/gps-360.log @@ -0,0 +1,259 @@ +# Name: Pharos GPS-360 +# Chipset: SiRfII +# Submitted-by: "Jeff Fisher" +# Date: 27 July 2006 +# Location: Regina, Saskatchewan, Canada, 50N104W +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021612.949,A,5029.3800,N,10441.0390,W,0.039560,189.06,280706,,*18 +$GPGGA,021613.949,5029.3800,N,10441.0389,W,1,04,12.5,572.4,M,-20.3,M,0.0,0000*7E +$GPGLL,5029.3800,N,10441.0389,W,021613.949,A*22 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021613.949,A,5029.3800,N,10441.0389,W,0.009850,267.99,280706,,*19 +$GPGGA,021614.949,5029.3800,N,10441.0388,W,1,04,12.5,572.3,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3800,N,10441.0388,W,021614.949,A*24 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,49,156,27,17,49,212,0,28,82,35,36,11,38,84,37*4A +$GPGSV,3,2,9,26,32,278,39,29,31,270,38,19,6,48,0,27,22,152,26*71 +$GPGSV,3,3,9,123,0,0,0*40 +$GPRMC,021614.949,A,5029.3800,N,10441.0388,W,0.016538,341.48,280706,,*1B +$GPGGA,021615.949,5029.3799,N,10441.0387,W,1,04,12.5,572.1,M,-20.3,M,0.0,0000*7C +$GPGLL,5029.3799,N,10441.0387,W,021615.949,A*25 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021615.949,A,5029.3799,N,10441.0387,W,0.024470,357.79,280706,,*13 +$GPGGA,021616.949,5029.3800,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7B +$GPGLL,5029.3800,N,10441.0387,W,021616.949,A*29 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021616.949,A,5029.3800,N,10441.0387,W,0.064679,355.50,280706,,*19 +$GPGGA,021617.949,5029.3800,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7A +$GPGLL,5029.3800,N,10441.0387,W,021617.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021617.949,A,5029.3800,N,10441.0387,W,0.081945,359.64,280706,,*18 +$GPGGA,021618.949,5029.3801,N,10441.0387,W,1,04,12.5,571.8,M,-20.3,M,0.0,0000*75 +$GPGLL,5029.3801,N,10441.0387,W,021618.949,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021618.949,A,5029.3801,N,10441.0387,W,0.123681,359.07,280706,,*1D +$GPGGA,021619.949,5029.3802,N,10441.0387,W,1,04,12.5,571.6,M,-20.3,M,0.0,0000*79 +$GPGLL,5029.3802,N,10441.0387,W,021619.949,A*24 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,25,17,50,212,0,28,82,37,36,11,38,84,36*42 +$GPGSV,3,2,9,26,32,277,39,29,31,270,38,19,6,48,0,27,22,152,20*78 +$GPGSV,3,3,9,123,0,0,0*40 +$GPRMC,021619.949,A,5029.3802,N,10441.0387,W,0.152675,359.28,280706,,*1F +$GPGGA,021620.949,5029.3803,N,10441.0387,W,1,04,12.5,571.7,M,-20.3,M,0.0,0000*73 +$GPGLL,5029.3803,N,10441.0387,W,021620.949,A*2F +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021620.949,A,5029.3803,N,10441.0387,W,0.149670,359.57,280706,,*13 +$GPGGA,021621.949,5029.3805,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7A +$GPGLL,5029.3805,N,10441.0387,W,021621.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021621.949,A,5029.3805,N,10441.0387,W,0.139805,358.04,280706,,*18 +$GPGGA,021622.949,5029.3806,N,10441.0387,W,1,04,12.5,571.7,M,-20.3,M,0.0,0000*74 +$GPGLL,5029.3806,N,10441.0387,W,021622.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021622.949,A,5029.3806,N,10441.0387,W,0.159851,358.60,280706,,*1D +$GPGGA,021623.949,5029.3808,N,10441.0387,W,1,04,12.5,571.2,M,-20.3,M,0.0,0000*7E +$GPGLL,5029.3808,N,10441.0387,W,021623.949,A*27 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021623.949,A,5029.3808,N,10441.0387,W,0.211601,1.82,280706,,*15 +$GPGGA,021624.949,5029.3810,N,10441.0386,W,1,04,12.5,570.7,M,-20.3,M,0.0,0000*75 +$GPGLL,5029.3810,N,10441.0386,W,021624.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,25,17,50,212,0,28,82,37,37,11,38,84,37*42 +$GPGSV,3,2,9,26,32,277,39,29,31,270,38,19,6,48,0,27,22,152,21*79 +$GPGSV,3,3,9,123,0,0,0*40 +$GPRMC,021624.949,A,5029.3810,N,10441.0386,W,0.200234,356.84,280706,,*1F +$GPGGA,021625.949,5029.3812,N,10441.0386,W,1,04,12.5,570.1,M,-20.3,M,0.0,0000*70 +$GPGLL,5029.3812,N,10441.0386,W,021625.949,A*2B +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021625.949,A,5029.3812,N,10441.0386,W,0.222299,359.84,280706,,*14 +$GPGGA,021626.949,5029.3814,N,10441.0385,W,1,04,12.5,569.4,M,-20.3,M,0.0,0000*7B +$GPGLL,5029.3814,N,10441.0385,W,021626.949,A*2D +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021626.949,A,5029.3814,N,10441.0385,W,0.196906,0.09,280706,,*19 +$GPGGA,021627.948,5029.3815,N,10441.0384,W,1,04,12.5,568.8,M,-20.3,M,0.0,0000*76 +$GPGLL,5029.3815,N,10441.0384,W,021627.948,A*2D +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021627.948,A,5029.3815,N,10441.0384,W,0.200037,355.83,280706,,*1F +$GPGGA,021628.948,5029.3828,N,10441.0382,W,1,05,2.0,567.6,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3828,N,10441.0382,W,021628.948,A*2A +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021628.948,A,5029.3828,N,10441.0382,W,0.144151,5.63,280706,,*12 +$GPGGA,021629.948,5029.3826,N,10441.0381,W,1,05,2.0,567.0,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3826,N,10441.0381,W,021629.948,A*26 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,39,29,31,270,37,19,6,48,0,27,22,152,28*7F +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021629.948,A,5029.3826,N,10441.0381,W,0.066422,8.45,280706,,*17 +$GPGGA,021630.948,5029.3826,N,10441.0380,W,1,04,12.5,567.0,M,-20.3,M,0.0,0000*73 +$GPGLL,5029.3826,N,10441.0380,W,021630.948,A*2F +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021630.948,A,5029.3826,N,10441.0380,W,0.067726,5.22,280706,,*14 +$GPGGA,021631.948,5029.3826,N,10441.0377,W,1,04,12.5,567.2,M,-20.3,M,0.0,0000*78 +$GPGLL,5029.3826,N,10441.0377,W,021631.948,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021631.948,A,5029.3826,N,10441.0377,W,0.050347,4.93,280706,,*11 +$GPGGA,021632.948,5029.3826,N,10441.0370,W,1,05,2.0,567.2,M,-20.3,M,0.0,0000*49 +$GPGLL,5029.3826,N,10441.0370,W,021632.948,A*22 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021632.948,A,5029.3826,N,10441.0370,W,0.033580,1.77,280706,,*12 +$GPGGA,021633.948,5029.3826,N,10441.0370,W,1,04,12.5,566.9,M,-20.3,M,0.0,0000*77 +$GPGLL,5029.3826,N,10441.0370,W,021633.948,A*23 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021633.948,A,5029.3826,N,10441.0370,W,0.019509,345.64,280706,,*1B +$GPGGA,021634.948,5029.3825,N,10441.0370,W,1,04,12.5,566.7,M,-20.3,M,0.0,0000*7D +$GPGLL,5029.3825,N,10441.0370,W,021634.948,A*27 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,38,29,31,270,37,19,6,48,0,27,22,152,27*71 +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021634.948,A,5029.3825,N,10441.0370,W,0.003955,192.84,280706,,*17 +$GPGGA,021635.948,5029.3825,N,10441.0370,W,1,04,12.5,566.4,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3825,N,10441.0370,W,021635.948,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021635.948,A,5029.3825,N,10441.0370,W,0.095177,180.09,280706,,*17 +$GPGGA,021636.948,5029.3825,N,10441.0371,W,1,05,2.0,565.5,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3825,N,10441.0371,W,021636.948,A*24 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021636.948,A,5029.3825,N,10441.0371,W,0.023886,330.86,280706,,*11 +$GPGGA,021637.948,5029.3827,N,10441.0372,W,1,05,2.0,566.2,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3827,N,10441.0372,W,021637.948,A*24 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021637.948,A,5029.3827,N,10441.0372,W,0.061487,357.24,280706,,*13 +$GPGGA,021638.948,5029.3824,N,10441.0374,W,1,05,2.0,566.2,M,-20.3,M,0.0,0000*44 +$GPGLL,5029.3824,N,10441.0374,W,021638.948,A*2E +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021638.948,A,5029.3824,N,10441.0374,W,0.024092,262.30,280706,,*1A +$GPGGA,021639.948,5029.3825,N,10441.0375,W,1,05,2.0,565.6,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3825,N,10441.0375,W,021639.948,A*2F +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,38,29,31,270,36,19,6,48,0,27,22,152,28*7F +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021639.948,A,5029.3825,N,10441.0375,W,0.024297,20.59,280706,,*27 +$GPGGA,021640.948,5029.3825,N,10441.0376,W,1,04,12.5,565.3,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3825,N,10441.0376,W,021640.948,A*22 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021640.948,A,5029.3825,N,10441.0376,W,0.027357,327.53,280706,,*1A +$GPGGA,021641.948,5029.3825,N,10441.0376,W,1,04,12.5,565.0,M,-20.3,M,0.0,0000*7D +$GPGLL,5029.3825,N,10441.0376,W,021641.948,A*23 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021641.948,A,5029.3825,N,10441.0376,W,0.039535,27.78,280706,,*2C +$GPGGA,021642.948,5029.3829,N,10441.0379,W,1,05,2.0,564.7,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3829,N,10441.0379,W,021642.948,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021642.948,A,5029.3829,N,10441.0379,W,0.167129,0.94,280706,,*18 +$GPGGA,021643.947,5029.3837,N,10441.0381,W,1,05,2.0,563.6,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3837,N,10441.0381,W,021643.947,A*25 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021643.947,A,5029.3837,N,10441.0381,W,0.234120,354.99,280706,,*1D +$GPGGA,021644.947,5029.3844,N,10441.0383,W,1,05,2.0,562.5,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3844,N,10441.0383,W,021644.947,A*24 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,33,28,82,37,36,11,38,84,35*46 +$GPGSV,3,2,9,26,32,277,37,29,31,270,36,19,6,48,0,27,22,152,25*7D +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021644.947,A,5029.3844,N,10441.0383,W,0.225686,357.97,280706,,*1A +$GPGGA,021645.947,5029.3848,N,10441.0383,W,1,06,1.4,561.4,M,-20.3,M,0.0,0000*46 +$GPGLL,5029.3848,N,10441.0383,W,021645.947,A*29 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021645.947,A,5029.3848,N,10441.0383,W,0.073479,119.81,280706,,*1B +$GPGGA,021646.947,5029.3851,N,10441.0382,W,1,05,2.0,561.1,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3851,N,10441.0382,W,021646.947,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021646.947,A,5029.3851,N,10441.0382,W,0.079997,2.84,280706,,*18 +$GPGGA,021647.947,5029.3853,N,10441.0382,W,1,05,2.0,560.4,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3853,N,10441.0382,W,021647.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021647.947,A,5029.3853,N,10441.0382,W,0.134821,345.50,280706,,*16 +$GPGGA,021648.947,5029.3855,N,10441.0380,W,1,05,2.0,560.0,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3855,N,10441.0380,W,021648.947,A*2B +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021648.947,A,5029.3855,N,10441.0380,W,0.135447,3.49,280706,,*19 +$GPGGA,021649.947,5029.3856,N,10441.0379,W,1,05,2.0,559.3,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3856,N,10441.0379,W,021649.947,A*2F +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,34,28,82,39,35,11,38,84,33*4A +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,28*7A +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021649.947,A,5029.3856,N,10441.0379,W,0.118754,16.61,280706,,*2D +$GPGGA,021650.947,5029.3857,N,10441.0380,W,1,05,2.0,559.1,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3857,N,10441.0380,W,021650.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021650.947,A,5029.3857,N,10441.0380,W,0.122534,2.49,280706,,*10 +$GPGGA,021651.947,5029.3856,N,10441.0382,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3856,N,10441.0382,W,021651.947,A*22 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021651.947,A,5029.3856,N,10441.0382,W,0.117097,1.44,280706,,*16 +$GPGGA,021652.947,5029.3856,N,10441.0383,W,1,05,2.0,559.6,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3856,N,10441.0383,W,021652.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021652.947,A,5029.3856,N,10441.0383,W,0.110183,9.39,280706,,*15 +$GPGGA,021653.947,5029.3855,N,10441.0382,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*43 +$GPGLL,5029.3855,N,10441.0382,W,021653.947,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021653.947,A,5029.3855,N,10441.0382,W,0.104481,9.00,280706,,*1E +$GPGGA,021654.947,5029.3855,N,10441.0381,W,1,05,2.0,559.5,M,-20.3,M,0.0,0000*46 +$GPGLL,5029.3855,N,10441.0381,W,021654.947,A*27 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,34,28,82,39,36,11,38,84,33*49 +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,0*40 +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021654.947,A,5029.3855,N,10441.0381,W,0.142516,3.80,280706,,*15 +$GPGGA,021655.947,5029.3855,N,10441.0381,W,1,05,2.0,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0381,W,021655.947,A*26 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021655.947,A,5029.3855,N,10441.0381,W,0.120701,358.47,280706,,*12 +$GPGGA,021656.947,5029.3855,N,10441.0379,W,1,06,1.4,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0379,W,021656.947,A*22 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021656.947,A,5029.3855,N,10441.0379,W,0.094143,14.12,280706,,*23 +$GPGGA,021657.947,5029.3855,N,10441.0378,W,1,06,1.4,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0378,W,021657.947,A*22 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021657.947,A,5029.3855,N,10441.0378,W,0.096695,9.89,280706,,*13 +$GPGGA,021658.947,5029.3855,N,10441.0378,W,1,05,2.0,560.0,M,-20.3,M,0.0,0000*43 +$GPGLL,5029.3855,N,10441.0378,W,021658.947,A*2D +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021658.947,A,5029.3855,N,10441.0378,W,0.111024,0.77,280706,,*16 +$GPGGA,021659.946,5029.3855,N,10441.0376,W,1,05,2.0,559.8,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3855,N,10441.0376,W,021659.946,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,33,28,82,39,36,11,38,84,32*4F +$GPGSV,3,2,9,26,32,277,36,29,31,269,34,19,6,48,0,27,22,152,27*74 +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021659.946,A,5029.3855,N,10441.0376,W,0.144243,359.38,280706,,*1F +$GPGGA,021700.946,5029.3856,N,10441.0373,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3856,N,10441.0373,W,021700.946,A*28 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021700.946,A,5029.3856,N,10441.0373,W,0.127513,359.47,280706,,*1B +$GPGGA,021701.946,5029.3856,N,10441.0369,W,1,05,2.0,558.6,M,-20.3,M,0.0,0000*41 +$GPGLL,5029.3856,N,10441.0369,W,021701.946,A*22 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021701.946,A,5029.3856,N,10441.0369,W,0.082985,16.78,280706,,*28 +$GPGGA,021702.946,5029.3856,N,10441.0365,W,1,05,2.0,557.8,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3856,N,10441.0365,W,021702.946,A*2D +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021702.946,A,5029.3856,N,10441.0365,W,0.108057,8.59,280706,,*1E +$GPGGA,021703.946,5029.3857,N,10441.0363,W,1,05,2.0,556.8,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3857,N,10441.0363,W,021703.946,A*2B +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021703.946,A,5029.3857,N,10441.0363,W,0.193741,10.55,280706,,*2F +$GPGGA,021704.946,5029.3858,N,10441.0363,W,1,07,1.3,556.0,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3858,N,10441.0363,W,021704.946,A*23 +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A +$GPGSV,3,1,9,8,48,156,31,17,50,212,32,28,82,39,39,11,38,84,33*72 +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,30*73 +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021704.946,A,5029.3858,N,10441.0363,W,0.096613,335.19,280706,,*19 +$GPGGA,021705.946,5029.3859,N,10441.0363,W,1,07,1.3,555.4,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3859,N,10441.0363,W,021705.946,A*23 +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A +$GPRMC,021705.946,A,5029.3859,N,10441.0363,W,0.061763,22.98,280706,,*2B +$GPGGA,021706.946,5029.3860,N,10441.0364,W,1,07,1.3,554.9,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3860,N,10441.0364,W,021706.946,A*2D +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A diff --git a/test/daemon/gps-360.log.chk b/test/daemon/gps-360.log.chk new file mode 100644 index 0000000..67fe25c --- /dev/null +++ b/test/daemon/gps-360.log.chk @@ -0,0 +1,316 @@ +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +{"class":"TPV","tag":"GSA","epv":71.300,"mode":3} +$GPRMC,021612.949,A,5029.3800,N,10441.0390,W,0.039560,189.06,280706,,*18 +{"class":"TPV","tag":"RMC","time":1154052972.949,"ept":0.005,"lat":50.489666667,"lon":-104.683983333,"track":189.0600,"speed":0.020,"mode":2} +$GPGGA,021613.949,5029.3800,N,10441.0389,W,1,04,12.5,572.4,M,-20.3,M,0.0,0000*7E +$GPGLL,5029.3800,N,10441.0389,W,021613.949,A*22 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021613.949,A,5029.3800,N,10441.0389,W,0.009850,267.99,280706,,*19 +{"class":"TPV","tag":"RMC","time":1154052973.949,"ept":0.005,"lat":50.489666667,"lon":-104.683981667,"alt":572.400,"epv":71.300,"track":267.9900,"speed":0.005,"climb":0.000,"mode":3} +$GPGGA,021614.949,5029.3800,N,10441.0388,W,1,04,12.5,572.3,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3800,N,10441.0388,W,021614.949,A*24 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,49,156,27,17,49,212,0,28,82,35,36,11,38,84,37*4A +$GPGSV,3,2,9,26,32,278,39,29,31,270,38,19,6,48,0,27,22,152,26*71 +$GPGSV,3,3,9,123,0,0,0*40 +{"class":"SKY","tag":"GSV","xdop":2.18,"ydop":2.31,"vdop":5.67,"tdop":5.16,"hdop":3.18,"gdop":8.30,"pdop":6.50,"satellites":[{"PRN":8,"el":49,"az":156,"ss":27,"used":false},{"PRN":17,"el":49,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":35,"ss":36,"used":true},{"PRN":11,"el":38,"az":84,"ss":37,"used":true},{"PRN":26,"el":32,"az":278,"ss":39,"used":true},{"PRN":29,"el":31,"az":270,"ss":38,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":26,"used":false},{"PRN":123,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021614.949,A,5029.3800,N,10441.0388,W,0.016538,341.48,280706,,*1B +{"class":"TPV","tag":"RMC","time":1154052974.949,"ept":0.005,"lat":50.489666667,"lon":-104.683980000,"alt":572.300,"epx":32.645,"epy":34.721,"epv":71.300,"track":341.4800,"speed":0.009,"climb":-0.100,"mode":3} +$GPGGA,021615.949,5029.3799,N,10441.0387,W,1,04,12.5,572.1,M,-20.3,M,0.0,0000*7C +$GPGLL,5029.3799,N,10441.0387,W,021615.949,A*25 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021615.949,A,5029.3799,N,10441.0387,W,0.024470,357.79,280706,,*13 +{"class":"TPV","tag":"RMC","time":1154052975.949,"ept":0.005,"lat":50.489665000,"lon":-104.683978333,"alt":572.100,"epx":32.645,"epy":34.721,"epv":130.377,"track":357.7900,"speed":0.013,"climb":-0.200,"eps":69.44,"mode":3} +$GPGGA,021616.949,5029.3800,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7B +$GPGLL,5029.3800,N,10441.0387,W,021616.949,A*29 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021616.949,A,5029.3800,N,10441.0387,W,0.064679,355.50,280706,,*19 +{"class":"TPV","tag":"RMC","time":1154052976.949,"ept":0.005,"lat":50.489666667,"lon":-104.683978333,"alt":571.900,"epx":32.645,"epy":34.721,"epv":71.300,"track":355.5000,"speed":0.033,"climb":-0.200,"eps":69.44,"mode":3} +$GPGGA,021617.949,5029.3800,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7A +$GPGLL,5029.3800,N,10441.0387,W,021617.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021617.949,A,5029.3800,N,10441.0387,W,0.081945,359.64,280706,,*18 +{"class":"TPV","tag":"RMC","time":1154052977.949,"ept":0.005,"lat":50.489666667,"lon":-104.683978333,"alt":571.900,"epx":32.645,"epy":34.721,"epv":71.300,"track":359.6400,"speed":0.042,"climb":0.000,"eps":69.44,"mode":3} +$GPGGA,021618.949,5029.3801,N,10441.0387,W,1,04,12.5,571.8,M,-20.3,M,0.0,0000*75 +$GPGLL,5029.3801,N,10441.0387,W,021618.949,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021618.949,A,5029.3801,N,10441.0387,W,0.123681,359.07,280706,,*1D +{"class":"TPV","tag":"RMC","time":1154052978.949,"ept":0.005,"lat":50.489668333,"lon":-104.683978333,"alt":571.800,"epx":32.645,"epy":34.721,"epv":71.300,"track":359.0700,"speed":0.064,"climb":-0.100,"eps":69.44,"mode":3} +$GPGGA,021619.949,5029.3802,N,10441.0387,W,1,04,12.5,571.6,M,-20.3,M,0.0,0000*79 +$GPGLL,5029.3802,N,10441.0387,W,021619.949,A*24 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,25,17,50,212,0,28,82,37,36,11,38,84,36*42 +$GPGSV,3,2,9,26,32,277,39,29,31,270,38,19,6,48,0,27,22,152,20*78 +$GPGSV,3,3,9,123,0,0,0*40 +{"class":"SKY","tag":"GSV","xdop":2.28,"ydop":2.35,"vdop":5.94,"tdop":5.42,"hdop":3.27,"gdop":8.68,"pdop":6.79,"satellites":[{"PRN":8,"el":48,"az":156,"ss":25,"used":false},{"PRN":17,"el":50,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":37,"ss":36,"used":true},{"PRN":11,"el":38,"az":84,"ss":36,"used":true},{"PRN":26,"el":32,"az":277,"ss":39,"used":true},{"PRN":29,"el":31,"az":270,"ss":38,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":20,"used":false},{"PRN":123,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021619.949,A,5029.3802,N,10441.0387,W,0.152675,359.28,280706,,*1F +{"class":"TPV","tag":"RMC","time":1154052979.949,"ept":0.005,"lat":50.489670000,"lon":-104.683978333,"alt":571.600,"epx":32.645,"epy":34.721,"epv":71.300,"track":359.2800,"speed":0.079,"climb":-0.200,"eps":69.44,"mode":3} +$GPGGA,021620.949,5029.3803,N,10441.0387,W,1,04,12.5,571.7,M,-20.3,M,0.0,0000*73 +$GPGLL,5029.3803,N,10441.0387,W,021620.949,A*2F +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021620.949,A,5029.3803,N,10441.0387,W,0.149670,359.57,280706,,*13 +{"class":"TPV","tag":"RMC","time":1154052980.949,"ept":0.005,"lat":50.489671667,"lon":-104.683978333,"alt":571.700,"epx":34.137,"epy":35.324,"epv":136.685,"track":359.5700,"speed":0.077,"climb":0.100,"eps":70.04,"mode":3} +$GPGGA,021621.949,5029.3805,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7A +$GPGLL,5029.3805,N,10441.0387,W,021621.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021621.949,A,5029.3805,N,10441.0387,W,0.139805,358.04,280706,,*18 +{"class":"TPV","tag":"RMC","time":1154052981.949,"ept":0.005,"lat":50.489675000,"lon":-104.683978333,"alt":571.900,"epx":34.137,"epy":35.324,"epv":71.300,"track":358.0400,"speed":0.072,"climb":0.200,"eps":70.65,"mode":3} +$GPGGA,021622.949,5029.3806,N,10441.0387,W,1,04,12.5,571.7,M,-20.3,M,0.0,0000*74 +$GPGLL,5029.3806,N,10441.0387,W,021622.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021622.949,A,5029.3806,N,10441.0387,W,0.159851,358.60,280706,,*1D +{"class":"TPV","tag":"RMC","time":1154052982.949,"ept":0.005,"lat":50.489676667,"lon":-104.683978333,"alt":571.700,"epx":34.137,"epy":35.324,"epv":71.300,"track":358.6000,"speed":0.082,"climb":-0.200,"eps":70.65,"mode":3} +$GPGGA,021623.949,5029.3808,N,10441.0387,W,1,04,12.5,571.2,M,-20.3,M,0.0,0000*7E +$GPGLL,5029.3808,N,10441.0387,W,021623.949,A*27 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021623.949,A,5029.3808,N,10441.0387,W,0.211601,1.82,280706,,*15 +{"class":"TPV","tag":"RMC","time":1154052983.949,"ept":0.005,"lat":50.489680000,"lon":-104.683978333,"alt":571.200,"epx":34.137,"epy":35.324,"epv":71.300,"track":1.8200,"speed":0.109,"climb":-0.500,"eps":70.65,"mode":3} +$GPGGA,021624.949,5029.3810,N,10441.0386,W,1,04,12.5,570.7,M,-20.3,M,0.0,0000*75 +$GPGLL,5029.3810,N,10441.0386,W,021624.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,25,17,50,212,0,28,82,37,37,11,38,84,37*42 +$GPGSV,3,2,9,26,32,277,39,29,31,270,38,19,6,48,0,27,22,152,21*79 +$GPGSV,3,3,9,123,0,0,0*40 +{"class":"SKY","tag":"GSV","xdop":2.28,"ydop":2.35,"vdop":5.94,"tdop":5.42,"hdop":3.27,"gdop":8.68,"pdop":6.79,"satellites":[{"PRN":8,"el":48,"az":156,"ss":25,"used":false},{"PRN":17,"el":50,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":37,"ss":37,"used":true},{"PRN":11,"el":38,"az":84,"ss":37,"used":true},{"PRN":26,"el":32,"az":277,"ss":39,"used":true},{"PRN":29,"el":31,"az":270,"ss":38,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":21,"used":false},{"PRN":123,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021624.949,A,5029.3810,N,10441.0386,W,0.200234,356.84,280706,,*1F +{"class":"TPV","tag":"RMC","time":1154052984.949,"ept":0.005,"lat":50.489683333,"lon":-104.683976667,"alt":570.700,"epx":34.137,"epy":35.324,"epv":71.300,"track":356.8400,"speed":0.103,"climb":-0.500,"eps":70.65,"mode":3} +$GPGGA,021625.949,5029.3812,N,10441.0386,W,1,04,12.5,570.1,M,-20.3,M,0.0,0000*70 +$GPGLL,5029.3812,N,10441.0386,W,021625.949,A*2B +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021625.949,A,5029.3812,N,10441.0386,W,0.222299,359.84,280706,,*14 +{"class":"TPV","tag":"RMC","time":1154052985.949,"ept":0.005,"lat":50.489686667,"lon":-104.683976667,"alt":570.100,"epx":34.137,"epy":35.324,"epv":136.685,"track":359.8400,"speed":0.114,"climb":-0.600,"eps":70.65,"mode":3} +$GPGGA,021626.949,5029.3814,N,10441.0385,W,1,04,12.5,569.4,M,-20.3,M,0.0,0000*7B +$GPGLL,5029.3814,N,10441.0385,W,021626.949,A*2D +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021626.949,A,5029.3814,N,10441.0385,W,0.196906,0.09,280706,,*19 +{"class":"TPV","tag":"RMC","time":1154052986.949,"ept":0.005,"lat":50.489690000,"lon":-104.683975000,"alt":569.400,"epx":34.137,"epy":35.324,"epv":71.300,"track":0.0900,"speed":0.101,"climb":-0.700,"eps":70.65,"mode":3} +$GPGGA,021627.948,5029.3815,N,10441.0384,W,1,04,12.5,568.8,M,-20.3,M,0.0,0000*76 +$GPGLL,5029.3815,N,10441.0384,W,021627.948,A*2D +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021627.948,A,5029.3815,N,10441.0384,W,0.200037,355.83,280706,,*1F +{"class":"TPV","tag":"RMC","time":1154052987.948,"ept":0.005,"lat":50.489691667,"lon":-104.683973333,"alt":568.800,"epx":34.137,"epy":35.324,"epv":71.300,"track":355.8300,"speed":0.103,"climb":-0.601,"eps":70.72,"mode":3} +$GPGGA,021628.948,5029.3828,N,10441.0382,W,1,05,2.0,567.6,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3828,N,10441.0382,W,021628.948,A*2A +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021628.948,A,5029.3828,N,10441.0382,W,0.144151,5.63,280706,,*12 +{"class":"TPV","tag":"RMC","time":1154052988.948,"ept":0.005,"lat":50.489713333,"lon":-104.683970000,"alt":567.600,"epx":34.137,"epy":35.324,"epv":71.300,"track":5.6300,"speed":0.074,"climb":-1.200,"eps":70.65,"mode":3} +$GPGGA,021629.948,5029.3826,N,10441.0381,W,1,05,2.0,567.0,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3826,N,10441.0381,W,021629.948,A*26 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,39,29,31,270,37,19,6,48,0,27,22,152,28*7F +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.35,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":37,"ss":37,"used":true},{"PRN":11,"el":38,"az":84,"ss":36,"used":true},{"PRN":26,"el":32,"az":277,"ss":39,"used":true},{"PRN":29,"el":31,"az":270,"ss":37,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":28,"used":true},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021629.948,A,5029.3826,N,10441.0381,W,0.066422,8.45,280706,,*17 +{"class":"TPV","tag":"RMC","time":1154052989.948,"ept":0.005,"lat":50.489710000,"lon":-104.683968333,"alt":567.000,"epx":34.137,"epy":35.324,"epv":69.000,"track":8.4500,"speed":0.034,"climb":-0.600,"eps":70.65,"mode":3} +$GPGGA,021630.948,5029.3826,N,10441.0380,W,1,04,12.5,567.0,M,-20.3,M,0.0,0000*73 +$GPGLL,5029.3826,N,10441.0380,W,021630.948,A*2F +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021630.948,A,5029.3826,N,10441.0380,W,0.067726,5.22,280706,,*14 +{"class":"TPV","tag":"RMC","time":1154052990.948,"ept":0.005,"lat":50.489710000,"lon":-104.683966667,"alt":567.000,"epx":12.458,"epy":20.312,"epv":67.773,"track":5.2200,"speed":0.035,"climb":0.000,"eps":55.64,"mode":3} +$GPGGA,021631.948,5029.3826,N,10441.0377,W,1,04,12.5,567.2,M,-20.3,M,0.0,0000*78 +$GPGLL,5029.3826,N,10441.0377,W,021631.948,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021631.948,A,5029.3826,N,10441.0377,W,0.050347,4.93,280706,,*11 +{"class":"TPV","tag":"RMC","time":1154052991.948,"ept":0.005,"lat":50.489710000,"lon":-104.683961667,"alt":567.200,"epx":12.458,"epy":20.312,"epv":71.300,"track":4.9300,"speed":0.026,"climb":0.200,"eps":40.62,"mode":3} +$GPGGA,021632.948,5029.3826,N,10441.0370,W,1,05,2.0,567.2,M,-20.3,M,0.0,0000*49 +$GPGLL,5029.3826,N,10441.0370,W,021632.948,A*22 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021632.948,A,5029.3826,N,10441.0370,W,0.033580,1.77,280706,,*12 +{"class":"TPV","tag":"RMC","time":1154052992.948,"ept":0.005,"lat":50.489710000,"lon":-104.683950000,"alt":567.200,"epx":12.458,"epy":20.312,"epv":71.300,"track":1.7700,"speed":0.017,"climb":0.000,"eps":40.62,"mode":3} +$GPGGA,021633.948,5029.3826,N,10441.0370,W,1,04,12.5,566.9,M,-20.3,M,0.0,0000*77 +$GPGLL,5029.3826,N,10441.0370,W,021633.948,A*23 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021633.948,A,5029.3826,N,10441.0370,W,0.019509,345.64,280706,,*1B +{"class":"TPV","tag":"RMC","time":1154052993.948,"ept":0.005,"lat":50.489710000,"lon":-104.683950000,"alt":566.900,"epx":12.458,"epy":20.312,"epv":69.000,"track":345.6400,"speed":0.010,"climb":-0.300,"eps":40.62,"mode":3} +$GPGGA,021634.948,5029.3825,N,10441.0370,W,1,04,12.5,566.7,M,-20.3,M,0.0,0000*7D +$GPGLL,5029.3825,N,10441.0370,W,021634.948,A*27 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,38,29,31,270,37,19,6,48,0,27,22,152,27*71 +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":2.28,"ydop":2.35,"vdop":5.94,"tdop":5.42,"hdop":3.27,"gdop":8.68,"pdop":6.79,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":37,"ss":37,"used":true},{"PRN":11,"el":38,"az":84,"ss":36,"used":true},{"PRN":26,"el":32,"az":277,"ss":38,"used":true},{"PRN":29,"el":31,"az":270,"ss":37,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":27,"used":false},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021634.948,A,5029.3825,N,10441.0370,W,0.003955,192.84,280706,,*17 +{"class":"TPV","tag":"RMC","time":1154052994.948,"ept":0.005,"lat":50.489708333,"lon":-104.683950000,"alt":566.700,"epx":12.458,"epy":20.312,"epv":71.300,"track":192.8400,"speed":0.002,"climb":-0.200,"eps":40.62,"mode":3} +$GPGGA,021635.948,5029.3825,N,10441.0370,W,1,04,12.5,566.4,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3825,N,10441.0370,W,021635.948,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021635.948,A,5029.3825,N,10441.0370,W,0.095177,180.09,280706,,*17 +{"class":"TPV","tag":"RMC","time":1154052995.948,"ept":0.005,"lat":50.489708333,"lon":-104.683950000,"alt":566.400,"epx":34.137,"epy":35.324,"epv":136.685,"track":180.0900,"speed":0.049,"climb":-0.300,"eps":55.64,"mode":3} +$GPGGA,021636.948,5029.3825,N,10441.0371,W,1,05,2.0,565.5,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3825,N,10441.0371,W,021636.948,A*24 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021636.948,A,5029.3825,N,10441.0371,W,0.023886,330.86,280706,,*11 +{"class":"TPV","tag":"RMC","time":1154052996.948,"ept":0.005,"lat":50.489708333,"lon":-104.683951667,"alt":565.500,"epx":34.137,"epy":35.324,"epv":71.300,"track":330.8600,"speed":0.012,"climb":-0.900,"eps":70.65,"mode":3} +$GPGGA,021637.948,5029.3827,N,10441.0372,W,1,05,2.0,566.2,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3827,N,10441.0372,W,021637.948,A*24 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021637.948,A,5029.3827,N,10441.0372,W,0.061487,357.24,280706,,*13 +{"class":"TPV","tag":"RMC","time":1154052997.948,"ept":0.005,"lat":50.489711667,"lon":-104.683953333,"alt":566.200,"epx":34.137,"epy":35.324,"epv":69.000,"track":357.2400,"speed":0.032,"climb":0.700,"eps":70.65,"mode":3} +$GPGGA,021638.948,5029.3824,N,10441.0374,W,1,05,2.0,566.2,M,-20.3,M,0.0,0000*44 +$GPGLL,5029.3824,N,10441.0374,W,021638.948,A*2E +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021638.948,A,5029.3824,N,10441.0374,W,0.024092,262.30,280706,,*1A +{"class":"TPV","tag":"RMC","time":1154052998.948,"ept":0.005,"lat":50.489706667,"lon":-104.683956667,"alt":566.200,"epx":34.137,"epy":35.324,"epv":69.000,"track":262.3000,"speed":0.012,"climb":0.000,"eps":70.65,"mode":3} +$GPGGA,021639.948,5029.3825,N,10441.0375,W,1,05,2.0,565.6,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3825,N,10441.0375,W,021639.948,A*2F +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,38,29,31,270,36,19,6,48,0,27,22,152,28*7F +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.35,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":37,"ss":37,"used":true},{"PRN":11,"el":38,"az":84,"ss":36,"used":true},{"PRN":26,"el":32,"az":277,"ss":38,"used":true},{"PRN":29,"el":31,"az":270,"ss":36,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":28,"used":true},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021639.948,A,5029.3825,N,10441.0375,W,0.024297,20.59,280706,,*27 +{"class":"TPV","tag":"RMC","time":1154052999.948,"ept":0.005,"lat":50.489708333,"lon":-104.683958333,"alt":565.600,"epx":34.137,"epy":35.324,"epv":69.000,"track":20.5900,"speed":0.012,"climb":-0.600,"eps":70.65,"mode":3} +$GPGGA,021640.948,5029.3825,N,10441.0376,W,1,04,12.5,565.3,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3825,N,10441.0376,W,021640.948,A*22 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021640.948,A,5029.3825,N,10441.0376,W,0.027357,327.53,280706,,*1A +{"class":"TPV","tag":"RMC","time":1154053000.948,"ept":0.005,"lat":50.489708333,"lon":-104.683960000,"alt":565.300,"epx":12.458,"epy":20.312,"epv":67.773,"track":327.5300,"speed":0.014,"climb":-0.300,"eps":55.64,"mode":3} +$GPGGA,021641.948,5029.3825,N,10441.0376,W,1,04,12.5,565.0,M,-20.3,M,0.0,0000*7D +$GPGLL,5029.3825,N,10441.0376,W,021641.948,A*23 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021641.948,A,5029.3825,N,10441.0376,W,0.039535,27.78,280706,,*2C +{"class":"TPV","tag":"RMC","time":1154053001.948,"ept":0.005,"lat":50.489708333,"lon":-104.683960000,"alt":565.000,"epx":12.458,"epy":20.312,"epv":71.300,"track":27.7800,"speed":0.020,"climb":-0.300,"eps":40.62,"mode":3} +$GPGGA,021642.948,5029.3829,N,10441.0379,W,1,05,2.0,564.7,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3829,N,10441.0379,W,021642.948,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021642.948,A,5029.3829,N,10441.0379,W,0.167129,0.94,280706,,*18 +{"class":"TPV","tag":"RMC","time":1154053002.948,"ept":0.005,"lat":50.489715000,"lon":-104.683965000,"alt":564.700,"epx":12.458,"epy":20.312,"epv":71.300,"track":0.9400,"speed":0.086,"climb":-0.300,"eps":40.62,"mode":3} +$GPGGA,021643.947,5029.3837,N,10441.0381,W,1,05,2.0,563.6,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3837,N,10441.0381,W,021643.947,A*25 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021643.947,A,5029.3837,N,10441.0381,W,0.234120,354.99,280706,,*1D +{"class":"TPV","tag":"RMC","time":1154053003.947,"ept":0.005,"lat":50.489728333,"lon":-104.683968333,"alt":563.600,"epx":12.458,"epy":20.312,"epv":64.400,"track":354.9900,"speed":0.120,"climb":-1.101,"eps":40.66,"mode":3} +$GPGGA,021644.947,5029.3844,N,10441.0383,W,1,05,2.0,562.5,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3844,N,10441.0383,W,021644.947,A*24 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,33,28,82,37,36,11,38,84,35*46 +$GPGSV,3,2,9,26,32,277,37,29,31,270,36,19,6,48,0,27,22,152,25*7D +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.35,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":33,"used":true},{"PRN":28,"el":82,"az":37,"ss":36,"used":true},{"PRN":11,"el":38,"az":84,"ss":35,"used":true},{"PRN":26,"el":32,"az":277,"ss":37,"used":true},{"PRN":29,"el":31,"az":270,"ss":36,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":25,"used":false},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021644.947,A,5029.3844,N,10441.0383,W,0.225686,357.97,280706,,*1A +{"class":"TPV","tag":"RMC","time":1154053004.947,"ept":0.005,"lat":50.489740000,"lon":-104.683971667,"alt":562.500,"epx":12.458,"epy":20.312,"epv":64.400,"track":357.9700,"speed":0.116,"climb":-1.100,"eps":40.62,"mode":3} +$GPGGA,021645.947,5029.3848,N,10441.0383,W,1,06,1.4,561.4,M,-20.3,M,0.0,0000*46 +$GPGLL,5029.3848,N,10441.0383,W,021645.947,A*29 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021645.947,A,5029.3848,N,10441.0383,W,0.073479,119.81,280706,,*1B +{"class":"TPV","tag":"RMC","time":1154053005.947,"ept":0.005,"lat":50.489746667,"lon":-104.683971667,"alt":561.400,"epx":12.458,"epy":20.312,"epv":67.773,"track":119.8100,"speed":0.038,"climb":-1.100,"eps":40.62,"mode":3} +$GPGGA,021646.947,5029.3851,N,10441.0382,W,1,05,2.0,561.1,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3851,N,10441.0382,W,021646.947,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021646.947,A,5029.3851,N,10441.0382,W,0.079997,2.84,280706,,*18 +{"class":"TPV","tag":"RMC","time":1154053006.947,"ept":0.005,"lat":50.489751667,"lon":-104.683970000,"alt":561.100,"epx":12.458,"epy":20.312,"epv":52.900,"track":2.8400,"speed":0.041,"climb":-0.300,"eps":40.62,"mode":3} +$GPGGA,021647.947,5029.3853,N,10441.0382,W,1,05,2.0,560.4,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3853,N,10441.0382,W,021647.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021647.947,A,5029.3853,N,10441.0382,W,0.134821,345.50,280706,,*16 +{"class":"TPV","tag":"RMC","time":1154053007.947,"ept":0.005,"lat":50.489755000,"lon":-104.683970000,"alt":560.400,"epx":12.458,"epy":20.312,"epv":64.400,"track":345.5000,"speed":0.069,"climb":-0.700,"eps":40.62,"mode":3} +$GPGGA,021648.947,5029.3855,N,10441.0380,W,1,05,2.0,560.0,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3855,N,10441.0380,W,021648.947,A*2B +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021648.947,A,5029.3855,N,10441.0380,W,0.135447,3.49,280706,,*19 +{"class":"TPV","tag":"RMC","time":1154053008.947,"ept":0.005,"lat":50.489758333,"lon":-104.683966667,"alt":560.000,"epx":12.458,"epy":20.312,"epv":64.400,"track":3.4900,"speed":0.070,"climb":-0.400,"eps":40.62,"mode":3} +$GPGGA,021649.947,5029.3856,N,10441.0379,W,1,05,2.0,559.3,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3856,N,10441.0379,W,021649.947,A*2F +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,34,28,82,39,35,11,38,84,33*4A +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,28*7A +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.36,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":34,"used":true},{"PRN":28,"el":82,"az":39,"ss":35,"used":true},{"PRN":11,"el":38,"az":84,"ss":33,"used":true},{"PRN":26,"el":32,"az":277,"ss":37,"used":true},{"PRN":29,"el":31,"az":269,"ss":34,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":28,"used":false},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021649.947,A,5029.3856,N,10441.0379,W,0.118754,16.61,280706,,*2D +{"class":"TPV","tag":"RMC","time":1154053009.947,"ept":0.005,"lat":50.489760000,"lon":-104.683965000,"alt":559.300,"epx":12.458,"epy":20.312,"epv":64.400,"track":16.6100,"speed":0.061,"climb":-0.700,"eps":40.62,"mode":3} +$GPGGA,021650.947,5029.3857,N,10441.0380,W,1,05,2.0,559.1,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3857,N,10441.0380,W,021650.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021650.947,A,5029.3857,N,10441.0380,W,0.122534,2.49,280706,,*10 +{"class":"TPV","tag":"RMC","time":1154053010.947,"ept":0.005,"lat":50.489761667,"lon":-104.683966667,"alt":559.100,"epx":12.462,"epy":20.352,"epv":67.836,"track":2.4900,"speed":0.063,"climb":-0.200,"eps":40.66,"mode":3} +$GPGGA,021651.947,5029.3856,N,10441.0382,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3856,N,10441.0382,W,021651.947,A*22 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021651.947,A,5029.3856,N,10441.0382,W,0.117097,1.44,280706,,*16 +{"class":"TPV","tag":"RMC","time":1154053011.947,"ept":0.005,"lat":50.489760000,"lon":-104.683970000,"alt":559.400,"epx":12.462,"epy":20.352,"epv":64.400,"track":1.4400,"speed":0.060,"climb":0.300,"eps":40.70,"mode":3} +$GPGGA,021652.947,5029.3856,N,10441.0383,W,1,05,2.0,559.6,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3856,N,10441.0383,W,021652.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021652.947,A,5029.3856,N,10441.0383,W,0.110183,9.39,280706,,*15 +{"class":"TPV","tag":"RMC","time":1154053012.947,"ept":0.005,"lat":50.489760000,"lon":-104.683971667,"alt":559.600,"epx":12.462,"epy":20.352,"epv":64.400,"track":9.3900,"speed":0.057,"climb":0.200,"eps":40.70,"mode":3} +$GPGGA,021653.947,5029.3855,N,10441.0382,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*43 +$GPGLL,5029.3855,N,10441.0382,W,021653.947,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021653.947,A,5029.3855,N,10441.0382,W,0.104481,9.00,280706,,*1E +{"class":"TPV","tag":"RMC","time":1154053013.947,"ept":0.005,"lat":50.489758333,"lon":-104.683970000,"alt":559.400,"epx":12.462,"epy":20.352,"epv":64.400,"track":9.0000,"speed":0.054,"climb":-0.200,"eps":40.70,"mode":3} +$GPGGA,021654.947,5029.3855,N,10441.0381,W,1,05,2.0,559.5,M,-20.3,M,0.0,0000*46 +$GPGLL,5029.3855,N,10441.0381,W,021654.947,A*27 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,34,28,82,39,36,11,38,84,33*49 +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,0*40 +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.36,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":34,"used":true},{"PRN":28,"el":82,"az":39,"ss":36,"used":true},{"PRN":11,"el":38,"az":84,"ss":33,"used":true},{"PRN":26,"el":32,"az":277,"ss":37,"used":true},{"PRN":29,"el":31,"az":269,"ss":34,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":0,"used":false},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021654.947,A,5029.3855,N,10441.0381,W,0.142516,3.80,280706,,*15 +{"class":"TPV","tag":"RMC","time":1154053014.947,"ept":0.005,"lat":50.489758333,"lon":-104.683968333,"alt":559.500,"epx":12.462,"epy":20.352,"epv":64.400,"track":3.8000,"speed":0.073,"climb":0.100,"eps":40.70,"mode":3} +$GPGGA,021655.947,5029.3855,N,10441.0381,W,1,05,2.0,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0381,W,021655.947,A*26 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021655.947,A,5029.3855,N,10441.0381,W,0.120701,358.47,280706,,*12 +{"class":"TPV","tag":"RMC","time":1154053015.947,"ept":0.005,"lat":50.489758333,"lon":-104.683968333,"alt":559.800,"epx":12.462,"epy":20.352,"epv":67.836,"track":358.4700,"speed":0.062,"climb":0.300,"eps":40.70,"mode":3} +$GPGGA,021656.947,5029.3855,N,10441.0379,W,1,06,1.4,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0379,W,021656.947,A*22 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021656.947,A,5029.3855,N,10441.0379,W,0.094143,14.12,280706,,*23 +{"class":"TPV","tag":"RMC","time":1154053016.947,"ept":0.005,"lat":50.489758333,"lon":-104.683965000,"alt":559.800,"epx":12.462,"epy":20.352,"epv":64.400,"track":14.1200,"speed":0.048,"climb":0.000,"eps":40.70,"mode":3} +$GPGGA,021657.947,5029.3855,N,10441.0378,W,1,06,1.4,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0378,W,021657.947,A*22 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021657.947,A,5029.3855,N,10441.0378,W,0.096695,9.89,280706,,*13 +{"class":"TPV","tag":"RMC","time":1154053017.947,"ept":0.005,"lat":50.489758333,"lon":-104.683963333,"alt":559.800,"epx":12.462,"epy":20.352,"epv":52.900,"track":9.8900,"speed":0.050,"climb":0.000,"eps":40.70,"mode":3} +$GPGGA,021658.947,5029.3855,N,10441.0378,W,1,05,2.0,560.0,M,-20.3,M,0.0,0000*43 +$GPGLL,5029.3855,N,10441.0378,W,021658.947,A*2D +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021658.947,A,5029.3855,N,10441.0378,W,0.111024,0.77,280706,,*16 +{"class":"TPV","tag":"RMC","time":1154053018.947,"ept":0.005,"lat":50.489758333,"lon":-104.683963333,"alt":560.000,"epx":12.462,"epy":20.352,"epv":52.900,"track":0.7700,"speed":0.057,"climb":0.200,"eps":40.70,"mode":3} +$GPGGA,021659.946,5029.3855,N,10441.0376,W,1,05,2.0,559.8,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3855,N,10441.0376,W,021659.946,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,33,28,82,39,36,11,38,84,32*4F +$GPGSV,3,2,9,26,32,277,36,29,31,269,34,19,6,48,0,27,22,152,27*74 +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.36,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":33,"used":true},{"PRN":28,"el":82,"az":39,"ss":36,"used":true},{"PRN":11,"el":38,"az":84,"ss":32,"used":true},{"PRN":26,"el":32,"az":277,"ss":36,"used":true},{"PRN":29,"el":31,"az":269,"ss":34,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":27,"used":false},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021659.946,A,5029.3855,N,10441.0376,W,0.144243,359.38,280706,,*1F +{"class":"TPV","tag":"RMC","time":1154053019.946,"ept":0.005,"lat":50.489758333,"lon":-104.683960000,"alt":559.800,"epx":12.462,"epy":20.352,"epv":64.400,"track":359.3800,"speed":0.074,"climb":-0.200,"eps":40.74,"mode":3} +$GPGGA,021700.946,5029.3856,N,10441.0373,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3856,N,10441.0373,W,021700.946,A*28 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021700.946,A,5029.3856,N,10441.0373,W,0.127513,359.47,280706,,*1B +{"class":"TPV","tag":"RMC","time":1154053020.946,"ept":0.005,"lat":50.489760000,"lon":-104.683955000,"alt":559.400,"epx":12.462,"epy":20.352,"epv":67.836,"track":359.4700,"speed":0.066,"climb":-0.400,"eps":40.70,"mode":3} +$GPGGA,021701.946,5029.3856,N,10441.0369,W,1,05,2.0,558.6,M,-20.3,M,0.0,0000*41 +$GPGLL,5029.3856,N,10441.0369,W,021701.946,A*22 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021701.946,A,5029.3856,N,10441.0369,W,0.082985,16.78,280706,,*28 +{"class":"TPV","tag":"RMC","time":1154053021.946,"ept":0.005,"lat":50.489760000,"lon":-104.683948333,"alt":558.600,"epx":12.462,"epy":20.352,"epv":64.400,"track":16.7800,"speed":0.043,"climb":-0.800,"eps":40.70,"mode":3} +$GPGGA,021702.946,5029.3856,N,10441.0365,W,1,05,2.0,557.8,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3856,N,10441.0365,W,021702.946,A*2D +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021702.946,A,5029.3856,N,10441.0365,W,0.108057,8.59,280706,,*1E +{"class":"TPV","tag":"RMC","time":1154053022.946,"ept":0.005,"lat":50.489760000,"lon":-104.683941667,"alt":557.800,"epx":12.462,"epy":20.352,"epv":64.400,"track":8.5900,"speed":0.056,"climb":-0.800,"eps":40.70,"mode":3} +$GPGGA,021703.946,5029.3857,N,10441.0363,W,1,05,2.0,556.8,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3857,N,10441.0363,W,021703.946,A*2B +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021703.946,A,5029.3857,N,10441.0363,W,0.193741,10.55,280706,,*2F +{"class":"TPV","tag":"RMC","time":1154053023.946,"ept":0.005,"lat":50.489761667,"lon":-104.683938333,"alt":556.800,"epx":12.462,"epy":20.352,"epv":64.400,"track":10.5500,"speed":0.100,"climb":-1.000,"eps":40.70,"mode":3} +$GPGGA,021704.946,5029.3858,N,10441.0363,W,1,07,1.3,556.0,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3858,N,10441.0363,W,021704.946,A*23 +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A +$GPGSV,3,1,9,8,48,156,31,17,50,212,32,28,82,39,39,11,38,84,33*72 +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,30*73 +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":1.27,"vdop":1.94,"tdop":1.22,"hdop":1.41,"gdop":2.69,"pdop":2.40,"satellites":[{"PRN":8,"el":48,"az":156,"ss":31,"used":true},{"PRN":17,"el":50,"az":212,"ss":32,"used":true},{"PRN":28,"el":82,"az":39,"ss":39,"used":true},{"PRN":11,"el":38,"az":84,"ss":33,"used":true},{"PRN":26,"el":32,"az":277,"ss":37,"used":true},{"PRN":29,"el":31,"az":269,"ss":34,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":30,"used":true},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021704.946,A,5029.3858,N,10441.0363,W,0.096613,335.19,280706,,*19 +{"class":"TPV","tag":"RMC","time":1154053024.946,"ept":0.005,"lat":50.489763333,"lon":-104.683938333,"alt":556.000,"epx":12.462,"epy":20.352,"epv":64.400,"track":335.1900,"speed":0.050,"climb":-0.800,"eps":40.70,"mode":3} +$GPGGA,021705.946,5029.3859,N,10441.0363,W,1,07,1.3,555.4,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3859,N,10441.0363,W,021705.946,A*23 +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A +$GPRMC,021705.946,A,5029.3859,N,10441.0363,W,0.061763,22.98,280706,,*2B +{"class":"TPV","tag":"RMC","time":1154053025.946,"ept":0.005,"lat":50.489765000,"lon":-104.683938333,"alt":555.400,"epx":9.353,"epy":18.976,"epv":44.702,"track":22.9800,"speed":0.032,"climb":-0.600,"eps":39.33,"mode":3} +$GPGGA,021706.946,5029.3860,N,10441.0364,W,1,07,1.3,554.9,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3860,N,10441.0364,W,021706.946,A*2D +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A diff --git a/test/daemon/gpslim236.log b/test/daemon/gpslim236.log new file mode 100644 index 0000000..d237580 --- /dev/null +++ b/test/daemon/gpslim236.log @@ -0,0 +1,176 @@ +# Name: Holux GPSlim 236 +# Chipset: SiRF-III +# Submitted-by: "Kévin REDON" +# Date: 22 Jul 2006 +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGGA,185244.000,4854.2575,N,00219.9816,E,1,05,1.7,124.4,M,47.3,M,,0000*56 +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,20,05,54,079,16,06,43,204,29,14,39,247,41*75 +$GPGSV,3,2,11,01,31,303,31,02,28,077,20,25,17,309,,09,17,138,25*7A +$GPGSV,3,3,11,04,14,040,,24,02,020,,20,00,342,*4D +$GPRMC,185244.000,A,4854.2575,N,00219.9816,E,0.00,296.61,210706,,,A*6C +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185245.000,4854.2575,N,00219.9815,E,1,05,1.7,124.1,M,47.3,M,,0000*51 +$GPRMC,185245.000,A,4854.2575,N,00219.9815,E,0.00,296.61,210706,,,A*6E +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185246.000,4854.2575,N,00219.9814,E,1,05,1.7,124.0,M,47.3,M,,0000*52 +$GPRMC,185246.000,A,4854.2575,N,00219.9814,E,0.00,296.61,210706,,,A*6C +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185247.000,4854.2575,N,00219.9814,E,1,05,1.7,124.3,M,47.3,M,,0000*50 +$GPRMC,185247.000,A,4854.2575,N,00219.9814,E,0.00,296.61,210706,,,A*6D +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185248.000,4854.2574,N,00219.9812,E,1,05,1.7,123.6,M,47.3,M,,0000*5A +$GPRMC,185248.000,A,4854.2574,N,00219.9812,E,0.00,296.61,210706,,,A*65 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185249.000,4854.2572,N,00219.9810,E,1,05,1.7,123.0,M,47.3,M,,0000*59 +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,22,05,54,079,16,06,43,204,28,14,39,247,41*76 +$GPGSV,3,2,11,01,31,303,31,02,28,077,21,25,17,309,07,09,17,138,25*7C +$GPGSV,3,3,11,04,14,040,15,24,02,020,17,20,00,342,13*4D +$GPRMC,185249.000,A,4854.2572,N,00219.9810,E,0.00,296.61,210706,,,A*60 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185250.000,4854.2571,N,00219.9807,E,1,05,1.7,122.0,M,47.3,M,,0000*55 +$GPRMC,185250.000,A,4854.2571,N,00219.9807,E,0.00,296.61,210706,,,A*6D +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185251.000,4854.2570,N,00219.9806,E,1,05,1.7,121.8,M,47.3,M,,0000*5F +$GPRMC,185251.000,A,4854.2570,N,00219.9806,E,0.00,296.61,210706,,,A*6C +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185252.000,4854.2569,N,00219.9804,E,1,05,1.7,121.2,M,47.3,M,,0000*5C +$GPRMC,185252.000,A,4854.2569,N,00219.9804,E,0.00,296.61,210706,,,A*65 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185253.000,4854.2569,N,00219.9803,E,1,05,1.7,121.1,M,47.3,M,,0000*59 +$GPRMC,185253.000,A,4854.2569,N,00219.9803,E,0.00,296.61,210706,,,A*63 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185254.000,4854.2565,N,00219.9796,E,1,05,1.7,118.1,M,47.3,M,,0000*5B +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,23,05,54,079,17,06,43,204,28,14,39,247,40*77 +$GPGSV,3,2,11,01,31,303,31,02,28,077,20,25,17,309,11,09,17,138,25*7A +$GPGSV,3,3,11,04,14,040,08,24,02,020,11,20,00,342,*45 +$GPRMC,185254.000,A,4854.2565,N,00219.9796,E,0.00,296.61,210706,,,A*6B +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185255.000,4854.2562,N,00219.9788,E,1,05,1.7,115.0,M,47.3,M,,0000*5E +$GPRMC,185255.000,A,4854.2562,N,00219.9788,E,0.00,296.61,210706,,,A*62 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185256.000,4854.2559,N,00219.9783,E,1,05,1.7,113.0,M,47.3,M,,0000*58 +$GPRMC,185256.000,A,4854.2559,N,00219.9783,E,0.00,296.61,210706,,,A*62 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185257.000,4854.2556,N,00219.9777,E,1,05,1.7,110.4,M,47.3,M,,0000*5A +$GPRMC,185257.000,A,4854.2556,N,00219.9777,E,0.00,296.61,210706,,,A*67 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185258.000,4854.2554,N,00219.9772,E,1,05,1.7,108.4,M,47.3,M,,0000*5B +$GPRMC,185258.000,A,4854.2554,N,00219.9772,E,0.00,296.61,210706,,,A*6F +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185259.000,4854.2550,N,00219.9764,E,1,05,1.7,105.3,M,47.3,M,,0000*53 +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,24,05,54,079,17,06,43,204,29,14,39,247,40*71 +$GPGSV,3,2,11,01,31,303,31,02,28,077,13,25,17,309,10,09,17,138,25*7B +$GPGSV,3,3,11,04,14,040,10,24,02,020,18,20,00,342,09*4C +$GPRMC,185259.000,A,4854.2550,N,00219.9764,E,0.00,296.61,210706,,,A*6D +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185300.000,4854.2547,N,00219.9759,E,1,05,1.7,103.6,M,47.3,M,,0000*55 +$GPRMC,185300.000,A,4854.2547,N,00219.9759,E,0.00,296.61,210706,,,A*68 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185301.000,4854.2545,N,00219.9754,E,1,05,1.7,101.5,M,47.3,M,,0000*5A +$GPRMC,185301.000,A,4854.2545,N,00219.9754,E,0.00,296.61,210706,,,A*66 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185302.000,4854.2543,N,00219.9751,E,1,05,1.7,100.1,M,47.3,M,,0000*5F +$GPRMC,185302.000,A,4854.2543,N,00219.9751,E,0.00,296.61,210706,,,A*66 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185303.000,4854.2543,N,00219.9750,E,1,05,1.7,99.5,M,47.3,M,,0000*6A +$GPRMC,185303.000,A,4854.2543,N,00219.9750,E,0.00,296.61,210706,,,A*66 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185304.000,4854.2543,N,00219.9749,E,1,05,1.7,99.3,M,47.3,M,,0000*63 +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,24,05,54,079,18,06,43,204,31,14,39,247,40*77 +$GPGSV,3,2,11,01,31,303,31,02,28,077,11,25,17,309,13,09,17,138,24*7B +$GPGSV,3,3,11,04,14,040,10,24,02,020,07,20,00,342,12*48 +$GPRMC,185304.000,A,4854.2543,N,00219.9749,E,0.00,296.61,210706,,,A*69 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185305.000,4854.2542,N,00219.9749,E,1,05,1.7,99.0,M,47.3,M,,0000*60 +$GPRMC,185305.000,A,4854.2542,N,00219.9749,E,0.00,296.61,210706,,,A*69 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185306.000,4854.2543,N,00219.9751,E,1,05,1.7,99.2,M,47.3,M,,0000*69 +$GPRMC,185306.000,A,4854.2543,N,00219.9751,E,0.00,296.61,210706,,,A*62 +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185307.000,4854.2542,N,00219.9749,E,1,05,1.7,98.8,M,47.3,M,,0000*6B +$GPRMC,185307.000,A,4854.2542,N,00219.9749,E,0.00,296.61,210706,,,A*6B +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185308.000,4854.2542,N,00219.9746,E,1,05,1.7,98.8,M,47.3,M,,0000*6B +$GPRMC,185308.000,A,4854.2542,N,00219.9746,E,1.05,277.83,210706,,,A*6C +$GPVTG,277.83,T,,M,1.05,N,1.9,K,A*08 +$GPGGA,185309.000,4854.2542,N,00219.9744,E,1,05,1.7,98.4,M,47.3,M,,0000*64 +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,23,05,54,079,18,06,43,204,32,14,39,247,40*73 +$GPGSV,3,2,11,01,31,303,31,02,28,077,15,25,17,309,11,09,17,138,24*7D +$GPGSV,3,3,11,04,14,040,,24,02,020,,20,00,342,11*4D +$GPRMC,185309.000,A,4854.2542,N,00219.9744,E,0.00,277.83,210706,,,A*6B +$GPVTG,277.83,T,,M,0.00,N,0.0,K,A*04 +$GPGGA,185310.000,4854.2540,N,00219.9743,E,1,05,1.7,97.3,M,47.3,M,,0000*61 +$GPRMC,185310.000,A,4854.2540,N,00219.9743,E,0.00,277.83,210706,,,A*66 +$GPVTG,277.83,T,,M,0.00,N,0.0,K,A*04 +$GPGGA,185311.000,4854.2541,N,00219.9746,E,1,05,1.7,97.3,M,47.3,M,,0000*64 +$GPRMC,185311.000,A,4854.2541,N,00219.9746,E,0.00,277.83,210706,,,A*63 +$GPVTG,277.83,T,,M,0.00,N,0.0,K,A*04 +$GPGGA,185312.000,4854.2542,N,00219.9750,E,1,05,1.7,97.9,M,47.3,M,,0000*69 +$GPRMC,185312.000,A,4854.2542,N,00219.9750,E,0.00,277.83,210706,,,A*64 +$GPVTG,277.83,T,,M,0.00,N,0.0,K,A*04 +$GPGGA,185313.000,4854.2542,N,00219.9753,E,1,05,1.7,98.4,M,47.3,M,,0000*69 +$GPRMC,185313.000,A,4854.2542,N,00219.9753,E,0.00,277.83,210706,,,A*66 +$GPVTG,277.83,T,,M,0.00,N,0.0,K,A*04 +$GPGGA,185314.000,4854.2542,N,00219.9750,E,1,05,1.7,98.5,M,47.3,M,,0000*6C +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,22,05,54,079,19,06,43,204,33,14,39,247,40*72 +$GPGSV,3,2,11,01,31,303,30,02,28,077,,25,17,309,08,09,17,138,23*77 +$GPGSV,3,3,11,04,14,040,14,24,02,020,09,20,00,342,08*49 +$GPRMC,185314.000,A,4854.2542,N,00219.9750,E,1.06,270.56,210706,,,A*6A +$GPVTG,270.56,T,,M,1.06,N,2.0,K,A*0E +$GPGGA,185315.000,4854.2543,N,00219.9748,E,1,05,1.7,99.0,M,47.3,M,,0000*61 +$GPRMC,185315.000,A,4854.2543,N,00219.9748,E,0.00,270.56,210706,,,A*64 +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185316.000,4854.2544,N,00219.9751,E,1,05,1.7,99.1,M,47.3,M,,0000*6C +$GPRMC,185316.000,A,4854.2544,N,00219.9751,E,0.00,270.56,210706,,,A*68 +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185317.000,4854.2546,N,00219.9759,E,1,05,1.7,100.3,M,47.3,M,,0000*54 +$GPRMC,185317.000,A,4854.2546,N,00219.9759,E,0.00,270.56,210706,,,A*63 +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185318.000,4854.2547,N,00219.9762,E,1,05,1.7,101.1,M,47.3,M,,0000*51 +$GPRMC,185318.000,A,4854.2547,N,00219.9762,E,0.00,270.56,210706,,,A*65 +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185319.000,4854.2546,N,00219.9758,E,1,05,1.7,100.3,M,47.3,M,,0000*5B +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.7,1.7,2.2*39 +$GPGSV,3,1,11,30,79,308,21,05,54,079,19,06,43,204,34,14,39,247,40*76 +$GPGSV,3,2,11,01,31,303,30,02,28,077,,25,17,309,14,09,17,138,23*7A +$GPGSV,3,3,11,04,14,040,10,24,02,020,09,20,00,342,12*46 +$GPRMC,185319.000,A,4854.2546,N,00219.9758,E,0.00,270.56,210706,,,A*6C +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185320.000,4854.2545,N,00219.9757,E,1,05,1.7,99.8,M,47.3,M,,0000*67 +$GPRMC,185320.000,A,4854.2545,N,00219.9757,E,0.00,270.56,210706,,,A*6A +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185321.000,4854.2544,N,00219.9753,E,1,05,1.7,99.1,M,47.3,M,,0000*6A +$GPRMC,185321.000,A,4854.2544,N,00219.9753,E,1.28,261.85,210706,,,A*6B +$GPVTG,261.85,T,,M,1.28,N,2.4,K,A*08 +$GPGGA,185322.000,4854.2544,N,00219.9752,E,1,05,1.7,99.4,M,47.3,M,,0000*6D +$GPRMC,185322.000,A,4854.2544,N,00219.9752,E,0.00,261.85,210706,,,A*62 +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 +$GPGGA,185323.000,4854.2544,N,00219.9753,E,1,05,1.7,99.5,M,47.3,M,,0000*6C +$GPRMC,185323.000,A,4854.2544,N,00219.9753,E,0.00,261.85,210706,,,A*62 +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 +$GPGGA,185324.000,4854.2545,N,00219.9754,E,1,05,1.7,99.5,M,47.3,M,,0000*6D +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.7,1.7,2.2*39 +$GPGSV,3,1,11,30,79,308,20,05,54,079,18,06,43,204,35,14,39,247,40*77 +$GPGSV,3,2,11,01,31,303,30,02,28,077,,25,17,309,11,09,17,138,22*7E +$GPGSV,3,3,11,04,14,040,,24,02,020,08,20,00,342,08*4D +$GPRMC,185324.000,A,4854.2545,N,00219.9754,E,0.00,261.85,210706,,,A*63 +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 +$GPGGA,185325.000,4854.2546,N,00219.9759,E,1,05,1.7,99.9,M,47.3,M,,0000*6E +$GPRMC,185325.000,A,4854.2546,N,00219.9759,E,0.00,261.85,210706,,,A*6C +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 +$GPGGA,185326.000,4854.2547,N,00219.9763,E,1,05,1.7,99.7,M,47.3,M,,0000*6B +$GPRMC,185326.000,A,4854.2547,N,00219.9763,E,0.00,261.85,210706,,,A*67 +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 +$GPGGA,185327.000,4854.2546,N,00219.9764,E,1,05,1.7,98.5,M,47.3,M,,0000*6F +$GPRMC,185327.000,A,4854.2546,N,00219.9764,E,0.00,261.85,210706,,,A*60 +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 diff --git a/test/daemon/gpslim236.log.chk b/test/daemon/gpslim236.log.chk new file mode 100644 index 0000000..eee9859 --- /dev/null +++ b/test/daemon/gpslim236.log.chk @@ -0,0 +1,223 @@ +$GPGGA,185244.000,4854.2575,N,00219.9816,E,1,05,1.7,124.4,M,47.3,M,,0000*56 +{"class":"TPV","tag":"GGA","lat":48.904291667,"lon":2.333026667,"alt":124.400,"mode":3} +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +{"class":"TPV","tag":"GSA","lat":48.904291667,"lon":2.333026667,"alt":124.400,"epv":50.600,"mode":3} +$GPGSV,3,1,11,30,79,308,20,05,54,079,16,06,43,204,29,14,39,247,41*75 +$GPGSV,3,2,11,01,31,303,31,02,28,077,20,25,17,309,,09,17,138,25*7A +$GPGSV,3,3,11,04,14,040,,24,02,020,,20,00,342,*4D +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":1.14,"vdop":3.61,"tdop":2.85,"hdop":1.67,"gdop":4.89,"pdop":3.97,"satellites":[{"PRN":30,"el":79,"az":308,"ss":20,"used":true},{"PRN":5,"el":54,"az":79,"ss":16,"used":false},{"PRN":6,"el":43,"az":204,"ss":29,"used":true},{"PRN":14,"el":39,"az":247,"ss":41,"used":true},{"PRN":1,"el":31,"az":303,"ss":31,"used":true},{"PRN":2,"el":28,"az":77,"ss":20,"used":false},{"PRN":25,"el":17,"az":309,"ss":0,"used":false},{"PRN":9,"el":17,"az":138,"ss":25,"used":true},{"PRN":4,"el":14,"az":40,"ss":0,"used":false},{"PRN":24,"el":2,"az":20,"ss":0,"used":false},{"PRN":20,"el":0,"az":342,"ss":0,"used":false}]} +$GPRMC,185244.000,A,4854.2575,N,00219.9816,E,0.00,296.61,210706,,,A*6C +{"class":"TPV","tag":"RMC","time":1153507964.000,"ept":0.005,"lat":48.904291667,"lon":2.333026667,"alt":124.400,"epx":18.222,"epy":17.174,"epv":50.600,"track":296.6100,"speed":0.000,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185245.000,4854.2575,N,00219.9815,E,1,05,1.7,124.1,M,47.3,M,,0000*51 +$GPRMC,185245.000,A,4854.2575,N,00219.9815,E,0.00,296.61,210706,,,A*6E +{"class":"TPV","tag":"RMC","time":1153507965.000,"ept":0.005,"lat":48.904291667,"lon":2.333025000,"alt":124.100,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.300,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185246.000,4854.2575,N,00219.9814,E,1,05,1.7,124.0,M,47.3,M,,0000*52 +$GPRMC,185246.000,A,4854.2575,N,00219.9814,E,0.00,296.61,210706,,,A*6C +{"class":"TPV","tag":"RMC","time":1153507966.000,"ept":0.005,"lat":48.904291667,"lon":2.333023333,"alt":124.000,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.100,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185247.000,4854.2575,N,00219.9814,E,1,05,1.7,124.3,M,47.3,M,,0000*50 +$GPRMC,185247.000,A,4854.2575,N,00219.9814,E,0.00,296.61,210706,,,A*6D +{"class":"TPV","tag":"RMC","time":1153507967.000,"ept":0.005,"lat":48.904291667,"lon":2.333023333,"alt":124.300,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":0.300,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185248.000,4854.2574,N,00219.9812,E,1,05,1.7,123.6,M,47.3,M,,0000*5A +$GPRMC,185248.000,A,4854.2574,N,00219.9812,E,0.00,296.61,210706,,,A*65 +{"class":"TPV","tag":"RMC","time":1153507968.000,"ept":0.005,"lat":48.904290000,"lon":2.333020000,"alt":123.600,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.700,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185249.000,4854.2572,N,00219.9810,E,1,05,1.7,123.0,M,47.3,M,,0000*59 +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,22,05,54,079,16,06,43,204,28,14,39,247,41*76 +$GPGSV,3,2,11,01,31,303,31,02,28,077,21,25,17,309,07,09,17,138,25*7C +$GPGSV,3,3,11,04,14,040,15,24,02,020,17,20,00,342,13*4D +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":1.14,"vdop":3.61,"tdop":2.85,"hdop":1.67,"gdop":4.89,"pdop":3.97,"satellites":[{"PRN":30,"el":79,"az":308,"ss":22,"used":true},{"PRN":5,"el":54,"az":79,"ss":16,"used":false},{"PRN":6,"el":43,"az":204,"ss":28,"used":true},{"PRN":14,"el":39,"az":247,"ss":41,"used":true},{"PRN":1,"el":31,"az":303,"ss":31,"used":true},{"PRN":2,"el":28,"az":77,"ss":21,"used":false},{"PRN":25,"el":17,"az":309,"ss":7,"used":false},{"PRN":9,"el":17,"az":138,"ss":25,"used":true},{"PRN":4,"el":14,"az":40,"ss":15,"used":false},{"PRN":24,"el":2,"az":20,"ss":17,"used":false},{"PRN":20,"el":0,"az":342,"ss":13,"used":false}]} +$GPRMC,185249.000,A,4854.2572,N,00219.9810,E,0.00,296.61,210706,,,A*60 +{"class":"TPV","tag":"RMC","time":1153507969.000,"ept":0.005,"lat":48.904286667,"lon":2.333016667,"alt":123.000,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.600,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185250.000,4854.2571,N,00219.9807,E,1,05,1.7,122.0,M,47.3,M,,0000*55 +$GPRMC,185250.000,A,4854.2571,N,00219.9807,E,0.00,296.61,210706,,,A*6D +{"class":"TPV","tag":"RMC","time":1153507970.000,"ept":0.005,"lat":48.904285000,"lon":2.333011667,"alt":122.000,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-1.000,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185251.000,4854.2570,N,00219.9806,E,1,05,1.7,121.8,M,47.3,M,,0000*5F +$GPRMC,185251.000,A,4854.2570,N,00219.9806,E,0.00,296.61,210706,,,A*6C +{"class":"TPV","tag":"RMC","time":1153507971.000,"ept":0.005,"lat":48.904283333,"lon":2.333010000,"alt":121.800,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.200,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185252.000,4854.2569,N,00219.9804,E,1,05,1.7,121.2,M,47.3,M,,0000*5C +$GPRMC,185252.000,A,4854.2569,N,00219.9804,E,0.00,296.61,210706,,,A*65 +{"class":"TPV","tag":"RMC","time":1153507972.000,"ept":0.005,"lat":48.904281667,"lon":2.333006667,"alt":121.200,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.600,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185253.000,4854.2569,N,00219.9803,E,1,05,1.7,121.1,M,47.3,M,,0000*59 +$GPRMC,185253.000,A,4854.2569,N,00219.9803,E,0.00,296.61,210706,,,A*63 +{"class":"TPV","tag":"RMC","time":1153507973.000,"ept":0.005,"lat":48.904281667,"lon":2.333005000,"alt":121.100,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.100,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185254.000,4854.2565,N,00219.9796,E,1,05,1.7,118.1,M,47.3,M,,0000*5B +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,23,05,54,079,17,06,43,204,28,14,39,247,40*77 +$GPGSV,3,2,11,01,31,303,31,02,28,077,20,25,17,309,11,09,17,138,25*7A +$GPGSV,3,3,11,04,14,040,08,24,02,020,11,20,00,342,*45 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":1.14,"vdop":3.61,"tdop":2.85,"hdop":1.67,"gdop":4.89,"pdop":3.97,"satellites":[{"PRN":30,"el":79,"az":308,"ss":23,"used":true},{"PRN":5,"el":54,"az":79,"ss":17,"used":false},{"PRN":6,"el":43,"az":204,"ss":28,"used":true},{"PRN":14,"el":39,"az":247,"ss":40,"used":true},{"PRN":1,"el":31,"az":303,"ss":31,"used":true},{"PRN":2,"el":28,"az":77,"ss":20,"used":false},{"PRN":25,"el":17,"az":309,"ss":11,"used":false},{"PRN":9,"el":17,"az":138,"ss":25,"used":true},{"PRN":4,"el":14,"az":40,"ss":8,"used":false},{"PRN":24,"el":2,"az":20,"ss":11,"used":false},{"PRN":20,"el":0,"az":342,"ss":0,"used":false}]} +$GPRMC,185254.000,A,4854.2565,N,00219.9796,E,0.00,296.61,210706,,,A*6B +{"class":"TPV","tag":"RMC","time":1153507974.000,"ept":0.005,"lat":48.904275000,"lon":2.332993333,"alt":118.100,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-3.000,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185255.000,4854.2562,N,00219.9788,E,1,05,1.7,115.0,M,47.3,M,,0000*5E +$GPRMC,185255.000,A,4854.2562,N,00219.9788,E,0.00,296.61,210706,,,A*62 +{"class":"TPV","tag":"RMC","time":1153507975.000,"ept":0.005,"lat":48.904270000,"lon":2.332980000,"alt":115.000,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-3.100,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185256.000,4854.2559,N,00219.9783,E,1,05,1.7,113.0,M,47.3,M,,0000*58 +$GPRMC,185256.000,A,4854.2559,N,00219.9783,E,0.00,296.61,210706,,,A*62 +{"class":"TPV","tag":"RMC","time":1153507976.000,"ept":0.005,"lat":48.904265000,"lon":2.332971667,"alt":113.000,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-2.000,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185257.000,4854.2556,N,00219.9777,E,1,05,1.7,110.4,M,47.3,M,,0000*5A +$GPRMC,185257.000,A,4854.2556,N,00219.9777,E,0.00,296.61,210706,,,A*67 +{"class":"TPV","tag":"RMC","time":1153507977.000,"ept":0.005,"lat":48.904260000,"lon":2.332961667,"alt":110.400,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-2.600,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185258.000,4854.2554,N,00219.9772,E,1,05,1.7,108.4,M,47.3,M,,0000*5B +$GPRMC,185258.000,A,4854.2554,N,00219.9772,E,0.00,296.61,210706,,,A*6F +{"class":"TPV","tag":"RMC","time":1153507978.000,"ept":0.005,"lat":48.904256667,"lon":2.332953333,"alt":108.400,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-2.000,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185259.000,4854.2550,N,00219.9764,E,1,05,1.7,105.3,M,47.3,M,,0000*53 +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,24,05,54,079,17,06,43,204,29,14,39,247,40*71 +$GPGSV,3,2,11,01,31,303,31,02,28,077,13,25,17,309,10,09,17,138,25*7B +$GPGSV,3,3,11,04,14,040,10,24,02,020,18,20,00,342,09*4C +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":1.14,"vdop":3.61,"tdop":2.85,"hdop":1.67,"gdop":4.89,"pdop":3.97,"satellites":[{"PRN":30,"el":79,"az":308,"ss":24,"used":true},{"PRN":5,"el":54,"az":79,"ss":17,"used":false},{"PRN":6,"el":43,"az":204,"ss":29,"used":true},{"PRN":14,"el":39,"az":247,"ss":40,"used":true},{"PRN":1,"el":31,"az":303,"ss":31,"used":true},{"PRN":2,"el":28,"az":77,"ss":13,"used":false},{"PRN":25,"el":17,"az":309,"ss":10,"used":false},{"PRN":9,"el":17,"az":138,"ss":25,"used":true},{"PRN":4,"el":14,"az":40,"ss":10,"used":false},{"PRN":24,"el":2,"az":20,"ss":18,"used":false},{"PRN":20,"el":0,"az":342,"ss":9,"used":false}]} +$GPRMC,185259.000,A,4854.2550,N,00219.9764,E,0.00,296.61,210706,,,A*6D +{"class":"TPV","tag":"RMC","time":1153507979.000,"ept":0.005,"lat":48.904250000,"lon":2.332940000,"alt":105.300,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-3.100,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185300.000,4854.2547,N,00219.9759,E,1,05,1.7,103.6,M,47.3,M,,0000*55 +$GPRMC,185300.000,A,4854.2547,N,00219.9759,E,0.00,296.61,210706,,,A*68 +{"class":"TPV","tag":"RMC","time":1153507980.000,"ept":0.005,"lat":48.904245000,"lon":2.332931667,"alt":103.600,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-1.700,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185301.000,4854.2545,N,00219.9754,E,1,05,1.7,101.5,M,47.3,M,,0000*5A +$GPRMC,185301.000,A,4854.2545,N,00219.9754,E,0.00,296.61,210706,,,A*66 +{"class":"TPV","tag":"RMC","time":1153507981.000,"ept":0.005,"lat":48.904241667,"lon":2.332923333,"alt":101.500,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-2.100,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185302.000,4854.2543,N,00219.9751,E,1,05,1.7,100.1,M,47.3,M,,0000*5F +$GPRMC,185302.000,A,4854.2543,N,00219.9751,E,0.00,296.61,210706,,,A*66 +{"class":"TPV","tag":"RMC","time":1153507982.000,"ept":0.005,"lat":48.904238333,"lon":2.332918333,"alt":100.100,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-1.400,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185303.000,4854.2543,N,00219.9750,E,1,05,1.7,99.5,M,47.3,M,,0000*6A +$GPRMC,185303.000,A,4854.2543,N,00219.9750,E,0.00,296.61,210706,,,A*66 +{"class":"TPV","tag":"RMC","time":1153507983.000,"ept":0.005,"lat":48.904238333,"lon":2.332916667,"alt":99.500,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.600,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185304.000,4854.2543,N,00219.9749,E,1,05,1.7,99.3,M,47.3,M,,0000*63 +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,24,05,54,079,18,06,43,204,31,14,39,247,40*77 +$GPGSV,3,2,11,01,31,303,31,02,28,077,11,25,17,309,13,09,17,138,24*7B +$GPGSV,3,3,11,04,14,040,10,24,02,020,07,20,00,342,12*48 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":1.14,"vdop":3.61,"tdop":2.85,"hdop":1.67,"gdop":4.89,"pdop":3.97,"satellites":[{"PRN":30,"el":79,"az":308,"ss":24,"used":true},{"PRN":5,"el":54,"az":79,"ss":18,"used":false},{"PRN":6,"el":43,"az":204,"ss":31,"used":true},{"PRN":14,"el":39,"az":247,"ss":40,"used":true},{"PRN":1,"el":31,"az":303,"ss":31,"used":true},{"PRN":2,"el":28,"az":77,"ss":11,"used":false},{"PRN":25,"el":17,"az":309,"ss":13,"used":false},{"PRN":9,"el":17,"az":138,"ss":24,"used":true},{"PRN":4,"el":14,"az":40,"ss":10,"used":false},{"PRN":24,"el":2,"az":20,"ss":7,"used":false},{"PRN":20,"el":0,"az":342,"ss":12,"used":false}]} +$GPRMC,185304.000,A,4854.2543,N,00219.9749,E,0.00,296.61,210706,,,A*69 +{"class":"TPV","tag":"RMC","time":1153507984.000,"ept":0.005,"lat":48.904238333,"lon":2.332915000,"alt":99.300,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.200,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185305.000,4854.2542,N,00219.9749,E,1,05,1.7,99.0,M,47.3,M,,0000*60 +$GPRMC,185305.000,A,4854.2542,N,00219.9749,E,0.00,296.61,210706,,,A*69 +{"class":"TPV","tag":"RMC","time":1153507985.000,"ept":0.005,"lat":48.904236667,"lon":2.332915000,"alt":99.000,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.300,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185306.000,4854.2543,N,00219.9751,E,1,05,1.7,99.2,M,47.3,M,,0000*69 +$GPRMC,185306.000,A,4854.2543,N,00219.9751,E,0.00,296.61,210706,,,A*62 +{"class":"TPV","tag":"RMC","time":1153507986.000,"ept":0.005,"lat":48.904238333,"lon":2.332918333,"alt":99.200,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":0.200,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185307.000,4854.2542,N,00219.9749,E,1,05,1.7,98.8,M,47.3,M,,0000*6B +$GPRMC,185307.000,A,4854.2542,N,00219.9749,E,0.00,296.61,210706,,,A*6B +{"class":"TPV","tag":"RMC","time":1153507987.000,"ept":0.005,"lat":48.904236667,"lon":2.332915000,"alt":98.800,"epx":18.222,"epy":17.174,"epv":82.942,"track":296.6100,"speed":0.000,"climb":-0.400,"eps":36.44,"mode":3} +$GPVTG,296.61,T,,M,0.00,N,0.0,K,A*07 +$GPGGA,185308.000,4854.2542,N,00219.9746,E,1,05,1.7,98.8,M,47.3,M,,0000*6B +$GPRMC,185308.000,A,4854.2542,N,00219.9746,E,1.05,277.83,210706,,,A*6C +{"class":"TPV","tag":"RMC","time":1153507988.000,"ept":0.005,"lat":48.904236667,"lon":2.332910000,"alt":98.800,"epx":18.222,"epy":17.174,"epv":82.942,"track":277.8300,"speed":0.540,"climb":0.000,"eps":36.44,"mode":3} +$GPVTG,277.83,T,,M,1.05,N,1.9,K,A*08 +$GPGGA,185309.000,4854.2542,N,00219.9744,E,1,05,1.7,98.4,M,47.3,M,,0000*64 +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,23,05,54,079,18,06,43,204,32,14,39,247,40*73 +$GPGSV,3,2,11,01,31,303,31,02,28,077,15,25,17,309,11,09,17,138,24*7D +$GPGSV,3,3,11,04,14,040,,24,02,020,,20,00,342,11*4D +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":1.14,"vdop":3.61,"tdop":2.85,"hdop":1.67,"gdop":4.89,"pdop":3.97,"satellites":[{"PRN":30,"el":79,"az":308,"ss":23,"used":true},{"PRN":5,"el":54,"az":79,"ss":18,"used":false},{"PRN":6,"el":43,"az":204,"ss":32,"used":true},{"PRN":14,"el":39,"az":247,"ss":40,"used":true},{"PRN":1,"el":31,"az":303,"ss":31,"used":true},{"PRN":2,"el":28,"az":77,"ss":15,"used":false},{"PRN":25,"el":17,"az":309,"ss":11,"used":false},{"PRN":9,"el":17,"az":138,"ss":24,"used":true},{"PRN":4,"el":14,"az":40,"ss":0,"used":false},{"PRN":24,"el":2,"az":20,"ss":0,"used":false},{"PRN":20,"el":0,"az":342,"ss":11,"used":false}]} +$GPRMC,185309.000,A,4854.2542,N,00219.9744,E,0.00,277.83,210706,,,A*6B +{"class":"TPV","tag":"RMC","time":1153507989.000,"ept":0.005,"lat":48.904236667,"lon":2.332906667,"alt":98.400,"epx":18.222,"epy":17.174,"epv":82.942,"track":277.8300,"speed":0.000,"climb":-0.400,"eps":36.44,"mode":3} +$GPVTG,277.83,T,,M,0.00,N,0.0,K,A*04 +$GPGGA,185310.000,4854.2540,N,00219.9743,E,1,05,1.7,97.3,M,47.3,M,,0000*61 +$GPRMC,185310.000,A,4854.2540,N,00219.9743,E,0.00,277.83,210706,,,A*66 +{"class":"TPV","tag":"RMC","time":1153507990.000,"ept":0.005,"lat":48.904233333,"lon":2.332905000,"alt":97.300,"epx":18.222,"epy":17.174,"epv":82.942,"track":277.8300,"speed":0.000,"climb":-1.100,"eps":36.44,"mode":3} +$GPVTG,277.83,T,,M,0.00,N,0.0,K,A*04 +$GPGGA,185311.000,4854.2541,N,00219.9746,E,1,05,1.7,97.3,M,47.3,M,,0000*64 +$GPRMC,185311.000,A,4854.2541,N,00219.9746,E,0.00,277.83,210706,,,A*63 +{"class":"TPV","tag":"RMC","time":1153507991.000,"ept":0.005,"lat":48.904235000,"lon":2.332910000,"alt":97.300,"epx":18.222,"epy":17.174,"epv":82.942,"track":277.8300,"speed":0.000,"climb":0.000,"eps":36.44,"mode":3} +$GPVTG,277.83,T,,M,0.00,N,0.0,K,A*04 +$GPGGA,185312.000,4854.2542,N,00219.9750,E,1,05,1.7,97.9,M,47.3,M,,0000*69 +$GPRMC,185312.000,A,4854.2542,N,00219.9750,E,0.00,277.83,210706,,,A*64 +{"class":"TPV","tag":"RMC","time":1153507992.000,"ept":0.005,"lat":48.904236667,"lon":2.332916667,"alt":97.900,"epx":18.222,"epy":17.174,"epv":82.942,"track":277.8300,"speed":0.000,"climb":0.600,"eps":36.44,"mode":3} +$GPVTG,277.83,T,,M,0.00,N,0.0,K,A*04 +$GPGGA,185313.000,4854.2542,N,00219.9753,E,1,05,1.7,98.4,M,47.3,M,,0000*69 +$GPRMC,185313.000,A,4854.2542,N,00219.9753,E,0.00,277.83,210706,,,A*66 +{"class":"TPV","tag":"RMC","time":1153507993.000,"ept":0.005,"lat":48.904236667,"lon":2.332921667,"alt":98.400,"epx":18.222,"epy":17.174,"epv":82.942,"track":277.8300,"speed":0.000,"climb":0.500,"eps":36.44,"mode":3} +$GPVTG,277.83,T,,M,0.00,N,0.0,K,A*04 +$GPGGA,185314.000,4854.2542,N,00219.9750,E,1,05,1.7,98.5,M,47.3,M,,0000*6C +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.8,1.7,2.2*36 +$GPGSV,3,1,11,30,79,308,22,05,54,079,19,06,43,204,33,14,39,247,40*72 +$GPGSV,3,2,11,01,31,303,30,02,28,077,,25,17,309,08,09,17,138,23*77 +$GPGSV,3,3,11,04,14,040,14,24,02,020,09,20,00,342,08*49 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":1.14,"vdop":3.61,"tdop":2.85,"hdop":1.67,"gdop":4.89,"pdop":3.97,"satellites":[{"PRN":30,"el":79,"az":308,"ss":22,"used":true},{"PRN":5,"el":54,"az":79,"ss":19,"used":false},{"PRN":6,"el":43,"az":204,"ss":33,"used":true},{"PRN":14,"el":39,"az":247,"ss":40,"used":true},{"PRN":1,"el":31,"az":303,"ss":30,"used":true},{"PRN":2,"el":28,"az":77,"ss":0,"used":false},{"PRN":25,"el":17,"az":309,"ss":8,"used":false},{"PRN":9,"el":17,"az":138,"ss":23,"used":true},{"PRN":4,"el":14,"az":40,"ss":14,"used":false},{"PRN":24,"el":2,"az":20,"ss":9,"used":false},{"PRN":20,"el":0,"az":342,"ss":8,"used":false}]} +$GPRMC,185314.000,A,4854.2542,N,00219.9750,E,1.06,270.56,210706,,,A*6A +{"class":"TPV","tag":"RMC","time":1153507994.000,"ept":0.005,"lat":48.904236667,"lon":2.332916667,"alt":98.500,"epx":18.222,"epy":17.174,"epv":82.942,"track":270.5600,"speed":0.545,"climb":0.100,"eps":36.44,"mode":3} +$GPVTG,270.56,T,,M,1.06,N,2.0,K,A*0E +$GPGGA,185315.000,4854.2543,N,00219.9748,E,1,05,1.7,99.0,M,47.3,M,,0000*61 +$GPRMC,185315.000,A,4854.2543,N,00219.9748,E,0.00,270.56,210706,,,A*64 +{"class":"TPV","tag":"RMC","time":1153507995.000,"ept":0.005,"lat":48.904238333,"lon":2.332913333,"alt":99.000,"epx":18.222,"epy":17.174,"epv":82.942,"track":270.5600,"speed":0.000,"climb":0.500,"eps":36.44,"mode":3} +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185316.000,4854.2544,N,00219.9751,E,1,05,1.7,99.1,M,47.3,M,,0000*6C +$GPRMC,185316.000,A,4854.2544,N,00219.9751,E,0.00,270.56,210706,,,A*68 +{"class":"TPV","tag":"RMC","time":1153507996.000,"ept":0.005,"lat":48.904240000,"lon":2.332918333,"alt":99.100,"epx":18.222,"epy":17.174,"epv":82.942,"track":270.5600,"speed":0.000,"climb":0.100,"eps":36.44,"mode":3} +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185317.000,4854.2546,N,00219.9759,E,1,05,1.7,100.3,M,47.3,M,,0000*54 +$GPRMC,185317.000,A,4854.2546,N,00219.9759,E,0.00,270.56,210706,,,A*63 +{"class":"TPV","tag":"RMC","time":1153507997.000,"ept":0.005,"lat":48.904243333,"lon":2.332931667,"alt":100.300,"epx":18.222,"epy":17.174,"epv":82.942,"track":270.5600,"speed":0.000,"climb":1.200,"eps":36.44,"mode":3} +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185318.000,4854.2547,N,00219.9762,E,1,05,1.7,101.1,M,47.3,M,,0000*51 +$GPRMC,185318.000,A,4854.2547,N,00219.9762,E,0.00,270.56,210706,,,A*65 +{"class":"TPV","tag":"RMC","time":1153507998.000,"ept":0.005,"lat":48.904245000,"lon":2.332936667,"alt":101.100,"epx":18.222,"epy":17.174,"epv":82.942,"track":270.5600,"speed":0.000,"climb":0.800,"eps":36.44,"mode":3} +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185319.000,4854.2546,N,00219.9758,E,1,05,1.7,100.3,M,47.3,M,,0000*5B +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.7,1.7,2.2*39 +$GPGSV,3,1,11,30,79,308,21,05,54,079,19,06,43,204,34,14,39,247,40*76 +$GPGSV,3,2,11,01,31,303,30,02,28,077,,25,17,309,14,09,17,138,23*7A +$GPGSV,3,3,11,04,14,040,10,24,02,020,09,20,00,342,12*46 +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":1.14,"vdop":3.61,"tdop":2.85,"hdop":1.67,"gdop":4.89,"pdop":3.97,"satellites":[{"PRN":30,"el":79,"az":308,"ss":21,"used":true},{"PRN":5,"el":54,"az":79,"ss":19,"used":false},{"PRN":6,"el":43,"az":204,"ss":34,"used":true},{"PRN":14,"el":39,"az":247,"ss":40,"used":true},{"PRN":1,"el":31,"az":303,"ss":30,"used":true},{"PRN":2,"el":28,"az":77,"ss":0,"used":false},{"PRN":25,"el":17,"az":309,"ss":14,"used":false},{"PRN":9,"el":17,"az":138,"ss":23,"used":true},{"PRN":4,"el":14,"az":40,"ss":10,"used":false},{"PRN":24,"el":2,"az":20,"ss":9,"used":false},{"PRN":20,"el":0,"az":342,"ss":12,"used":false}]} +$GPRMC,185319.000,A,4854.2546,N,00219.9758,E,0.00,270.56,210706,,,A*6C +{"class":"TPV","tag":"RMC","time":1153507999.000,"ept":0.005,"lat":48.904243333,"lon":2.332930000,"alt":100.300,"epx":18.222,"epy":17.174,"epv":82.942,"track":270.5600,"speed":0.000,"climb":-0.800,"eps":36.44,"mode":3} +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185320.000,4854.2545,N,00219.9757,E,1,05,1.7,99.8,M,47.3,M,,0000*67 +$GPRMC,185320.000,A,4854.2545,N,00219.9757,E,0.00,270.56,210706,,,A*6A +{"class":"TPV","tag":"RMC","time":1153508000.000,"ept":0.005,"lat":48.904241667,"lon":2.332928333,"alt":99.800,"epx":18.222,"epy":17.174,"epv":82.942,"track":270.5600,"speed":0.000,"climb":-0.500,"eps":36.44,"mode":3} +$GPVTG,270.56,T,,M,0.00,N,0.0,K,A*0B +$GPGGA,185321.000,4854.2544,N,00219.9753,E,1,05,1.7,99.1,M,47.3,M,,0000*6A +$GPRMC,185321.000,A,4854.2544,N,00219.9753,E,1.28,261.85,210706,,,A*6B +{"class":"TPV","tag":"RMC","time":1153508001.000,"ept":0.005,"lat":48.904240000,"lon":2.332921667,"alt":99.100,"epx":18.222,"epy":17.174,"epv":82.942,"track":261.8500,"speed":0.658,"climb":-0.700,"eps":36.44,"mode":3} +$GPVTG,261.85,T,,M,1.28,N,2.4,K,A*08 +$GPGGA,185322.000,4854.2544,N,00219.9752,E,1,05,1.7,99.4,M,47.3,M,,0000*6D +$GPRMC,185322.000,A,4854.2544,N,00219.9752,E,0.00,261.85,210706,,,A*62 +{"class":"TPV","tag":"RMC","time":1153508002.000,"ept":0.005,"lat":48.904240000,"lon":2.332920000,"alt":99.400,"epx":18.222,"epy":17.174,"epv":82.942,"track":261.8500,"speed":0.000,"climb":0.300,"eps":36.44,"mode":3} +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 +$GPGGA,185323.000,4854.2544,N,00219.9753,E,1,05,1.7,99.5,M,47.3,M,,0000*6C +$GPRMC,185323.000,A,4854.2544,N,00219.9753,E,0.00,261.85,210706,,,A*62 +{"class":"TPV","tag":"RMC","time":1153508003.000,"ept":0.005,"lat":48.904240000,"lon":2.332921667,"alt":99.500,"epx":18.222,"epy":17.174,"epv":82.942,"track":261.8500,"speed":0.000,"climb":0.100,"eps":36.44,"mode":3} +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 +$GPGGA,185324.000,4854.2545,N,00219.9754,E,1,05,1.7,99.5,M,47.3,M,,0000*6D +$GPGSA,A,3,14,01,30,06,09,,,,,,,,2.7,1.7,2.2*39 +$GPGSV,3,1,11,30,79,308,20,05,54,079,18,06,43,204,35,14,39,247,40*77 +$GPGSV,3,2,11,01,31,303,30,02,28,077,,25,17,309,11,09,17,138,22*7E +$GPGSV,3,3,11,04,14,040,,24,02,020,08,20,00,342,08*4D +{"class":"SKY","tag":"GSV","xdop":1.21,"ydop":1.14,"vdop":3.61,"tdop":2.85,"hdop":1.67,"gdop":4.89,"pdop":3.97,"satellites":[{"PRN":30,"el":79,"az":308,"ss":20,"used":true},{"PRN":5,"el":54,"az":79,"ss":18,"used":false},{"PRN":6,"el":43,"az":204,"ss":35,"used":true},{"PRN":14,"el":39,"az":247,"ss":40,"used":true},{"PRN":1,"el":31,"az":303,"ss":30,"used":true},{"PRN":2,"el":28,"az":77,"ss":0,"used":false},{"PRN":25,"el":17,"az":309,"ss":11,"used":false},{"PRN":9,"el":17,"az":138,"ss":22,"used":true},{"PRN":4,"el":14,"az":40,"ss":0,"used":false},{"PRN":24,"el":2,"az":20,"ss":8,"used":false},{"PRN":20,"el":0,"az":342,"ss":8,"used":false}]} +$GPRMC,185324.000,A,4854.2545,N,00219.9754,E,0.00,261.85,210706,,,A*63 +{"class":"TPV","tag":"RMC","time":1153508004.000,"ept":0.005,"lat":48.904241667,"lon":2.332923333,"alt":99.500,"epx":18.222,"epy":17.174,"epv":82.942,"track":261.8500,"speed":0.000,"climb":0.000,"eps":36.44,"mode":3} +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 +$GPGGA,185325.000,4854.2546,N,00219.9759,E,1,05,1.7,99.9,M,47.3,M,,0000*6E +$GPRMC,185325.000,A,4854.2546,N,00219.9759,E,0.00,261.85,210706,,,A*6C +{"class":"TPV","tag":"RMC","time":1153508005.000,"ept":0.005,"lat":48.904243333,"lon":2.332931667,"alt":99.900,"epx":18.222,"epy":17.174,"epv":82.942,"track":261.8500,"speed":0.000,"climb":0.400,"eps":36.44,"mode":3} +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 +$GPGGA,185326.000,4854.2547,N,00219.9763,E,1,05,1.7,99.7,M,47.3,M,,0000*6B +$GPRMC,185326.000,A,4854.2547,N,00219.9763,E,0.00,261.85,210706,,,A*67 +{"class":"TPV","tag":"RMC","time":1153508006.000,"ept":0.005,"lat":48.904245000,"lon":2.332938333,"alt":99.700,"epx":18.222,"epy":17.174,"epv":82.942,"track":261.8500,"speed":0.000,"climb":-0.200,"eps":36.44,"mode":3} +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 +$GPGGA,185327.000,4854.2546,N,00219.9764,E,1,05,1.7,98.5,M,47.3,M,,0000*6F +$GPRMC,185327.000,A,4854.2546,N,00219.9764,E,0.00,261.85,210706,,,A*60 +{"class":"TPV","tag":"RMC","time":1153508007.000,"ept":0.005,"lat":48.904243333,"lon":2.332940000,"alt":98.500,"epx":18.222,"epy":17.174,"epv":82.942,"track":261.8500,"speed":0.000,"climb":-1.200,"eps":36.44,"mode":3} +$GPVTG,261.85,T,,M,0.00,N,0.0,K,A*05 diff --git a/test/daemon/haicom-305N.log b/test/daemon/haicom-305N.log new file mode 100644 index 0000000..97a1b40 --- /dev/null +++ b/test/daemon/haicom-305N.log @@ -0,0 +1,335 @@ +# Name: Haicom HI-305N +# Chipset: SiRF-II +# Date: 8 Apr 2007 +# Location: 153E 27S +# Submitted by: "David Findlay" +# Description: Starts stationary, then moving 5m due west, 10m due south, then reversing course +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGSV,3,3,12,24,58,220,,26,17,053,,29,20,063,,30,60,311,44*7F +$GPRMC,095255.810,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*6E +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095257.809,2712.6404,S,15303.1201,E,0,00,00.0,4.0,M,42.2,M,,*7B +$GPRMC,095257.809,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*64 +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095258.809,2712.6404,S,15303.1201,E,0,00,00.0,4.0,M,42.2,M,,*74 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,*77 +$GPGSV,3,2,12,10,44,132,,12,39,002,45,18,13,332,,21,33,266,*78 +$GPGSV,3,3,12,24,58,220,,26,17,053,,29,20,063,,30,60,311,44*7F +$GPRMC,095258.809,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*6B +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095300.809,2712.6404,S,15303.1201,E,0,00,00.0,4.0,M,42.2,M,,*78 +$GPRMC,095300.809,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*67 +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095301.809,2712.6404,S,15303.1201,E,0,00,00.0,4.0,M,42.2,M,,*79 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,*77 +$GPGSV,3,2,12,10,44,132,,12,39,002,45,18,13,332,,21,33,266,*78 +$GPGSV,3,3,12,24,58,220,,26,17,053,,29,20,063,,30,60,311,44*7F +$GPRMC,095301.809,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*66 +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095303.808,2712.6404,S,15303.1201,E,0,00,17.0,4.0,M,42.2,M,,*7C +$GPRMC,095303.808,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*65 +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095304.802,2712.6520,S,15303.1397,E,1,00,17.0,3.0,M,42.2,M,,*7E +$GPGSA,A,2,05,12,30,,,,,,,,,,17.0,17.0,0.0*36 +$GPGSV,3,1,12,2,15,123,,5,45,347,44,6,58,198,,7,45,212,*76 +$GPGSV,3,2,12,10,44,132,,12,39,002,43,18,13,332,34,21,33,266,*79 +$GPGSV,3,3,12,24,58,220,,26,17,053,,29,20,063,,30,60,311,45*7E +$GPRMC,095304.802,A,2712.6520,S,15303.1397,E,0.00,133.96,080407,,,A*78 +$GPVTG,133.96,T,,,0.00,N,0.00,K,A*7E +$GPGGA,095305.802,2712.6547,S,15303.1350,E,1,04,21.1,3.0,M,42.2,M,,*75 +$GPRMC,095305.802,A,2712.6547,S,15303.1350,E,1.93,133.96,080407,,,A*78 +$GPVTG,133.96,T,,,1.93,N,3.57,K,A*74 +$GPGGA,095306.802,2712.6506,S,15303.1298,E,1,04,21.1,3.0,M,42.2,M,,*76 +$GPRMC,095306.802,A,2712.6506,S,15303.1298,E,0.00,279.46,080407,,,A*70 +$GPVTG,279.46,T,,,0.00,N,0.00,K,A*7E +$GPGGA,095307.801,2712.6486,S,15303.1293,E,1,04,21.1,3.0,M,42.2,M,,*76 +$GPGSA,A,2,05,07,12,30,,,,,,,,,34.7,21.1,27.6*00 +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,28*7D +$GPGSV,3,2,12,10,44,132,28,12,39,002,42,18,13,332,34,21,33,266,*72 +$GPGSV,3,3,12,24,58,220,,26,17,054,,29,20,063,,30,60,311,44*78 +$GPRMC,095307.801,A,2712.6486,S,15303.1293,E,1.73,279.46,080407,,,A*75 +$GPVTG,279.46,T,,,1.73,N,3.20,K,A*7A +$GPGGA,095308.801,2712.6469,S,15303.1278,E,1,04,21.1,3.0,M,42.2,M,,*7D +$GPRMC,095308.801,A,2712.6469,S,15303.1278,E,2.40,335.10,080407,,,A*77 +$GPVTG,335.10,T,,,2.40,N,4.45,K,A*77 +$GPGGA,095309.801,2712.6444,S,15303.1229,E,1,05,07.5,3.0,M,42.2,M,,*76 +$GPRMC,095309.801,A,2712.6444,S,15303.1229,E,5.19,299.36,080407,,,A*75 +$GPVTG,299.36,T,,,5.19,N,9.60,K,A*75 +$GPGGA,095310.801,2712.6428,S,15303.1203,E,1,05,07.5,3.0,M,42.2,M,,*7C +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,30*74 +$GPGSV,3,2,12,10,44,132,28,12,39,002,43,18,13,332,33,21,33,266,*74 +$GPGSV,3,3,12,24,58,220,35,26,17,054,37,29,20,063,,30,60,311,45*7B +$GPRMC,095310.801,A,2712.6428,S,15303.1203,E,0.00,307.41,080407,,,A*74 +$GPVTG,307.41,T,,,0.00,N,0.00,K,A*71 +$GPGGA,095311.801,2712.6419,S,15303.1214,E,1,05,07.5,4.1,M,42.2,M,,*7F +$GPRMC,095311.801,A,2712.6419,S,15303.1214,E,2.16,307.41,080407,,,A*74 +$GPVTG,307.41,T,,,2.16,N,4.00,K,A*70 +$GPGGA,095312.800,2712.6400,S,15303.1170,E,1,05,07.5,4.5,M,42.2,M,,*70 +$GPRMC,095312.800,A,2712.6400,S,15303.1170,E,0.00,312.27,080407,,,A*7E +$GPVTG,312.27,T,,,0.00,N,0.00,K,A*75 +$GPGGA,095313.800,2712.6402,S,15303.1209,E,1,05,07.5,8.6,M,42.2,M,,*71 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,32*76 +$GPGSV,3,2,12,10,44,132,26,12,39,002,44,18,13,332,31,21,33,266,*7F +$GPGSV,3,3,12,24,58,220,37,26,17,054,37,29,20,063,,30,60,311,45*79 +$GPRMC,095313.800,A,2712.6402,S,15303.1209,E,3.47,312.27,080407,,,A*70 +$GPVTG,312.27,T,,,3.47,N,6.42,K,A*75 +$GPGGA,095314.800,2712.6396,S,15303.1200,E,1,05,07.5,10.1,M,42.2,M,,*4B +$GPRMC,095314.800,A,2712.6396,S,15303.1200,E,2.01,312.27,080407,,,A*77 +$GPVTG,312.27,T,,,2.01,N,3.72,K,A*70 +$GPGGA,095315.800,2712.6403,S,15303.1229,E,1,05,07.5,13.7,M,42.2,M,,*4F +$GPRMC,095315.800,A,2712.6403,S,15303.1229,E,3.56,92.94,080407,,,A*46 +$GPVTG,92.94,T,,,3.56,N,6.58,K,A*4D +$GPGGA,095316.799,2712.6400,S,15303.1217,E,1,05,07.5,13.8,M,42.2,M,,*42 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,33*77 +$GPGSV,3,2,12,10,44,132,23,12,39,002,44,18,13,332,31,21,33,266,*7A +$GPGSV,3,3,12,24,58,220,37,26,17,054,38,29,20,063,,30,60,311,45*76 +$GPRMC,095316.799,A,2712.6400,S,15303.1217,E,1.83,92.94,080407,,,A*4E +$GPVTG,92.94,T,,,1.83,N,3.39,K,A*45 +$GPGGA,095317.799,2712.6397,S,15303.1210,E,1,05,07.5,13.1,M,42.2,M,,*44 +$GPRMC,095317.799,A,2712.6397,S,15303.1210,E,1.78,92.94,080407,,,A*45 +$GPVTG,92.94,T,,,1.78,N,3.30,K,A*48 +$GPGGA,095318.799,2712.6409,S,15303.1239,E,1,05,07.5,18.1,M,42.2,M,,*4B +$GPRMC,095318.799,A,2712.6409,S,15303.1239,E,2.69,129.81,080407,,,A*77 +$GPVTG,129.81,T,,,2.69,N,4.97,K,A*74 +$GPGGA,095319.799,2712.6420,S,15303.1303,E,1,05,07.5,22.8,M,42.2,M,,*49 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,34*70 +$GPGSV,3,2,12,10,44,132,27,12,39,002,44,18,13,332,32,21,33,266,*7D +$GPGSV,3,3,12,24,58,220,37,26,17,054,39,29,20,063,,30,60,311,46*74 +$GPRMC,095319.799,A,2712.6420,S,15303.1303,E,5.09,100.78,080407,,,A*79 +$GPVTG,100.78,T,,,5.09,N,9.43,K,A*7C +$GPGGA,095320.799,2712.6420,S,15303.1290,E,1,05,07.5,19.5,M,42.2,M,,*4D +$GPRMC,095320.799,A,2712.6420,S,15303.1290,E,1.55,100.78,080407,,,A*75 +$GPVTG,100.78,T,,,1.55,N,2.87,K,A*72 +$GPGGA,095321.798,2712.6419,S,15303.1285,E,1,05,07.5,18.2,M,42.2,M,,*45 +$GPRMC,095321.798,A,2712.6419,S,15303.1285,E,1.15,100.78,080407,,,A*7F +$GPVTG,100.78,T,,,1.15,N,2.13,K,A*7B +$GPGGA,095322.798,2712.6419,S,15303.1281,E,1,05,07.5,17.3,M,42.2,M,,*4C +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,44,6,58,198,,7,45,212,32*77 +$GPGSV,3,2,12,10,44,132,31,12,39,002,44,18,13,332,33,21,33,266,*7B +$GPGSV,3,3,12,24,58,220,37,26,17,054,39,29,20,063,,30,60,311,45*77 +$GPRMC,095322.798,A,2712.6419,S,15303.1281,E,0.99,100.78,080407,,,A*7D +$GPVTG,100.78,T,,,0.99,N,1.84,K,A*73 +$GPGGA,095323.798,2712.6418,S,15303.1278,E,1,05,07.5,17.7,M,42.2,M,,*4E +$GPRMC,095323.798,A,2712.6418,S,15303.1278,E,0.00,100.78,080407,,,A*7B +$GPVTG,100.78,T,,,0.00,N,0.00,K,A*7E +$GPGGA,095324.798,2712.6417,S,15303.1275,E,1,05,07.5,18.0,M,42.2,M,,*43 +$GPRMC,095324.798,A,2712.6417,S,15303.1275,E,0.00,100.78,080407,,,A*7E +$GPVTG,100.78,T,,,0.00,N,0.00,K,A*7E +$GPGGA,095325.797,2712.6416,S,15303.1269,E,1,05,07.5,17.7,M,42.2,M,,*49 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,42,6,58,198,,7,45,212,31*72 +$GPGSV,3,2,12,10,44,132,34,12,39,002,43,18,13,332,30,21,33,266,*7A +$GPGSV,3,3,12,24,58,220,37,26,17,054,40,29,20,063,,30,60,311,44*78 +$GPRMC,095325.797,A,2712.6416,S,15303.1269,E,0.00,100.78,080407,,,A*7C +$GPVTG,100.78,T,,,0.00,N,0.00,K,A*7E +$GPGGA,095326.797,2712.6415,S,15303.1253,E,1,05,07.5,15.0,M,42.2,M,,*45 +$GPRMC,095326.797,A,2712.6415,S,15303.1253,E,1.10,100.78,080407,,,A*75 +$GPVTG,100.78,T,,,1.10,N,2.03,K,A*7F +$GPGGA,095327.797,2712.6414,S,15303.1244,E,1,05,07.5,14.2,M,42.2,M,,*40 +$GPRMC,095327.797,A,2712.6414,S,15303.1244,E,1.51,100.78,080407,,,A*76 +$GPVTG,100.78,T,,,1.51,N,2.80,K,A*71 +$GPGGA,095328.797,2712.6413,S,15303.1235,E,1,05,07.5,13.4,M,42.2,M,,*4F +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,42,6,58,198,,7,45,212,37*74 +$GPGSV,3,2,12,10,44,132,37,12,39,002,43,18,13,332,27,21,33,266,*7F +$GPGSV,3,3,12,24,58,220,40,26,17,054,39,29,20,063,,30,60,311,44*76 +$GPRMC,095328.797,A,2712.6413,S,15303.1235,E,1.55,276.34,080407,,,A*76 +$GPVTG,276.34,T,,,1.55,N,2.86,K,A*79 +$GPGGA,095329.797,2712.6413,S,15303.1226,E,1,05,07.5,12.7,M,42.2,M,,*4E +$GPRMC,095329.797,A,2712.6413,S,15303.1226,E,1.67,276.34,080407,,,A*74 +$GPVTG,276.34,T,,,1.67,N,3.09,K,A*7E +$GPGGA,095330.796,2712.6413,S,15303.1218,E,1,05,07.5,12.4,M,42.2,M,,*49 +$GPRMC,095330.796,A,2712.6413,S,15303.1218,E,1.72,276.34,080407,,,A*74 +$GPVTG,276.34,T,,,1.72,N,3.19,K,A*7B +$GPGGA,095331.796,2712.6414,S,15303.1212,E,1,05,07.5,12.3,M,42.2,M,,*42 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,43,6,58,198,,7,45,212,42*77 +$GPGSV,3,2,12,10,44,132,41,12,39,002,44,18,13,332,28,21,33,265,*75 +$GPGSV,3,3,12,24,58,220,42,26,17,054,35,29,20,063,38,30,59,311,44*79 +$GPRMC,095331.796,A,2712.6414,S,15303.1212,E,1.79,276.34,080407,,,A*73 +$GPVTG,276.34,T,,,1.79,N,3.32,K,A*79 +$GPGGA,095333.796,2712.6422,S,15303.1205,E,1,05,07.5,11.9,M,42.2,M,,*4A +$GPRMC,095333.796,A,2712.6422,S,15303.1205,E,1.87,276.34,080407,,,A*73 +$GPVTG,276.34,T,,,1.87,N,3.46,K,A*7B +$GPGGA,095334.796,2712.6427,S,15303.1202,E,1,05,07.5,11.6,M,42.2,M,,*40 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,41,6,58,198,,7,45,212,44*73 +$GPGSV,3,2,12,10,44,132,42,12,39,002,40,18,13,332,29,21,33,265,*73 +$GPGSV,3,3,12,24,58,220,43,26,17,054,38,29,20,063,39,30,59,311,44*74 +$GPRMC,095334.796,A,2712.6427,S,15303.1202,E,2.01,276.34,080407,,,A*7B +$GPVTG,276.34,T,,,2.01,N,3.72,K,A*71 +$GPGGA,095336.795,2712.6439,S,15303.1195,E,1,04,10.4,11.6,M,42.2,M,,*45 +$GPRMC,095336.795,A,2712.6439,S,15303.1195,E,2.37,209.25,080407,,,A*75 +$GPVTG,209.25,T,,,2.37,N,4.38,K,A*75 +$GPGGA,095337.795,2712.6444,S,15303.1189,E,1,06,02.3,11.3,M,42.2,M,,*40 +$GPGSA,A,3,05,07,12,21,24,30,,,,,,,4.8,2.3,4.2*3E +$GPGSV,3,1,12,2,15,123,,5,45,347,39,6,58,198,,7,45,212,44*7C +$GPGSV,3,2,12,10,44,132,42,12,39,002,38,18,13,332,27,21,33,265,36*77 +$GPGSV,3,3,12,24,58,220,44,26,17,054,39,29,20,063,40,30,59,311,45*7D +$GPRMC,095337.795,A,2712.6444,S,15303.1189,E,2.31,209.45,080407,,,A*73 +$GPVTG,209.45,T,,,2.31,N,4.28,K,A*74 +$GPGGA,095338.795,2712.6450,S,15303.1192,E,1,06,02.3,12.4,M,42.2,M,,*44 +$GPRMC,095338.795,A,2712.6450,S,15303.1192,E,2.24,203.09,080407,,,A*75 +$GPVTG,203.09,T,,,2.24,N,4.14,K,A*7D +$GPGGA,095339.794,2712.6456,S,15303.1185,E,1,06,04.1,11.6,M,42.2,M,,*41 +$GPRMC,095339.794,A,2712.6456,S,15303.1185,E,2.28,200.03,080407,,,A*70 +$GPVTG,200.03,T,,,2.28,N,4.22,K,A*7D +$GPGGA,095340.794,2712.6461,S,15303.1180,E,1,07,01.3,10.0,M,42.2,M,,*4F +$GPGSA,A,3,02,05,07,12,21,24,30,,,,,,3.0,1.3,2.7*33 +$GPGSV,3,1,12,2,15,123,39,5,45,347,39,6,58,198,43,7,45,212,43*76 +$GPGSV,3,2,12,10,44,132,43,12,39,002,37,18,13,332,25,21,33,265,35*78 +$GPGSV,3,3,12,24,58,220,44,26,17,054,41,29,20,063,41,30,59,311,44*72 +$GPRMC,095340.794,A,2712.6461,S,15303.1180,E,2.23,189.90,080407,,,A*7C +$GPVTG,189.90,T,,,2.23,N,4.12,K,A*7D +$GPGGA,095341.794,2712.6467,S,15303.1177,E,1,07,01.3,10.0,M,42.2,M,,*40 +$GPRMC,095341.794,A,2712.6467,S,15303.1177,E,2.24,191.01,080407,,,A*75 +$GPVTG,191.01,T,,,2.24,N,4.15,K,A*7C +$GPGGA,095342.794,2712.6472,S,15303.1170,E,1,07,01.3,9.1,M,42.2,M,,*79 +$GPRMC,095342.794,A,2712.6472,S,15303.1170,E,2.28,193.30,080407,,,A*79 +$GPVTG,193.30,T,,,2.28,N,4.22,K,A*74 +$GPGGA,095343.794,2712.6478,S,15303.1166,E,1,07,01.3,8.1,M,42.2,M,,*74 +$GPGSA,A,3,02,05,07,12,21,24,30,,,,,,3.0,1.3,2.7*33 +$GPGSV,3,1,12,2,15,123,36,5,45,347,38,6,58,198,45,7,45,212,42*7F +$GPGSV,3,2,12,10,44,132,43,12,39,002,36,18,14,332,23,21,34,265,37*7D +$GPGSV,3,3,12,24,58,220,43,26,17,054,41,29,20,063,41,30,59,312,44*76 +$GPRMC,095343.794,A,2712.6478,S,15303.1166,E,2.18,187.10,080407,,,A*71 +$GPVTG,187.10,T,,,2.18,N,4.03,K,A*73 +$GPGGA,095344.793,2712.6483,S,15303.1163,E,1,07,01.3,8.4,M,42.2,M,,*70 +$GPRMC,095344.793,A,2712.6483,S,15303.1163,E,2.26,192.88,080407,,,A*78 +$GPVTG,192.88,T,,,2.26,N,4.18,K,A*71 +$GPGGA,095345.793,2712.6489,S,15303.1158,E,1,07,01.3,7.5,M,42.2,M,,*7D +$GPRMC,095345.793,A,2712.6489,S,15303.1158,E,2.26,190.81,080407,,,A*70 +$GPVTG,190.81,T,,,2.26,N,4.18,K,A*7A +$GPGGA,095346.793,2712.6494,S,15303.1153,E,1,07,01.3,7.5,M,42.2,M,,*79 +$GPGSA,A,3,02,05,07,12,21,24,30,,,,,,3.0,1.3,2.7*33 +$GPGSV,3,1,12,2,15,123,37,5,45,347,39,6,58,198,44,7,45,212,42*7E +$GPGSV,3,2,12,10,44,132,44,12,39,002,37,18,14,332,23,21,34,265,39*75 +$GPGSV,3,3,12,24,58,220,41,26,17,054,42,29,20,063,41,30,59,312,43*70 +$GPRMC,095346.793,A,2712.6494,S,15303.1153,E,2.22,194.09,080407,,,A*74 +$GPVTG,194.09,T,,,2.22,N,4.11,K,A*73 +$GPGGA,095347.793,2712.6500,S,15303.1150,E,1,07,01.3,7.5,M,42.2,M,,*77 +$GPRMC,095347.793,A,2712.6500,S,15303.1150,E,2.23,191.68,080407,,,A*79 +$GPVTG,191.68,T,,,2.23,N,4.13,K,A*72 +$GPGGA,095348.792,2712.6505,S,15303.1148,E,1,07,01.3,7.4,M,42.2,M,,*74 +$GPRMC,095348.792,A,2712.6505,S,15303.1148,E,2.11,187.45,080407,,,A*72 +$GPVTG,187.45,T,,,2.11,N,3.91,K,A*76 +$GPGGA,095349.792,2712.6511,S,15303.1147,E,1,07,01.3,7.3,M,42.2,M,,*78 +$GPGSA,A,3,02,05,07,12,21,24,30,,,,,,3.0,1.3,2.7*33 +$GPGSV,3,1,12,2,15,123,35,5,45,347,38,6,58,198,44,7,45,212,41*7E +$GPGSV,3,2,12,10,44,132,43,12,39,002,39,18,14,332,23,21,34,265,40*72 +$GPGSV,3,3,12,24,58,220,40,26,17,054,41,29,20,063,42,30,59,312,44*76 +$GPRMC,095349.792,A,2712.6511,S,15303.1147,E,2.04,188.22,080407,,,A*73 +$GPVTG,188.22,T,,,2.04,N,3.78,K,A*7B +$GPGGA,095350.792,2712.6515,S,15303.1143,E,1,07,01.3,7.0,M,42.2,M,,*73 +$GPRMC,095350.792,A,2712.6515,S,15303.1143,E,1.77,194.81,080407,,,A*78 +$GPVTG,194.81,T,,,1.77,N,3.28,K,A*7D +$GPGGA,095351.792,2712.6515,S,15303.1138,E,1,07,01.3,6.2,M,42.2,M,,*7D +$GPRMC,095351.792,A,2712.6515,S,15303.1138,E,0.98,194.81,080407,,,A*75 +$GPVTG,194.81,T,,,0.98,N,1.81,K,A*7C +$GPGGA,095352.792,2712.6511,S,15303.1137,E,1,06,02.3,5.8,M,42.2,M,,*7E +$GPGSA,A,3,05,07,12,21,24,30,,,,,,,4.8,2.3,4.2*3E +$GPGSV,3,1,12,2,15,123,33,5,45,347,41,6,58,198,42,7,45,212,41*70 +$GPGSV,3,2,12,10,44,132,42,12,39,002,40,18,14,332,25,21,34,265,39*75 +$GPGSV,3,3,12,24,58,220,41,26,17,054,39,29,20,063,40,30,59,312,43*7D +$GPRMC,095352.792,A,2712.6511,S,15303.1137,E,1.39,350.04,080407,,,A*70 +$GPVTG,350.04,T,,,1.39,N,2.57,K,A*79 +$GPGGA,095353.791,2712.6505,S,15303.1137,E,1,06,02.3,5.9,M,42.2,M,,*78 +$GPRMC,095353.791,A,2712.6505,S,15303.1137,E,1.92,359.88,080407,,,A*7B +$GPVTG,359.88,T,,,1.92,N,3.56,K,A*75 +$GPGGA,095354.791,2712.6500,S,15303.1137,E,1,07,01.3,5.2,M,42.2,M,,*73 +$GPRMC,095354.791,A,2712.6500,S,15303.1137,E,2.00,11.44,080407,,,A*4E +$GPVTG,11.44,T,,,2.00,N,3.70,K,A*46 +$GPGGA,095355.791,2712.6493,S,15303.1137,E,1,07,01.3,4.7,M,42.2,M,,*7D +$GPGSA,A,3,02,05,07,12,21,24,30,,,,,,3.0,1.3,2.7*33 +$GPGSV,3,1,12,2,15,123,34,5,45,347,42,6,58,198,42,7,45,212,41*74 +$GPGSV,3,2,12,10,44,132,42,12,39,002,41,18,14,332,26,21,34,265,41*78 +$GPGSV,3,3,12,24,58,220,43,26,17,054,40,29,20,063,38,30,59,312,44*79 +$GPRMC,095355.791,A,2712.6493,S,15303.1137,E,2.13,16.78,080407,,,A*4E +$GPVTG,16.78,T,,,2.13,N,3.95,K,A*47 +$GPGGA,095356.791,2712.6487,S,15303.1136,E,1,07,01.3,4.3,M,42.2,M,,*7E +$GPRMC,095356.791,A,2712.6487,S,15303.1136,E,2.25,13.51,080407,,,A*42 +$GPVTG,13.51,T,,,2.25,N,4.16,K,A*40 +$GPGGA,095357.791,2712.6480,S,15303.1135,E,1,07,01.3,4.1,M,42.2,M,,*79 +$GPRMC,095357.791,A,2712.6480,S,15303.1135,E,2.30,7.49,080407,,,A*7F +$GPVTG,7.49,T,,,2.30,N,4.26,K,A*7B +$GPGGA,095358.790,2712.6473,S,15303.1133,E,1,08,01.1,3.9,M,42.2,M,,*7F +$GPGSA,A,3,02,05,07,10,12,21,24,30,,,,,2.6,1.1,2.4*34 +$GPGSV,3,1,12,2,15,123,36,5,45,347,43,6,58,198,42,7,45,212,41*77 +$GPGSV,3,2,12,10,43,132,41,12,39,002,41,18,14,332,26,21,34,265,42*7F +$GPGSV,3,3,12,24,58,219,43,26,17,054,38,29,20,063,37,30,59,312,44*73 +$GPRMC,095358.790,A,2712.6473,S,15303.1133,E,2.34,6.73,080407,,,A*77 +$GPVTG,6.73,T,,,2.34,N,4.32,K,A*72 +$GPGGA,095400.790,2712.6459,S,15303.1133,E,1,06,01.8,3.5,M,42.2,M,,*76 +$GPRMC,095400.790,A,2712.6459,S,15303.1133,E,2.40,7.80,080407,,,A*7B +$GPVTG,7.80,T,,,2.40,N,4.44,K,A*7D +$GPGGA,095401.790,2712.6453,S,15303.1133,E,1,08,01.1,3.7,M,42.2,M,,*78 +$GPGSA,A,3,02,05,07,10,12,21,24,30,,,,,2.6,1.1,2.4*34 +$GPGSV,3,1,12,2,15,123,35,5,45,347,43,6,58,198,42,7,45,212,39*7B +$GPGSV,3,2,12,10,43,132,40,12,39,002,40,18,14,332,25,21,34,265,40*7E +$GPGSV,3,3,12,24,58,219,44,26,17,054,38,29,20,063,37,30,59,312,43*73 +$GPRMC,095401.790,A,2712.6453,S,15303.1133,E,2.36,7.77,080407,,,A*79 +$GPVTG,7.77,T,,,2.36,N,4.37,K,A*70 +$GPGGA,095403.789,2712.6439,S,15303.1137,E,1,08,01.1,3.5,M,42.2,M,,*78 +$GPRMC,095403.789,A,2712.6439,S,15303.1137,E,2.48,15.66,080407,,,A*41 +$GPVTG,15.66,T,,,2.48,N,4.59,K,A*42 +$GPGGA,095404.789,2712.6432,S,15303.1137,E,1,09,01.1,3.3,M,42.2,M,,*73 +$GPGSA,A,3,02,05,06,07,10,12,21,24,30,,,,2.5,1.1,2.2*37 +$GPGSV,3,1,12,2,15,123,33,5,45,347,44,6,58,197,42,7,45,212,41*7A +$GPGSV,3,2,12,10,43,132,39,12,39,002,41,18,14,332,25,21,34,265,39*7F +$GPGSV,3,3,12,24,58,219,45,26,17,054,38,29,20,063,38,30,59,312,43*7D +$GPRMC,095404.789,A,2712.6432,S,15303.1137,E,2.45,12.39,080407,,,A*4D +$GPVTG,12.39,T,,,2.45,N,4.54,K,A*4F +$GPGGA,095405.789,2712.6425,S,15303.1138,E,1,09,01.1,3.1,M,42.2,M,,*79 +$GPRMC,095405.789,A,2712.6425,S,15303.1138,E,2.55,16.50,080407,,,A*4F +$GPVTG,16.50,T,,,2.55,N,4.73,K,A*40 +$GPGGA,095406.789,2712.6420,S,15303.1142,E,1,09,01.1,2.7,M,42.2,M,,*75 +$GPRMC,095406.789,A,2712.6420,S,15303.1142,E,2.35,31.12,080407,,,A*41 +$GPVTG,31.12,T,,,2.35,N,4.35,K,A*47 +$GPGGA,095407.788,2712.6415,S,15303.1145,E,1,08,01.7,2.5,M,42.2,M,,*71 +$GPGSA,A,3,02,05,06,07,10,12,24,30,,,,,3.9,1.7,3.4*38 +$GPGSV,3,1,12,2,14,123,33,5,45,347,43,6,58,197,42,7,45,212,41*7C +$GPGSV,3,2,12,10,43,132,42,12,39,002,40,18,14,332,28,21,34,265,36*70 +$GPGSV,3,3,12,24,58,219,43,26,17,054,38,29,20,063,39,30,59,312,43*7A +$GPRMC,095407.788,A,2712.6415,S,15303.1145,E,2.28,40.30,080407,,,A*4A +$GPVTG,40.30,T,,,2.28,N,4.23,K,A*4A +$GPGGA,095408.788,2712.6411,S,15303.1151,E,1,09,01.1,2.6,M,42.2,M,,*7B +$GPRMC,095408.788,A,2712.6411,S,15303.1151,E,2.35,51.76,080407,,,A*4A +$GPVTG,51.76,T,,,2.35,N,4.35,K,A*43 +$GPGGA,095409.788,2712.6409,S,15303.1158,E,1,09,01.1,2.6,M,42.2,M,,*7A +$GPRMC,095409.788,A,2712.6409,S,15303.1158,E,2.41,68.20,080407,,,A*41 +$GPVTG,68.20,T,,,2.41,N,4.47,K,A*4C +$GPGGA,095410.788,2712.6407,S,15303.1166,E,1,09,01.1,2.9,M,42.2,M,,*7E +$GPGSA,A,3,02,05,06,07,10,12,21,24,30,,,,2.5,1.1,2.2*37 +$GPGSV,3,1,12,2,14,123,28,5,45,347,43,6,58,197,42,7,45,212,41*76 +$GPGSV,3,2,12,10,43,132,43,12,39,002,42,18,14,332,31,21,34,265,37*7A +$GPGSV,3,3,12,24,58,219,43,26,17,054,39,29,20,063,37,30,59,312,44*72 +$GPRMC,095410.788,A,2712.6407,S,15303.1166,E,2.54,74.38,080407,,,A*4A +$GPVTG,74.38,T,,,2.54,N,4.71,K,A*49 +$GPGGA,095411.787,2712.6405,S,15303.1173,E,1,09,01.1,2.9,M,42.2,M,,*76 +$GPRMC,095411.787,A,2712.6405,S,15303.1173,E,2.34,76.68,080407,,,A*43 +$GPVTG,76.68,T,,,2.34,N,4.33,K,A*4E +$GPGGA,095412.787,2712.6404,S,15303.1180,E,1,09,01.1,3.0,M,42.2,M,,*70 +$GPRMC,095412.787,A,2712.6404,S,15303.1180,E,2.33,77.59,080407,,,A*49 +$GPVTG,77.59,T,,,2.33,N,4.32,K,A*4B +$GPGGA,095413.787,2712.6403,S,15303.1187,E,1,08,01.1,3.1,M,42.2,M,,*71 +$GPGSA,A,3,02,05,07,10,12,21,24,30,,,,,2.6,1.1,2.4*34 +$GPGSV,3,1,12,2,14,123,25,5,45,347,44,6,58,197,39,7,45,212,38*7E +$GPGSV,3,2,12,10,43,132,35,12,39,002,43,18,14,332,30,21,34,265,38*74 +$GPGSV,3,3,12,24,58,219,40,26,17,054,38,29,20,063,38,30,59,312,44*7F +$GPRMC,095413.787,A,2712.6403,S,15303.1187,E,2.47,79.51,080407,,,A*4D +$GPVTG,79.51,T,,,2.47,N,4.57,K,A*4D +$GPGGA,095414.787,2712.6403,S,15303.1194,E,1,09,01.1,3.2,M,42.2,M,,*76 +$GPRMC,095414.787,A,2712.6403,S,15303.1194,E,2.20,86.03,080407,,,A*4E +$GPVTG,86.03,T,,,2.20,N,4.07,K,A*4E +$GPGGA,095415.787,2712.6404,S,15303.1200,E,1,06,01.8,3.5,M,42.2,M,,*7F +$GPRMC,095415.787,A,2712.6404,S,15303.1200,E,2.11,96.86,080407,,,A*48 diff --git a/test/daemon/haicom-305N.log.chk b/test/daemon/haicom-305N.log.chk new file mode 100644 index 0000000..86d3db1 --- /dev/null +++ b/test/daemon/haicom-305N.log.chk @@ -0,0 +1,423 @@ +$GPGSV,3,3,12,24,58,220,,26,17,053,,29,20,063,,30,60,311,44*7F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":24,"el":58,"az":220,"ss":0,"used":false},{"PRN":26,"el":17,"az":53,"ss":0,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":44,"used":false}]} +$GPRMC,095255.810,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*6E +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095257.809,2712.6404,S,15303.1201,E,0,00,00.0,4.0,M,42.2,M,,*7B +$GPRMC,095257.809,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*64 +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095258.809,2712.6404,S,15303.1201,E,0,00,00.0,4.0,M,42.2,M,,*74 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,*77 +$GPGSV,3,2,12,10,44,132,,12,39,002,45,18,13,332,,21,33,266,*78 +$GPGSV,3,3,12,24,58,220,,26,17,053,,29,20,063,,30,60,311,44*7F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":45,"used":false},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":0,"used":false},{"PRN":10,"el":44,"az":132,"ss":0,"used":false},{"PRN":12,"el":39,"az":2,"ss":45,"used":false},{"PRN":18,"el":13,"az":332,"ss":0,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":0,"used":false},{"PRN":26,"el":17,"az":53,"ss":0,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":44,"used":false}]} +$GPRMC,095258.809,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*6B +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095300.809,2712.6404,S,15303.1201,E,0,00,00.0,4.0,M,42.2,M,,*78 +$GPRMC,095300.809,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*67 +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095301.809,2712.6404,S,15303.1201,E,0,00,00.0,4.0,M,42.2,M,,*79 +$GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,*77 +$GPGSV,3,2,12,10,44,132,,12,39,002,45,18,13,332,,21,33,266,*78 +$GPGSV,3,3,12,24,58,220,,26,17,053,,29,20,063,,30,60,311,44*7F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":45,"used":false},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":0,"used":false},{"PRN":10,"el":44,"az":132,"ss":0,"used":false},{"PRN":12,"el":39,"az":2,"ss":45,"used":false},{"PRN":18,"el":13,"az":332,"ss":0,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":0,"used":false},{"PRN":26,"el":17,"az":53,"ss":0,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":44,"used":false}]} +$GPRMC,095301.809,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*66 +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095303.808,2712.6404,S,15303.1201,E,0,00,17.0,4.0,M,42.2,M,,*7C +$GPRMC,095303.808,V,2712.6404,S,15303.1201,E,0.00,0.00,080407,,,A*65 +$GPVTG,0.00,T,,,0.00,N,0.00,K,A*70 +$GPGGA,095304.802,2712.6520,S,15303.1397,E,1,00,17.0,3.0,M,42.2,M,,*7E +{"class":"TPV","tag":"GGA","lat":-27.210866667,"lon":153.052328333,"alt":3.000,"mode":3} +$GPGSA,A,2,05,12,30,,,,,,,,,,17.0,17.0,0.0*36 +$GPGSV,3,1,12,2,15,123,,5,45,347,44,6,58,198,,7,45,212,*76 +$GPGSV,3,2,12,10,44,132,,12,39,002,43,18,13,332,34,21,33,266,*79 +$GPGSV,3,3,12,24,58,220,,26,17,053,,29,20,063,,30,60,311,45*7E +{"class":"SKY","tag":"GSV","satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":44,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":0,"used":false},{"PRN":10,"el":44,"az":132,"ss":0,"used":false},{"PRN":12,"el":39,"az":2,"ss":43,"used":true},{"PRN":18,"el":13,"az":332,"ss":34,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":0,"used":false},{"PRN":26,"el":17,"az":53,"ss":0,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":45,"used":true}]} +$GPRMC,095304.802,A,2712.6520,S,15303.1397,E,0.00,133.96,080407,,,A*78 +{"class":"TPV","tag":"RMC","time":1176025984.802,"ept":0.005,"lat":-27.210866667,"lon":153.052328333,"alt":3.000,"epv":0.000,"track":133.9600,"speed":0.000,"mode":3} +$GPVTG,133.96,T,,,0.00,N,0.00,K,A*7E +$GPGGA,095305.802,2712.6547,S,15303.1350,E,1,04,21.1,3.0,M,42.2,M,,*75 +$GPRMC,095305.802,A,2712.6547,S,15303.1350,E,1.93,133.96,080407,,,A*78 +{"class":"TPV","tag":"RMC","time":1176025985.802,"ept":0.005,"lat":-27.210911667,"lon":153.052250000,"alt":3.000,"track":133.9600,"speed":0.993,"climb":0.000,"mode":3} +$GPVTG,133.96,T,,,1.93,N,3.57,K,A*74 +$GPGGA,095306.802,2712.6506,S,15303.1298,E,1,04,21.1,3.0,M,42.2,M,,*76 +$GPRMC,095306.802,A,2712.6506,S,15303.1298,E,0.00,279.46,080407,,,A*70 +{"class":"TPV","tag":"RMC","time":1176025986.802,"ept":0.005,"lat":-27.210843333,"lon":153.052163333,"alt":3.000,"track":279.4600,"speed":0.000,"climb":0.000,"mode":3} +$GPVTG,279.46,T,,,0.00,N,0.00,K,A*7E +$GPGGA,095307.801,2712.6486,S,15303.1293,E,1,04,21.1,3.0,M,42.2,M,,*76 +$GPGSA,A,2,05,07,12,30,,,,,,,,,34.7,21.1,27.6*00 +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,28*7D +$GPGSV,3,2,12,10,44,132,28,12,39,002,42,18,13,332,34,21,33,266,*72 +$GPGSV,3,3,12,24,58,220,,26,17,054,,29,20,063,,30,60,311,44*78 +{"class":"SKY","tag":"GSV","xdop":2.86,"ydop":0.96,"vdop":5.91,"tdop":3.84,"hdop":3.02,"gdop":7.67,"pdop":6.64,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":45,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":28,"used":true},{"PRN":10,"el":44,"az":132,"ss":28,"used":false},{"PRN":12,"el":39,"az":2,"ss":42,"used":true},{"PRN":18,"el":13,"az":332,"ss":34,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":0,"used":false},{"PRN":26,"el":17,"az":54,"ss":0,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":44,"used":true}]} +$GPRMC,095307.801,A,2712.6486,S,15303.1293,E,1.73,279.46,080407,,,A*75 +{"class":"TPV","tag":"RMC","time":1176025987.801,"ept":0.005,"lat":-27.210810000,"lon":153.052155000,"alt":3.000,"epx":42.926,"epy":14.332,"epv":634.800,"track":279.4600,"speed":0.890,"climb":0.000,"mode":3} +$GPVTG,279.46,T,,,1.73,N,3.20,K,A*7A +$GPGGA,095308.801,2712.6469,S,15303.1278,E,1,04,21.1,3.0,M,42.2,M,,*7D +$GPRMC,095308.801,A,2712.6469,S,15303.1278,E,2.40,335.10,080407,,,A*77 +{"class":"TPV","tag":"RMC","time":1176025988.801,"ept":0.005,"lat":-27.210781667,"lon":153.052130000,"alt":3.000,"epx":42.926,"epy":14.332,"epv":135.991,"track":335.1000,"speed":1.235,"climb":0.000,"eps":85.85,"mode":3} +$GPVTG,335.10,T,,,2.40,N,4.45,K,A*77 +$GPGGA,095309.801,2712.6444,S,15303.1229,E,1,05,07.5,3.0,M,42.2,M,,*76 +$GPRMC,095309.801,A,2712.6444,S,15303.1229,E,5.19,299.36,080407,,,A*75 +{"class":"TPV","tag":"RMC","time":1176025989.801,"ept":0.005,"lat":-27.210740000,"lon":153.052048333,"alt":3.000,"epx":42.926,"epy":14.332,"epv":135.991,"track":299.3600,"speed":2.670,"climb":0.000,"eps":85.85,"mode":3} +$GPVTG,299.36,T,,,5.19,N,9.60,K,A*75 +$GPGGA,095310.801,2712.6428,S,15303.1203,E,1,05,07.5,3.0,M,42.2,M,,*7C +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,30*74 +$GPGSV,3,2,12,10,44,132,28,12,39,002,43,18,13,332,33,21,33,266,*74 +$GPGSV,3,3,12,24,58,220,35,26,17,054,37,29,20,063,,30,60,311,45*7B +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.95,"vdop":3.48,"tdop":2.43,"hdop":1.83,"gdop":4.62,"pdop":3.93,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":45,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":30,"used":true},{"PRN":10,"el":44,"az":132,"ss":28,"used":false},{"PRN":12,"el":39,"az":2,"ss":43,"used":true},{"PRN":18,"el":13,"az":332,"ss":33,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":35,"used":true},{"PRN":26,"el":17,"az":54,"ss":37,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":45,"used":true}]} +$GPRMC,095310.801,A,2712.6428,S,15303.1203,E,0.00,307.41,080407,,,A*74 +{"class":"TPV","tag":"RMC","time":1176025990.801,"ept":0.005,"lat":-27.210713333,"lon":153.052005000,"alt":3.000,"epx":42.926,"epy":14.332,"epv":135.991,"track":307.4100,"speed":0.000,"climb":0.000,"eps":85.85,"mode":3} +$GPVTG,307.41,T,,,0.00,N,0.00,K,A*71 +$GPGGA,095311.801,2712.6419,S,15303.1214,E,1,05,07.5,4.1,M,42.2,M,,*7F +$GPRMC,095311.801,A,2712.6419,S,15303.1214,E,2.16,307.41,080407,,,A*74 +{"class":"TPV","tag":"RMC","time":1176025991.801,"ept":0.005,"lat":-27.210698333,"lon":153.052023333,"alt":4.100,"epx":23.367,"epy":14.300,"epv":80.054,"track":307.4100,"speed":1.111,"climb":1.100,"eps":66.29,"mode":3} +$GPVTG,307.41,T,,,2.16,N,4.00,K,A*70 +$GPGGA,095312.800,2712.6400,S,15303.1170,E,1,05,07.5,4.5,M,42.2,M,,*70 +$GPRMC,095312.800,A,2712.6400,S,15303.1170,E,0.00,312.27,080407,,,A*7E +{"class":"TPV","tag":"RMC","time":1176025992.800,"ept":0.005,"lat":-27.210666667,"lon":153.051950000,"alt":4.500,"epx":23.367,"epy":14.300,"epv":80.054,"track":312.2700,"speed":0.000,"climb":0.400,"eps":46.78,"mode":3} +$GPVTG,312.27,T,,,0.00,N,0.00,K,A*75 +$GPGGA,095313.800,2712.6402,S,15303.1209,E,1,05,07.5,8.6,M,42.2,M,,*71 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,32*76 +$GPGSV,3,2,12,10,44,132,26,12,39,002,44,18,13,332,31,21,33,266,*7F +$GPGSV,3,3,12,24,58,220,37,26,17,054,37,29,20,063,,30,60,311,45*79 +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.95,"vdop":3.48,"tdop":2.43,"hdop":1.83,"gdop":4.62,"pdop":3.93,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":45,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":32,"used":true},{"PRN":10,"el":44,"az":132,"ss":26,"used":false},{"PRN":12,"el":39,"az":2,"ss":44,"used":true},{"PRN":18,"el":13,"az":332,"ss":31,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":37,"used":true},{"PRN":26,"el":17,"az":54,"ss":37,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":45,"used":true}]} +$GPRMC,095313.800,A,2712.6402,S,15303.1209,E,3.47,312.27,080407,,,A*70 +{"class":"TPV","tag":"RMC","time":1176025993.800,"ept":0.005,"lat":-27.210670000,"lon":153.052015000,"alt":8.600,"epx":23.367,"epy":14.300,"epv":80.054,"track":312.2700,"speed":1.785,"climb":4.100,"eps":46.73,"mode":3} +$GPVTG,312.27,T,,,3.47,N,6.42,K,A*75 +$GPGGA,095314.800,2712.6396,S,15303.1200,E,1,05,07.5,10.1,M,42.2,M,,*4B +$GPRMC,095314.800,A,2712.6396,S,15303.1200,E,2.01,312.27,080407,,,A*77 +{"class":"TPV","tag":"RMC","time":1176025994.800,"ept":0.005,"lat":-27.210660000,"lon":153.052000000,"alt":10.100,"epx":23.367,"epy":14.300,"epv":80.054,"track":312.2700,"speed":1.034,"climb":1.500,"eps":46.73,"mode":3} +$GPVTG,312.27,T,,,2.01,N,3.72,K,A*70 +$GPGGA,095315.800,2712.6403,S,15303.1229,E,1,05,07.5,13.7,M,42.2,M,,*4F +$GPRMC,095315.800,A,2712.6403,S,15303.1229,E,3.56,92.94,080407,,,A*46 +{"class":"TPV","tag":"RMC","time":1176025995.800,"ept":0.005,"lat":-27.210671667,"lon":153.052048333,"alt":13.700,"epx":23.367,"epy":14.300,"epv":80.054,"track":92.9400,"speed":1.831,"climb":3.600,"eps":46.73,"mode":3} +$GPVTG,92.94,T,,,3.56,N,6.58,K,A*4D +$GPGGA,095316.799,2712.6400,S,15303.1217,E,1,05,07.5,13.8,M,42.2,M,,*42 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,33*77 +$GPGSV,3,2,12,10,44,132,23,12,39,002,44,18,13,332,31,21,33,266,*7A +$GPGSV,3,3,12,24,58,220,37,26,17,054,38,29,20,063,,30,60,311,45*76 +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.95,"vdop":3.48,"tdop":2.43,"hdop":1.83,"gdop":4.62,"pdop":3.93,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":45,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":33,"used":true},{"PRN":10,"el":44,"az":132,"ss":23,"used":false},{"PRN":12,"el":39,"az":2,"ss":44,"used":true},{"PRN":18,"el":13,"az":332,"ss":31,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":37,"used":true},{"PRN":26,"el":17,"az":54,"ss":38,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":45,"used":true}]} +$GPRMC,095316.799,A,2712.6400,S,15303.1217,E,1.83,92.94,080407,,,A*4E +{"class":"TPV","tag":"RMC","time":1176025996.799,"ept":0.005,"lat":-27.210666667,"lon":153.052028333,"alt":13.800,"epx":23.367,"epy":14.300,"epv":80.054,"track":92.9400,"speed":0.941,"climb":0.100,"eps":46.78,"mode":3} +$GPVTG,92.94,T,,,1.83,N,3.39,K,A*45 +$GPGGA,095317.799,2712.6397,S,15303.1210,E,1,05,07.5,13.1,M,42.2,M,,*44 +$GPRMC,095317.799,A,2712.6397,S,15303.1210,E,1.78,92.94,080407,,,A*45 +{"class":"TPV","tag":"RMC","time":1176025997.799,"ept":0.005,"lat":-27.210661667,"lon":153.052016667,"alt":13.100,"epx":23.367,"epy":14.300,"epv":80.054,"track":92.9400,"speed":0.916,"climb":-0.700,"eps":46.73,"mode":3} +$GPVTG,92.94,T,,,1.78,N,3.30,K,A*48 +$GPGGA,095318.799,2712.6409,S,15303.1239,E,1,05,07.5,18.1,M,42.2,M,,*4B +$GPRMC,095318.799,A,2712.6409,S,15303.1239,E,2.69,129.81,080407,,,A*77 +{"class":"TPV","tag":"RMC","time":1176025998.799,"ept":0.005,"lat":-27.210681667,"lon":153.052065000,"alt":18.100,"epx":23.367,"epy":14.300,"epv":80.054,"track":129.8100,"speed":1.384,"climb":5.000,"eps":46.73,"mode":3} +$GPVTG,129.81,T,,,2.69,N,4.97,K,A*74 +$GPGGA,095319.799,2712.6420,S,15303.1303,E,1,05,07.5,22.8,M,42.2,M,,*49 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,45,6,58,198,,7,45,212,34*70 +$GPGSV,3,2,12,10,44,132,27,12,39,002,44,18,13,332,32,21,33,266,*7D +$GPGSV,3,3,12,24,58,220,37,26,17,054,39,29,20,063,,30,60,311,46*74 +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.95,"vdop":3.48,"tdop":2.43,"hdop":1.83,"gdop":4.62,"pdop":3.93,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":45,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":34,"used":true},{"PRN":10,"el":44,"az":132,"ss":27,"used":false},{"PRN":12,"el":39,"az":2,"ss":44,"used":true},{"PRN":18,"el":13,"az":332,"ss":32,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":37,"used":true},{"PRN":26,"el":17,"az":54,"ss":39,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":46,"used":true}]} +$GPRMC,095319.799,A,2712.6420,S,15303.1303,E,5.09,100.78,080407,,,A*79 +{"class":"TPV","tag":"RMC","time":1176025999.799,"ept":0.005,"lat":-27.210700000,"lon":153.052171667,"alt":22.800,"epx":23.367,"epy":14.300,"epv":80.054,"track":100.7800,"speed":2.619,"climb":4.700,"eps":46.73,"mode":3} +$GPVTG,100.78,T,,,5.09,N,9.43,K,A*7C +$GPGGA,095320.799,2712.6420,S,15303.1290,E,1,05,07.5,19.5,M,42.2,M,,*4D +$GPRMC,095320.799,A,2712.6420,S,15303.1290,E,1.55,100.78,080407,,,A*75 +{"class":"TPV","tag":"RMC","time":1176026000.799,"ept":0.005,"lat":-27.210700000,"lon":153.052150000,"alt":19.500,"epx":23.367,"epy":14.300,"epv":80.054,"track":100.7800,"speed":0.797,"climb":-3.300,"eps":46.73,"mode":3} +$GPVTG,100.78,T,,,1.55,N,2.87,K,A*72 +$GPGGA,095321.798,2712.6419,S,15303.1285,E,1,05,07.5,18.2,M,42.2,M,,*45 +$GPRMC,095321.798,A,2712.6419,S,15303.1285,E,1.15,100.78,080407,,,A*7F +{"class":"TPV","tag":"RMC","time":1176026001.798,"ept":0.005,"lat":-27.210698333,"lon":153.052141667,"alt":18.200,"epx":23.367,"epy":14.300,"epv":80.054,"track":100.7800,"speed":0.592,"climb":-1.301,"eps":46.78,"mode":3} +$GPVTG,100.78,T,,,1.15,N,2.13,K,A*7B +$GPGGA,095322.798,2712.6419,S,15303.1281,E,1,05,07.5,17.3,M,42.2,M,,*4C +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,44,6,58,198,,7,45,212,32*77 +$GPGSV,3,2,12,10,44,132,31,12,39,002,44,18,13,332,33,21,33,266,*7B +$GPGSV,3,3,12,24,58,220,37,26,17,054,39,29,20,063,,30,60,311,45*77 +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.95,"vdop":3.48,"tdop":2.43,"hdop":1.83,"gdop":4.62,"pdop":3.93,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":44,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":32,"used":true},{"PRN":10,"el":44,"az":132,"ss":31,"used":false},{"PRN":12,"el":39,"az":2,"ss":44,"used":true},{"PRN":18,"el":13,"az":332,"ss":33,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":37,"used":true},{"PRN":26,"el":17,"az":54,"ss":39,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":45,"used":true}]} +$GPRMC,095322.798,A,2712.6419,S,15303.1281,E,0.99,100.78,080407,,,A*7D +{"class":"TPV","tag":"RMC","time":1176026002.798,"ept":0.005,"lat":-27.210698333,"lon":153.052135000,"alt":17.300,"epx":23.367,"epy":14.300,"epv":80.054,"track":100.7800,"speed":0.509,"climb":-0.900,"eps":46.73,"mode":3} +$GPVTG,100.78,T,,,0.99,N,1.84,K,A*73 +$GPGGA,095323.798,2712.6418,S,15303.1278,E,1,05,07.5,17.7,M,42.2,M,,*4E +$GPRMC,095323.798,A,2712.6418,S,15303.1278,E,0.00,100.78,080407,,,A*7B +{"class":"TPV","tag":"RMC","time":1176026003.798,"ept":0.005,"lat":-27.210696667,"lon":153.052130000,"alt":17.700,"epx":23.367,"epy":14.300,"epv":80.054,"track":100.7800,"speed":0.000,"climb":0.400,"eps":46.73,"mode":3} +$GPVTG,100.78,T,,,0.00,N,0.00,K,A*7E +$GPGGA,095324.798,2712.6417,S,15303.1275,E,1,05,07.5,18.0,M,42.2,M,,*43 +$GPRMC,095324.798,A,2712.6417,S,15303.1275,E,0.00,100.78,080407,,,A*7E +{"class":"TPV","tag":"RMC","time":1176026004.798,"ept":0.005,"lat":-27.210695000,"lon":153.052125000,"alt":18.000,"epx":23.367,"epy":14.300,"epv":80.054,"track":100.7800,"speed":0.000,"climb":0.300,"eps":46.73,"mode":3} +$GPVTG,100.78,T,,,0.00,N,0.00,K,A*7E +$GPGGA,095325.797,2712.6416,S,15303.1269,E,1,05,07.5,17.7,M,42.2,M,,*49 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,42,6,58,198,,7,45,212,31*72 +$GPGSV,3,2,12,10,44,132,34,12,39,002,43,18,13,332,30,21,33,266,*7A +$GPGSV,3,3,12,24,58,220,37,26,17,054,40,29,20,063,,30,60,311,44*78 +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.95,"vdop":3.48,"tdop":2.43,"hdop":1.83,"gdop":4.62,"pdop":3.93,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":42,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":31,"used":true},{"PRN":10,"el":44,"az":132,"ss":34,"used":false},{"PRN":12,"el":39,"az":2,"ss":43,"used":true},{"PRN":18,"el":13,"az":332,"ss":30,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":37,"used":true},{"PRN":26,"el":17,"az":54,"ss":40,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":44,"used":true}]} +$GPRMC,095325.797,A,2712.6416,S,15303.1269,E,0.00,100.78,080407,,,A*7C +{"class":"TPV","tag":"RMC","time":1176026005.797,"ept":0.005,"lat":-27.210693333,"lon":153.052115000,"alt":17.700,"epx":23.367,"epy":14.300,"epv":80.054,"track":100.7800,"speed":0.000,"climb":-0.300,"eps":46.78,"mode":3} +$GPVTG,100.78,T,,,0.00,N,0.00,K,A*7E +$GPGGA,095326.797,2712.6415,S,15303.1253,E,1,05,07.5,15.0,M,42.2,M,,*45 +$GPRMC,095326.797,A,2712.6415,S,15303.1253,E,1.10,100.78,080407,,,A*75 +{"class":"TPV","tag":"RMC","time":1176026006.797,"ept":0.005,"lat":-27.210691667,"lon":153.052088333,"alt":15.000,"epx":23.367,"epy":14.300,"epv":80.054,"track":100.7800,"speed":0.566,"climb":-2.700,"eps":46.73,"mode":3} +$GPVTG,100.78,T,,,1.10,N,2.03,K,A*7F +$GPGGA,095327.797,2712.6414,S,15303.1244,E,1,05,07.5,14.2,M,42.2,M,,*40 +$GPRMC,095327.797,A,2712.6414,S,15303.1244,E,1.51,100.78,080407,,,A*76 +{"class":"TPV","tag":"RMC","time":1176026007.797,"ept":0.005,"lat":-27.210690000,"lon":153.052073333,"alt":14.200,"epx":23.367,"epy":14.300,"epv":80.054,"track":100.7800,"speed":0.777,"climb":-0.800,"eps":46.73,"mode":3} +$GPVTG,100.78,T,,,1.51,N,2.80,K,A*71 +$GPGGA,095328.797,2712.6413,S,15303.1235,E,1,05,07.5,13.4,M,42.2,M,,*4F +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,42,6,58,198,,7,45,212,37*74 +$GPGSV,3,2,12,10,44,132,37,12,39,002,43,18,13,332,27,21,33,266,*7F +$GPGSV,3,3,12,24,58,220,40,26,17,054,39,29,20,063,,30,60,311,44*76 +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.95,"vdop":3.48,"tdop":2.43,"hdop":1.83,"gdop":4.62,"pdop":3.93,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":42,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":37,"used":true},{"PRN":10,"el":44,"az":132,"ss":37,"used":false},{"PRN":12,"el":39,"az":2,"ss":43,"used":true},{"PRN":18,"el":13,"az":332,"ss":27,"used":false},{"PRN":21,"el":33,"az":266,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":40,"used":true},{"PRN":26,"el":17,"az":54,"ss":39,"used":false},{"PRN":29,"el":20,"az":63,"ss":0,"used":false},{"PRN":30,"el":60,"az":311,"ss":44,"used":true}]} +$GPRMC,095328.797,A,2712.6413,S,15303.1235,E,1.55,276.34,080407,,,A*76 +{"class":"TPV","tag":"RMC","time":1176026008.797,"ept":0.005,"lat":-27.210688333,"lon":153.052058333,"alt":13.400,"epx":23.367,"epy":14.300,"epv":80.054,"track":276.3400,"speed":0.797,"climb":-0.800,"eps":46.73,"mode":3} +$GPVTG,276.34,T,,,1.55,N,2.86,K,A*79 +$GPGGA,095329.797,2712.6413,S,15303.1226,E,1,05,07.5,12.7,M,42.2,M,,*4E +$GPRMC,095329.797,A,2712.6413,S,15303.1226,E,1.67,276.34,080407,,,A*74 +{"class":"TPV","tag":"RMC","time":1176026009.797,"ept":0.005,"lat":-27.210688333,"lon":153.052043333,"alt":12.700,"epx":23.367,"epy":14.300,"epv":80.054,"track":276.3400,"speed":0.859,"climb":-0.700,"eps":46.73,"mode":3} +$GPVTG,276.34,T,,,1.67,N,3.09,K,A*7E +$GPGGA,095330.796,2712.6413,S,15303.1218,E,1,05,07.5,12.4,M,42.2,M,,*49 +$GPRMC,095330.796,A,2712.6413,S,15303.1218,E,1.72,276.34,080407,,,A*74 +{"class":"TPV","tag":"RMC","time":1176026010.796,"ept":0.005,"lat":-27.210688333,"lon":153.052030000,"alt":12.400,"epx":23.367,"epy":14.300,"epv":80.054,"track":276.3400,"speed":0.885,"climb":-0.300,"eps":46.78,"mode":3} +$GPVTG,276.34,T,,,1.72,N,3.19,K,A*7B +$GPGGA,095331.796,2712.6414,S,15303.1212,E,1,05,07.5,12.3,M,42.2,M,,*42 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,43,6,58,198,,7,45,212,42*77 +$GPGSV,3,2,12,10,44,132,41,12,39,002,44,18,13,332,28,21,33,265,*75 +$GPGSV,3,3,12,24,58,220,42,26,17,054,35,29,20,063,38,30,59,311,44*79 +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.95,"vdop":3.48,"tdop":2.43,"hdop":1.83,"gdop":4.62,"pdop":3.93,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":43,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":42,"used":true},{"PRN":10,"el":44,"az":132,"ss":41,"used":false},{"PRN":12,"el":39,"az":2,"ss":44,"used":true},{"PRN":18,"el":13,"az":332,"ss":28,"used":false},{"PRN":21,"el":33,"az":265,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":42,"used":true},{"PRN":26,"el":17,"az":54,"ss":35,"used":false},{"PRN":29,"el":20,"az":63,"ss":38,"used":false},{"PRN":30,"el":59,"az":311,"ss":44,"used":true}]} +$GPRMC,095331.796,A,2712.6414,S,15303.1212,E,1.79,276.34,080407,,,A*73 +{"class":"TPV","tag":"RMC","time":1176026011.796,"ept":0.005,"lat":-27.210690000,"lon":153.052020000,"alt":12.300,"epx":23.367,"epy":14.300,"epv":80.054,"track":276.3400,"speed":0.921,"climb":-0.100,"eps":46.73,"mode":3} +$GPVTG,276.34,T,,,1.79,N,3.32,K,A*79 +$GPGGA,095333.796,2712.6422,S,15303.1205,E,1,05,07.5,11.9,M,42.2,M,,*4A +$GPRMC,095333.796,A,2712.6422,S,15303.1205,E,1.87,276.34,080407,,,A*73 +{"class":"TPV","tag":"RMC","time":1176026013.796,"ept":0.005,"lat":-27.210703333,"lon":153.052008333,"alt":11.900,"epx":23.367,"epy":14.300,"epv":80.054,"track":276.3400,"speed":0.962,"climb":-0.200,"eps":23.37,"mode":3} +$GPVTG,276.34,T,,,1.87,N,3.46,K,A*7B +$GPGGA,095334.796,2712.6427,S,15303.1202,E,1,05,07.5,11.6,M,42.2,M,,*40 +$GPGSA,A,3,05,07,12,24,30,,,,,,,,11.7,7.5,9.0*0A +$GPGSV,3,1,12,2,15,123,,5,45,347,41,6,58,198,,7,45,212,44*73 +$GPGSV,3,2,12,10,44,132,42,12,39,002,40,18,13,332,29,21,33,265,*73 +$GPGSV,3,3,12,24,58,220,43,26,17,054,38,29,20,063,39,30,59,311,44*74 +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.95,"vdop":3.48,"tdop":2.43,"hdop":1.83,"gdop":4.62,"pdop":3.93,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":41,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":44,"used":true},{"PRN":10,"el":44,"az":132,"ss":42,"used":false},{"PRN":12,"el":39,"az":2,"ss":40,"used":true},{"PRN":18,"el":13,"az":332,"ss":29,"used":false},{"PRN":21,"el":33,"az":265,"ss":0,"used":false},{"PRN":24,"el":58,"az":220,"ss":43,"used":true},{"PRN":26,"el":17,"az":54,"ss":38,"used":false},{"PRN":29,"el":20,"az":63,"ss":39,"used":false},{"PRN":30,"el":59,"az":311,"ss":44,"used":true}]} +$GPRMC,095334.796,A,2712.6427,S,15303.1202,E,2.01,276.34,080407,,,A*7B +{"class":"TPV","tag":"RMC","time":1176026014.796,"ept":0.005,"lat":-27.210711667,"lon":153.052003333,"alt":11.600,"epx":23.367,"epy":14.300,"epv":80.054,"track":276.3400,"speed":1.034,"climb":-0.300,"eps":46.73,"mode":3} +$GPVTG,276.34,T,,,2.01,N,3.72,K,A*71 +$GPGGA,095336.795,2712.6439,S,15303.1195,E,1,04,10.4,11.6,M,42.2,M,,*45 +$GPRMC,095336.795,A,2712.6439,S,15303.1195,E,2.37,209.25,080407,,,A*75 +{"class":"TPV","tag":"RMC","time":1176026016.795,"ept":0.005,"lat":-27.210731667,"lon":153.051991667,"alt":11.600,"epx":23.367,"epy":14.300,"epv":80.054,"track":209.2500,"speed":1.219,"climb":0.000,"eps":23.38,"mode":3} +$GPVTG,209.25,T,,,2.37,N,4.38,K,A*75 +$GPGGA,095337.795,2712.6444,S,15303.1189,E,1,06,02.3,11.3,M,42.2,M,,*40 +$GPGSA,A,3,05,07,12,21,24,30,,,,,,,4.8,2.3,4.2*3E +$GPGSV,3,1,12,2,15,123,,5,45,347,39,6,58,198,,7,45,212,44*7C +$GPGSV,3,2,12,10,44,132,42,12,39,002,38,18,13,332,27,21,33,265,36*77 +$GPGSV,3,3,12,24,58,220,44,26,17,054,39,29,20,063,40,30,59,311,45*7D +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.72,"vdop":3.47,"tdop":2.39,"hdop":1.71,"gdop":4.55,"pdop":3.87,"satellites":[{"PRN":2,"el":15,"az":123,"ss":0,"used":false},{"PRN":5,"el":45,"az":347,"ss":39,"used":true},{"PRN":6,"el":58,"az":198,"ss":0,"used":false},{"PRN":7,"el":45,"az":212,"ss":44,"used":true},{"PRN":10,"el":44,"az":132,"ss":42,"used":false},{"PRN":12,"el":39,"az":2,"ss":38,"used":true},{"PRN":18,"el":13,"az":332,"ss":27,"used":false},{"PRN":21,"el":33,"az":265,"ss":36,"used":true},{"PRN":24,"el":58,"az":220,"ss":44,"used":true},{"PRN":26,"el":17,"az":54,"ss":39,"used":false},{"PRN":29,"el":20,"az":63,"ss":40,"used":false},{"PRN":30,"el":59,"az":311,"ss":45,"used":true}]} +$GPRMC,095337.795,A,2712.6444,S,15303.1189,E,2.31,209.45,080407,,,A*73 +{"class":"TPV","tag":"RMC","time":1176026017.795,"ept":0.005,"lat":-27.210740000,"lon":153.051981667,"alt":11.300,"epx":23.367,"epy":14.300,"epv":80.054,"track":209.4500,"speed":1.188,"climb":-0.300,"eps":46.73,"mode":3} +$GPVTG,209.45,T,,,2.31,N,4.28,K,A*74 +$GPGGA,095338.795,2712.6450,S,15303.1192,E,1,06,02.3,12.4,M,42.2,M,,*44 +$GPRMC,095338.795,A,2712.6450,S,15303.1192,E,2.24,203.09,080407,,,A*75 +{"class":"TPV","tag":"RMC","time":1176026018.795,"ept":0.005,"lat":-27.210750000,"lon":153.051986667,"alt":12.400,"epx":23.360,"epy":10.770,"epv":79.875,"track":203.0900,"speed":1.152,"climb":1.100,"eps":46.73,"mode":3} +$GPVTG,203.09,T,,,2.24,N,4.14,K,A*7D +$GPGGA,095339.794,2712.6456,S,15303.1185,E,1,06,04.1,11.6,M,42.2,M,,*41 +$GPRMC,095339.794,A,2712.6456,S,15303.1185,E,2.28,200.03,080407,,,A*70 +{"class":"TPV","tag":"RMC","time":1176026019.794,"ept":0.005,"lat":-27.210760000,"lon":153.051975000,"alt":11.600,"epx":23.360,"epy":10.770,"epv":79.875,"track":200.0300,"speed":1.173,"climb":-0.801,"eps":46.77,"mode":3} +$GPVTG,200.03,T,,,2.28,N,4.22,K,A*7D +$GPGGA,095340.794,2712.6461,S,15303.1180,E,1,07,01.3,10.0,M,42.2,M,,*4F +$GPGSA,A,3,02,05,07,12,21,24,30,,,,,,3.0,1.3,2.7*33 +$GPGSV,3,1,12,2,15,123,39,5,45,347,39,6,58,198,43,7,45,212,43*76 +$GPGSV,3,2,12,10,44,132,43,12,39,002,37,18,13,332,25,21,33,265,35*78 +$GPGSV,3,3,12,24,58,220,44,26,17,054,41,29,20,063,41,30,59,311,44*72 +{"class":"SKY","tag":"GSV","xdop":1.04,"ydop":0.71,"vdop":1.91,"tdop":1.19,"hdop":1.26,"gdop":2.58,"pdop":2.29,"satellites":[{"PRN":2,"el":15,"az":123,"ss":39,"used":true},{"PRN":5,"el":45,"az":347,"ss":39,"used":true},{"PRN":6,"el":58,"az":198,"ss":43,"used":false},{"PRN":7,"el":45,"az":212,"ss":43,"used":true},{"PRN":10,"el":44,"az":132,"ss":43,"used":false},{"PRN":12,"el":39,"az":2,"ss":37,"used":true},{"PRN":18,"el":13,"az":332,"ss":25,"used":false},{"PRN":21,"el":33,"az":265,"ss":35,"used":true},{"PRN":24,"el":58,"az":220,"ss":44,"used":true},{"PRN":26,"el":17,"az":54,"ss":41,"used":false},{"PRN":29,"el":20,"az":63,"ss":41,"used":false},{"PRN":30,"el":59,"az":311,"ss":44,"used":true}]} +$GPRMC,095340.794,A,2712.6461,S,15303.1180,E,2.23,189.90,080407,,,A*7C +{"class":"TPV","tag":"RMC","time":1176026020.794,"ept":0.005,"lat":-27.210768333,"lon":153.051966667,"alt":10.000,"epx":23.360,"epy":10.770,"epv":79.875,"track":189.9000,"speed":1.147,"climb":-1.600,"eps":46.72,"mode":3} +$GPVTG,189.90,T,,,2.23,N,4.12,K,A*7D +$GPGGA,095341.794,2712.6467,S,15303.1177,E,1,07,01.3,10.0,M,42.2,M,,*40 +$GPRMC,095341.794,A,2712.6467,S,15303.1177,E,2.24,191.01,080407,,,A*75 +{"class":"TPV","tag":"RMC","time":1176026021.794,"ept":0.005,"lat":-27.210778333,"lon":153.051961667,"alt":10.000,"epx":15.636,"epy":10.722,"epv":43.917,"track":191.0100,"speed":1.152,"climb":0.000,"eps":39.00,"mode":3} +$GPVTG,191.01,T,,,2.24,N,4.15,K,A*7C +$GPGGA,095342.794,2712.6472,S,15303.1170,E,1,07,01.3,9.1,M,42.2,M,,*79 +$GPRMC,095342.794,A,2712.6472,S,15303.1170,E,2.28,193.30,080407,,,A*79 +{"class":"TPV","tag":"RMC","time":1176026022.794,"ept":0.005,"lat":-27.210786667,"lon":153.051950000,"alt":9.100,"epx":15.636,"epy":10.722,"epv":43.917,"track":193.3000,"speed":1.173,"climb":-0.900,"eps":31.27,"mode":3} +$GPVTG,193.30,T,,,2.28,N,4.22,K,A*74 +$GPGGA,095343.794,2712.6478,S,15303.1166,E,1,07,01.3,8.1,M,42.2,M,,*74 +$GPGSA,A,3,02,05,07,12,21,24,30,,,,,,3.0,1.3,2.7*33 +$GPGSV,3,1,12,2,15,123,36,5,45,347,38,6,58,198,45,7,45,212,42*7F +$GPGSV,3,2,12,10,44,132,43,12,39,002,36,18,14,332,23,21,34,265,37*7D +$GPGSV,3,3,12,24,58,220,43,26,17,054,41,29,20,063,41,30,59,312,44*76 +{"class":"SKY","tag":"GSV","xdop":1.05,"ydop":0.71,"vdop":1.95,"tdop":1.22,"hdop":1.27,"gdop":2.63,"pdop":2.33,"satellites":[{"PRN":2,"el":15,"az":123,"ss":36,"used":true},{"PRN":5,"el":45,"az":347,"ss":38,"used":true},{"PRN":6,"el":58,"az":198,"ss":45,"used":false},{"PRN":7,"el":45,"az":212,"ss":42,"used":true},{"PRN":10,"el":44,"az":132,"ss":43,"used":false},{"PRN":12,"el":39,"az":2,"ss":36,"used":true},{"PRN":18,"el":14,"az":332,"ss":23,"used":false},{"PRN":21,"el":34,"az":265,"ss":37,"used":true},{"PRN":24,"el":58,"az":220,"ss":43,"used":true},{"PRN":26,"el":17,"az":54,"ss":41,"used":false},{"PRN":29,"el":20,"az":63,"ss":41,"used":false},{"PRN":30,"el":59,"az":312,"ss":44,"used":true}]} +$GPRMC,095343.794,A,2712.6478,S,15303.1166,E,2.18,187.10,080407,,,A*71 +{"class":"TPV","tag":"RMC","time":1176026023.794,"ept":0.005,"lat":-27.210796667,"lon":153.051943333,"alt":8.100,"epx":15.636,"epy":10.722,"epv":43.917,"track":187.1000,"speed":1.121,"climb":-1.000,"eps":31.27,"mode":3} +$GPVTG,187.10,T,,,2.18,N,4.03,K,A*73 +$GPGGA,095344.793,2712.6483,S,15303.1163,E,1,07,01.3,8.4,M,42.2,M,,*70 +$GPRMC,095344.793,A,2712.6483,S,15303.1163,E,2.26,192.88,080407,,,A*78 +{"class":"TPV","tag":"RMC","time":1176026024.793,"ept":0.005,"lat":-27.210805000,"lon":153.051938333,"alt":8.400,"epx":15.734,"epy":10.717,"epv":44.819,"track":192.8800,"speed":1.163,"climb":0.300,"eps":31.40,"mode":3} +$GPVTG,192.88,T,,,2.26,N,4.18,K,A*71 +$GPGGA,095345.793,2712.6489,S,15303.1158,E,1,07,01.3,7.5,M,42.2,M,,*7D +$GPRMC,095345.793,A,2712.6489,S,15303.1158,E,2.26,190.81,080407,,,A*70 +{"class":"TPV","tag":"RMC","time":1176026025.793,"ept":0.005,"lat":-27.210815000,"lon":153.051930000,"alt":7.500,"epx":15.734,"epy":10.717,"epv":44.819,"track":190.8100,"speed":1.163,"climb":-0.900,"eps":31.47,"mode":3} +$GPVTG,190.81,T,,,2.26,N,4.18,K,A*7A +$GPGGA,095346.793,2712.6494,S,15303.1153,E,1,07,01.3,7.5,M,42.2,M,,*79 +$GPGSA,A,3,02,05,07,12,21,24,30,,,,,,3.0,1.3,2.7*33 +$GPGSV,3,1,12,2,15,123,37,5,45,347,39,6,58,198,44,7,45,212,42*7E +$GPGSV,3,2,12,10,44,132,44,12,39,002,37,18,14,332,23,21,34,265,39*75 +$GPGSV,3,3,12,24,58,220,41,26,17,054,42,29,20,063,41,30,59,312,43*70 +{"class":"SKY","tag":"GSV","xdop":1.05,"ydop":0.71,"vdop":1.95,"tdop":1.22,"hdop":1.27,"gdop":2.63,"pdop":2.33,"satellites":[{"PRN":2,"el":15,"az":123,"ss":37,"used":true},{"PRN":5,"el":45,"az":347,"ss":39,"used":true},{"PRN":6,"el":58,"az":198,"ss":44,"used":false},{"PRN":7,"el":45,"az":212,"ss":42,"used":true},{"PRN":10,"el":44,"az":132,"ss":44,"used":false},{"PRN":12,"el":39,"az":2,"ss":37,"used":true},{"PRN":18,"el":14,"az":332,"ss":23,"used":false},{"PRN":21,"el":34,"az":265,"ss":39,"used":true},{"PRN":24,"el":58,"az":220,"ss":41,"used":true},{"PRN":26,"el":17,"az":54,"ss":42,"used":false},{"PRN":29,"el":20,"az":63,"ss":41,"used":false},{"PRN":30,"el":59,"az":312,"ss":43,"used":true}]} +$GPRMC,095346.793,A,2712.6494,S,15303.1153,E,2.22,194.09,080407,,,A*74 +{"class":"TPV","tag":"RMC","time":1176026026.793,"ept":0.005,"lat":-27.210823333,"lon":153.051921667,"alt":7.500,"epx":15.734,"epy":10.717,"epv":44.819,"track":194.0900,"speed":1.142,"climb":0.000,"eps":31.47,"mode":3} +$GPVTG,194.09,T,,,2.22,N,4.11,K,A*73 +$GPGGA,095347.793,2712.6500,S,15303.1150,E,1,07,01.3,7.5,M,42.2,M,,*77 +$GPRMC,095347.793,A,2712.6500,S,15303.1150,E,2.23,191.68,080407,,,A*79 +{"class":"TPV","tag":"RMC","time":1176026027.793,"ept":0.005,"lat":-27.210833333,"lon":153.051916667,"alt":7.500,"epx":15.734,"epy":10.717,"epv":44.819,"track":191.6800,"speed":1.147,"climb":0.000,"eps":31.47,"mode":3} +$GPVTG,191.68,T,,,2.23,N,4.13,K,A*72 +$GPGGA,095348.792,2712.6505,S,15303.1148,E,1,07,01.3,7.4,M,42.2,M,,*74 +$GPRMC,095348.792,A,2712.6505,S,15303.1148,E,2.11,187.45,080407,,,A*72 +{"class":"TPV","tag":"RMC","time":1176026028.792,"ept":0.005,"lat":-27.210841667,"lon":153.051913333,"alt":7.400,"epx":15.734,"epy":10.717,"epv":44.819,"track":187.4500,"speed":1.085,"climb":-0.100,"eps":31.50,"mode":3} +$GPVTG,187.45,T,,,2.11,N,3.91,K,A*76 +$GPGGA,095349.792,2712.6511,S,15303.1147,E,1,07,01.3,7.3,M,42.2,M,,*78 +$GPGSA,A,3,02,05,07,12,21,24,30,,,,,,3.0,1.3,2.7*33 +$GPGSV,3,1,12,2,15,123,35,5,45,347,38,6,58,198,44,7,45,212,41*7E +$GPGSV,3,2,12,10,44,132,43,12,39,002,39,18,14,332,23,21,34,265,40*72 +$GPGSV,3,3,12,24,58,220,40,26,17,054,41,29,20,063,42,30,59,312,44*76 +{"class":"SKY","tag":"GSV","xdop":1.05,"ydop":0.71,"vdop":1.95,"tdop":1.22,"hdop":1.27,"gdop":2.63,"pdop":2.33,"satellites":[{"PRN":2,"el":15,"az":123,"ss":35,"used":true},{"PRN":5,"el":45,"az":347,"ss":38,"used":true},{"PRN":6,"el":58,"az":198,"ss":44,"used":false},{"PRN":7,"el":45,"az":212,"ss":41,"used":true},{"PRN":10,"el":44,"az":132,"ss":43,"used":false},{"PRN":12,"el":39,"az":2,"ss":39,"used":true},{"PRN":18,"el":14,"az":332,"ss":23,"used":false},{"PRN":21,"el":34,"az":265,"ss":40,"used":true},{"PRN":24,"el":58,"az":220,"ss":40,"used":true},{"PRN":26,"el":17,"az":54,"ss":41,"used":false},{"PRN":29,"el":20,"az":63,"ss":42,"used":false},{"PRN":30,"el":59,"az":312,"ss":44,"used":true}]} +$GPRMC,095349.792,A,2712.6511,S,15303.1147,E,2.04,188.22,080407,,,A*73 +{"class":"TPV","tag":"RMC","time":1176026029.792,"ept":0.005,"lat":-27.210851667,"lon":153.051911667,"alt":7.300,"epx":15.734,"epy":10.717,"epv":44.819,"track":188.2200,"speed":1.049,"climb":-0.100,"eps":31.47,"mode":3} +$GPVTG,188.22,T,,,2.04,N,3.78,K,A*7B +$GPGGA,095350.792,2712.6515,S,15303.1143,E,1,07,01.3,7.0,M,42.2,M,,*73 +$GPRMC,095350.792,A,2712.6515,S,15303.1143,E,1.77,194.81,080407,,,A*78 +{"class":"TPV","tag":"RMC","time":1176026030.792,"ept":0.005,"lat":-27.210858333,"lon":153.051905000,"alt":7.000,"epx":15.734,"epy":10.717,"epv":44.819,"track":194.8100,"speed":0.911,"climb":-0.300,"eps":31.47,"mode":3} +$GPVTG,194.81,T,,,1.77,N,3.28,K,A*7D +$GPGGA,095351.792,2712.6515,S,15303.1138,E,1,07,01.3,6.2,M,42.2,M,,*7D +$GPRMC,095351.792,A,2712.6515,S,15303.1138,E,0.98,194.81,080407,,,A*75 +{"class":"TPV","tag":"RMC","time":1176026031.792,"ept":0.005,"lat":-27.210858333,"lon":153.051896667,"alt":6.200,"epx":15.734,"epy":10.717,"epv":44.819,"track":194.8100,"speed":0.504,"climb":-0.800,"eps":31.47,"mode":3} +$GPVTG,194.81,T,,,0.98,N,1.81,K,A*7C +$GPGGA,095352.792,2712.6511,S,15303.1137,E,1,06,02.3,5.8,M,42.2,M,,*7E +$GPGSA,A,3,05,07,12,21,24,30,,,,,,,4.8,2.3,4.2*3E +$GPGSV,3,1,12,2,15,123,33,5,45,347,41,6,58,198,42,7,45,212,41*70 +$GPGSV,3,2,12,10,44,132,42,12,39,002,40,18,14,332,25,21,34,265,39*75 +$GPGSV,3,3,12,24,58,220,41,26,17,054,39,29,20,063,40,30,59,312,43*7D +{"class":"SKY","tag":"GSV","xdop":1.56,"ydop":0.72,"vdop":3.47,"tdop":2.39,"hdop":1.71,"gdop":4.55,"pdop":3.87,"satellites":[{"PRN":2,"el":15,"az":123,"ss":33,"used":false},{"PRN":5,"el":45,"az":347,"ss":41,"used":true},{"PRN":6,"el":58,"az":198,"ss":42,"used":false},{"PRN":7,"el":45,"az":212,"ss":41,"used":true},{"PRN":10,"el":44,"az":132,"ss":42,"used":false},{"PRN":12,"el":39,"az":2,"ss":40,"used":true},{"PRN":18,"el":14,"az":332,"ss":25,"used":false},{"PRN":21,"el":34,"az":265,"ss":39,"used":true},{"PRN":24,"el":58,"az":220,"ss":41,"used":true},{"PRN":26,"el":17,"az":54,"ss":39,"used":false},{"PRN":29,"el":20,"az":63,"ss":40,"used":false},{"PRN":30,"el":59,"az":312,"ss":43,"used":true}]} +$GPRMC,095352.792,A,2712.6511,S,15303.1137,E,1.39,350.04,080407,,,A*70 +{"class":"TPV","tag":"RMC","time":1176026032.792,"ept":0.005,"lat":-27.210851667,"lon":153.051895000,"alt":5.800,"epx":15.734,"epy":10.717,"epv":44.819,"track":350.0400,"speed":0.715,"climb":-0.400,"eps":31.47,"mode":3} +$GPVTG,350.04,T,,,1.39,N,2.57,K,A*79 +$GPGGA,095353.791,2712.6505,S,15303.1137,E,1,06,02.3,5.9,M,42.2,M,,*78 +$GPRMC,095353.791,A,2712.6505,S,15303.1137,E,1.92,359.88,080407,,,A*7B +{"class":"TPV","tag":"RMC","time":1176026033.791,"ept":0.005,"lat":-27.210841667,"lon":153.051895000,"alt":5.900,"epx":23.360,"epy":10.770,"epv":79.875,"track":359.8800,"speed":0.988,"climb":0.100,"eps":39.13,"mode":3} +$GPVTG,359.88,T,,,1.92,N,3.56,K,A*75 +$GPGGA,095354.791,2712.6500,S,15303.1137,E,1,07,01.3,5.2,M,42.2,M,,*73 +$GPRMC,095354.791,A,2712.6500,S,15303.1137,E,2.00,11.44,080407,,,A*4E +{"class":"TPV","tag":"RMC","time":1176026034.791,"ept":0.005,"lat":-27.210833333,"lon":153.051895000,"alt":5.200,"epx":23.360,"epy":10.770,"epv":79.875,"track":11.4400,"speed":1.029,"climb":-0.700,"eps":46.72,"mode":3} +$GPVTG,11.44,T,,,2.00,N,3.70,K,A*46 +$GPGGA,095355.791,2712.6493,S,15303.1137,E,1,07,01.3,4.7,M,42.2,M,,*7D +$GPGSA,A,3,02,05,07,12,21,24,30,,,,,,3.0,1.3,2.7*33 +$GPGSV,3,1,12,2,15,123,34,5,45,347,42,6,58,198,42,7,45,212,41*74 +$GPGSV,3,2,12,10,44,132,42,12,39,002,41,18,14,332,26,21,34,265,41*78 +$GPGSV,3,3,12,24,58,220,43,26,17,054,40,29,20,063,38,30,59,312,44*79 +{"class":"SKY","tag":"GSV","xdop":1.05,"ydop":0.71,"vdop":1.95,"tdop":1.22,"hdop":1.27,"gdop":2.63,"pdop":2.33,"satellites":[{"PRN":2,"el":15,"az":123,"ss":34,"used":true},{"PRN":5,"el":45,"az":347,"ss":42,"used":true},{"PRN":6,"el":58,"az":198,"ss":42,"used":false},{"PRN":7,"el":45,"az":212,"ss":41,"used":true},{"PRN":10,"el":44,"az":132,"ss":42,"used":false},{"PRN":12,"el":39,"az":2,"ss":41,"used":true},{"PRN":18,"el":14,"az":332,"ss":26,"used":false},{"PRN":21,"el":34,"az":265,"ss":41,"used":true},{"PRN":24,"el":58,"az":220,"ss":43,"used":true},{"PRN":26,"el":17,"az":54,"ss":40,"used":false},{"PRN":29,"el":20,"az":63,"ss":38,"used":false},{"PRN":30,"el":59,"az":312,"ss":44,"used":true}]} +$GPRMC,095355.791,A,2712.6493,S,15303.1137,E,2.13,16.78,080407,,,A*4E +{"class":"TPV","tag":"RMC","time":1176026035.791,"ept":0.005,"lat":-27.210821667,"lon":153.051895000,"alt":4.700,"epx":23.360,"epy":10.770,"epv":79.875,"track":16.7800,"speed":1.096,"climb":-0.500,"eps":46.72,"mode":3} +$GPVTG,16.78,T,,,2.13,N,3.95,K,A*47 +$GPGGA,095356.791,2712.6487,S,15303.1136,E,1,07,01.3,4.3,M,42.2,M,,*7E +$GPRMC,095356.791,A,2712.6487,S,15303.1136,E,2.25,13.51,080407,,,A*42 +{"class":"TPV","tag":"RMC","time":1176026036.791,"ept":0.005,"lat":-27.210811667,"lon":153.051893333,"alt":4.300,"epx":15.734,"epy":10.717,"epv":44.819,"track":13.5100,"speed":1.157,"climb":-0.400,"eps":39.09,"mode":3} +$GPVTG,13.51,T,,,2.25,N,4.16,K,A*40 +$GPGGA,095357.791,2712.6480,S,15303.1135,E,1,07,01.3,4.1,M,42.2,M,,*79 +$GPRMC,095357.791,A,2712.6480,S,15303.1135,E,2.30,7.49,080407,,,A*7F +{"class":"TPV","tag":"RMC","time":1176026037.791,"ept":0.005,"lat":-27.210800000,"lon":153.051891667,"alt":4.100,"epx":15.734,"epy":10.717,"epv":44.819,"track":7.4900,"speed":1.183,"climb":-0.200,"eps":31.47,"mode":3} +$GPVTG,7.49,T,,,2.30,N,4.26,K,A*7B +$GPGGA,095358.790,2712.6473,S,15303.1133,E,1,08,01.1,3.9,M,42.2,M,,*7F +$GPGSA,A,3,02,05,07,10,12,21,24,30,,,,,2.6,1.1,2.4*34 +$GPGSV,3,1,12,2,15,123,36,5,45,347,43,6,58,198,42,7,45,212,41*77 +$GPGSV,3,2,12,10,43,132,41,12,39,002,41,18,14,332,26,21,34,265,42*7F +$GPGSV,3,3,12,24,58,219,43,26,17,054,38,29,20,063,37,30,59,312,44*73 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":0.66,"vdop":1.87,"tdop":1.13,"hdop":1.02,"gdop":2.41,"pdop":2.13,"satellites":[{"PRN":2,"el":15,"az":123,"ss":36,"used":true},{"PRN":5,"el":45,"az":347,"ss":43,"used":true},{"PRN":6,"el":58,"az":198,"ss":42,"used":false},{"PRN":7,"el":45,"az":212,"ss":41,"used":true},{"PRN":10,"el":43,"az":132,"ss":41,"used":true},{"PRN":12,"el":39,"az":2,"ss":41,"used":true},{"PRN":18,"el":14,"az":332,"ss":26,"used":false},{"PRN":21,"el":34,"az":265,"ss":42,"used":true},{"PRN":24,"el":58,"az":219,"ss":43,"used":true},{"PRN":26,"el":17,"az":54,"ss":38,"used":false},{"PRN":29,"el":20,"az":63,"ss":37,"used":false},{"PRN":30,"el":59,"az":312,"ss":44,"used":true}]} +$GPRMC,095358.790,A,2712.6473,S,15303.1133,E,2.34,6.73,080407,,,A*77 +{"class":"TPV","tag":"RMC","time":1176026038.790,"ept":0.005,"lat":-27.210788333,"lon":153.051888333,"alt":3.900,"epx":15.734,"epy":10.717,"epv":44.819,"track":6.7300,"speed":1.204,"climb":-0.200,"eps":31.50,"mode":3} +$GPVTG,6.73,T,,,2.34,N,4.32,K,A*72 +$GPGGA,095400.790,2712.6459,S,15303.1133,E,1,06,01.8,3.5,M,42.2,M,,*76 +$GPRMC,095400.790,A,2712.6459,S,15303.1133,E,2.40,7.80,080407,,,A*7B +{"class":"TPV","tag":"RMC","time":1176026040.790,"ept":0.005,"lat":-27.210765000,"lon":153.051888333,"alt":3.500,"epx":11.747,"epy":9.832,"epv":42.908,"track":7.8000,"speed":1.235,"climb":-0.200,"eps":13.74,"mode":3} +$GPVTG,7.80,T,,,2.40,N,4.44,K,A*7D +$GPGGA,095401.790,2712.6453,S,15303.1133,E,1,08,01.1,3.7,M,42.2,M,,*78 +$GPGSA,A,3,02,05,07,10,12,21,24,30,,,,,2.6,1.1,2.4*34 +$GPGSV,3,1,12,2,15,123,35,5,45,347,43,6,58,198,42,7,45,212,39*7B +$GPGSV,3,2,12,10,43,132,40,12,39,002,40,18,14,332,25,21,34,265,40*7E +$GPGSV,3,3,12,24,58,219,44,26,17,054,38,29,20,063,37,30,59,312,43*73 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":0.66,"vdop":1.87,"tdop":1.13,"hdop":1.02,"gdop":2.41,"pdop":2.13,"satellites":[{"PRN":2,"el":15,"az":123,"ss":35,"used":true},{"PRN":5,"el":45,"az":347,"ss":43,"used":true},{"PRN":6,"el":58,"az":198,"ss":42,"used":false},{"PRN":7,"el":45,"az":212,"ss":39,"used":true},{"PRN":10,"el":43,"az":132,"ss":40,"used":true},{"PRN":12,"el":39,"az":2,"ss":40,"used":true},{"PRN":18,"el":14,"az":332,"ss":25,"used":false},{"PRN":21,"el":34,"az":265,"ss":40,"used":true},{"PRN":24,"el":58,"az":219,"ss":44,"used":true},{"PRN":26,"el":17,"az":54,"ss":38,"used":false},{"PRN":29,"el":20,"az":63,"ss":37,"used":false},{"PRN":30,"el":59,"az":312,"ss":43,"used":true}]} +$GPRMC,095401.790,A,2712.6453,S,15303.1133,E,2.36,7.77,080407,,,A*79 +{"class":"TPV","tag":"RMC","time":1176026041.790,"ept":0.005,"lat":-27.210755000,"lon":153.051888333,"alt":3.700,"epx":11.747,"epy":9.832,"epv":42.908,"track":7.7700,"speed":1.214,"climb":0.200,"eps":23.49,"mode":3} +$GPVTG,7.77,T,,,2.36,N,4.37,K,A*70 +$GPGGA,095403.789,2712.6439,S,15303.1137,E,1,08,01.1,3.5,M,42.2,M,,*78 +$GPRMC,095403.789,A,2712.6439,S,15303.1137,E,2.48,15.66,080407,,,A*41 +{"class":"TPV","tag":"RMC","time":1176026043.789,"ept":0.005,"lat":-27.210731667,"lon":153.051895000,"alt":3.500,"epx":11.747,"epy":9.832,"epv":42.908,"track":15.6600,"speed":1.276,"climb":-0.100,"eps":11.75,"mode":3} +$GPVTG,15.66,T,,,2.48,N,4.59,K,A*42 +$GPGGA,095404.789,2712.6432,S,15303.1137,E,1,09,01.1,3.3,M,42.2,M,,*73 +$GPGSA,A,3,02,05,06,07,10,12,21,24,30,,,,2.5,1.1,2.2*37 +$GPGSV,3,1,12,2,15,123,33,5,45,347,44,6,58,197,42,7,45,212,41*7A +$GPGSV,3,2,12,10,43,132,39,12,39,002,41,18,14,332,25,21,34,265,39*7F +$GPGSV,3,3,12,24,58,219,45,26,17,054,38,29,20,063,38,30,59,312,43*7D +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":0.65,"vdop":1.78,"tdop":1.10,"hdop":1.01,"gdop":2.33,"pdop":2.05,"satellites":[{"PRN":2,"el":15,"az":123,"ss":33,"used":true},{"PRN":5,"el":45,"az":347,"ss":44,"used":true},{"PRN":6,"el":58,"az":197,"ss":42,"used":true},{"PRN":7,"el":45,"az":212,"ss":41,"used":true},{"PRN":10,"el":43,"az":132,"ss":39,"used":true},{"PRN":12,"el":39,"az":2,"ss":41,"used":true},{"PRN":18,"el":14,"az":332,"ss":25,"used":false},{"PRN":21,"el":34,"az":265,"ss":39,"used":true},{"PRN":24,"el":58,"az":219,"ss":45,"used":true},{"PRN":26,"el":17,"az":54,"ss":38,"used":false},{"PRN":29,"el":20,"az":63,"ss":38,"used":false},{"PRN":30,"el":59,"az":312,"ss":43,"used":true}]} +$GPRMC,095404.789,A,2712.6432,S,15303.1137,E,2.45,12.39,080407,,,A*4D +{"class":"TPV","tag":"RMC","time":1176026044.789,"ept":0.005,"lat":-27.210720000,"lon":153.051895000,"alt":3.300,"epx":11.747,"epy":9.832,"epv":42.908,"track":12.3900,"speed":1.260,"climb":-0.200,"eps":23.49,"mode":3} +$GPVTG,12.39,T,,,2.45,N,4.54,K,A*4F +$GPGGA,095405.789,2712.6425,S,15303.1138,E,1,09,01.1,3.1,M,42.2,M,,*79 +$GPRMC,095405.789,A,2712.6425,S,15303.1138,E,2.55,16.50,080407,,,A*4F +{"class":"TPV","tag":"RMC","time":1176026045.789,"ept":0.005,"lat":-27.210708333,"lon":153.051896667,"alt":3.100,"epx":11.626,"epy":9.703,"epv":40.965,"track":16.5000,"speed":1.312,"climb":-0.200,"eps":23.37,"mode":3} +$GPVTG,16.50,T,,,2.55,N,4.73,K,A*40 +$GPGGA,095406.789,2712.6420,S,15303.1142,E,1,09,01.1,2.7,M,42.2,M,,*75 +$GPRMC,095406.789,A,2712.6420,S,15303.1142,E,2.35,31.12,080407,,,A*41 +{"class":"TPV","tag":"RMC","time":1176026046.789,"ept":0.005,"lat":-27.210700000,"lon":153.051903333,"alt":2.700,"epx":11.626,"epy":9.703,"epv":40.965,"track":31.1200,"speed":1.209,"climb":-0.400,"eps":23.25,"mode":3} +$GPVTG,31.12,T,,,2.35,N,4.35,K,A*47 +$GPGGA,095407.788,2712.6415,S,15303.1145,E,1,08,01.7,2.5,M,42.2,M,,*71 +$GPGSA,A,3,02,05,06,07,10,12,24,30,,,,,3.9,1.7,3.4*38 +$GPGSV,3,1,12,2,14,123,33,5,45,347,43,6,58,197,42,7,45,212,41*7C +$GPGSV,3,2,12,10,43,132,42,12,39,002,40,18,14,332,28,21,34,265,36*70 +$GPGSV,3,3,12,24,58,219,43,26,17,054,38,29,20,063,39,30,59,312,43*7A +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":0.65,"vdop":1.83,"tdop":1.10,"hdop":1.02,"gdop":2.37,"pdop":2.10,"satellites":[{"PRN":2,"el":14,"az":123,"ss":33,"used":true},{"PRN":5,"el":45,"az":347,"ss":43,"used":true},{"PRN":6,"el":58,"az":197,"ss":42,"used":true},{"PRN":7,"el":45,"az":212,"ss":41,"used":true},{"PRN":10,"el":43,"az":132,"ss":42,"used":true},{"PRN":12,"el":39,"az":2,"ss":40,"used":true},{"PRN":18,"el":14,"az":332,"ss":28,"used":false},{"PRN":21,"el":34,"az":265,"ss":36,"used":false},{"PRN":24,"el":58,"az":219,"ss":43,"used":true},{"PRN":26,"el":17,"az":54,"ss":38,"used":false},{"PRN":29,"el":20,"az":63,"ss":39,"used":false},{"PRN":30,"el":59,"az":312,"ss":43,"used":true}]} +$GPRMC,095407.788,A,2712.6415,S,15303.1145,E,2.28,40.30,080407,,,A*4A +{"class":"TPV","tag":"RMC","time":1176026047.788,"ept":0.005,"lat":-27.210691667,"lon":153.051908333,"alt":2.500,"epx":11.626,"epy":9.703,"epv":40.965,"track":40.3000,"speed":1.173,"climb":-0.200,"eps":23.28,"mode":3} +$GPVTG,40.30,T,,,2.28,N,4.23,K,A*4A +$GPGGA,095408.788,2712.6411,S,15303.1151,E,1,09,01.1,2.6,M,42.2,M,,*7B +$GPRMC,095408.788,A,2712.6411,S,15303.1151,E,2.35,51.76,080407,,,A*4A +{"class":"TPV","tag":"RMC","time":1176026048.788,"ept":0.005,"lat":-27.210685000,"lon":153.051918333,"alt":2.600,"epx":11.782,"epy":9.803,"epv":42.197,"track":51.7600,"speed":1.209,"climb":0.100,"eps":23.41,"mode":3} +$GPVTG,51.76,T,,,2.35,N,4.35,K,A*43 +$GPGGA,095409.788,2712.6409,S,15303.1158,E,1,09,01.1,2.6,M,42.2,M,,*7A +$GPRMC,095409.788,A,2712.6409,S,15303.1158,E,2.41,68.20,080407,,,A*41 +{"class":"TPV","tag":"RMC","time":1176026049.788,"ept":0.005,"lat":-27.210681667,"lon":153.051930000,"alt":2.600,"epx":11.782,"epy":9.803,"epv":42.197,"track":68.2000,"speed":1.240,"climb":0.000,"eps":23.56,"mode":3} +$GPVTG,68.20,T,,,2.41,N,4.47,K,A*4C +$GPGGA,095410.788,2712.6407,S,15303.1166,E,1,09,01.1,2.9,M,42.2,M,,*7E +$GPGSA,A,3,02,05,06,07,10,12,21,24,30,,,,2.5,1.1,2.2*37 +$GPGSV,3,1,12,2,14,123,28,5,45,347,43,6,58,197,42,7,45,212,41*76 +$GPGSV,3,2,12,10,43,132,43,12,39,002,42,18,14,332,31,21,34,265,37*7A +$GPGSV,3,3,12,24,58,219,43,26,17,054,39,29,20,063,37,30,59,312,44*72 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":0.64,"vdop":1.75,"tdop":1.08,"hdop":1.01,"gdop":2.30,"pdop":2.02,"satellites":[{"PRN":2,"el":14,"az":123,"ss":28,"used":true},{"PRN":5,"el":45,"az":347,"ss":43,"used":true},{"PRN":6,"el":58,"az":197,"ss":42,"used":true},{"PRN":7,"el":45,"az":212,"ss":41,"used":true},{"PRN":10,"el":43,"az":132,"ss":43,"used":true},{"PRN":12,"el":39,"az":2,"ss":42,"used":true},{"PRN":18,"el":14,"az":332,"ss":31,"used":false},{"PRN":21,"el":34,"az":265,"ss":37,"used":true},{"PRN":24,"el":58,"az":219,"ss":43,"used":true},{"PRN":26,"el":17,"az":54,"ss":39,"used":false},{"PRN":29,"el":20,"az":63,"ss":37,"used":false},{"PRN":30,"el":59,"az":312,"ss":44,"used":true}]} +$GPRMC,095410.788,A,2712.6407,S,15303.1166,E,2.54,74.38,080407,,,A*4A +{"class":"TPV","tag":"RMC","time":1176026050.788,"ept":0.005,"lat":-27.210678333,"lon":153.051943333,"alt":2.900,"epx":11.782,"epy":9.803,"epv":42.197,"track":74.3800,"speed":1.307,"climb":0.300,"eps":23.56,"mode":3} +$GPVTG,74.38,T,,,2.54,N,4.71,K,A*49 +$GPGGA,095411.787,2712.6405,S,15303.1173,E,1,09,01.1,2.9,M,42.2,M,,*76 +$GPRMC,095411.787,A,2712.6405,S,15303.1173,E,2.34,76.68,080407,,,A*43 +{"class":"TPV","tag":"RMC","time":1176026051.787,"ept":0.005,"lat":-27.210675000,"lon":153.051955000,"alt":2.900,"epx":11.661,"epy":9.666,"epv":40.350,"track":76.6800,"speed":1.204,"climb":0.000,"eps":23.47,"mode":3} +$GPVTG,76.68,T,,,2.34,N,4.33,K,A*4E +$GPGGA,095412.787,2712.6404,S,15303.1180,E,1,09,01.1,3.0,M,42.2,M,,*70 +$GPRMC,095412.787,A,2712.6404,S,15303.1180,E,2.33,77.59,080407,,,A*49 +{"class":"TPV","tag":"RMC","time":1176026052.787,"ept":0.005,"lat":-27.210673333,"lon":153.051966667,"alt":3.000,"epx":11.661,"epy":9.666,"epv":40.350,"track":77.5900,"speed":1.199,"climb":0.100,"eps":23.32,"mode":3} +$GPVTG,77.59,T,,,2.33,N,4.32,K,A*4B +$GPGGA,095413.787,2712.6403,S,15303.1187,E,1,08,01.1,3.1,M,42.2,M,,*71 +$GPGSA,A,3,02,05,07,10,12,21,24,30,,,,,2.6,1.1,2.4*34 +$GPGSV,3,1,12,2,14,123,25,5,45,347,44,6,58,197,39,7,45,212,38*7E +$GPGSV,3,2,12,10,43,132,35,12,39,002,43,18,14,332,30,21,34,265,38*74 +$GPGSV,3,3,12,24,58,219,40,26,17,054,38,29,20,063,38,30,59,312,44*7F +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":0.65,"vdop":1.83,"tdop":1.10,"hdop":1.02,"gdop":2.37,"pdop":2.10,"satellites":[{"PRN":2,"el":14,"az":123,"ss":25,"used":true},{"PRN":5,"el":45,"az":347,"ss":44,"used":true},{"PRN":6,"el":58,"az":197,"ss":39,"used":false},{"PRN":7,"el":45,"az":212,"ss":38,"used":true},{"PRN":10,"el":43,"az":132,"ss":35,"used":true},{"PRN":12,"el":39,"az":2,"ss":43,"used":true},{"PRN":18,"el":14,"az":332,"ss":30,"used":false},{"PRN":21,"el":34,"az":265,"ss":38,"used":true},{"PRN":24,"el":58,"az":219,"ss":40,"used":true},{"PRN":26,"el":17,"az":54,"ss":38,"used":false},{"PRN":29,"el":20,"az":63,"ss":38,"used":false},{"PRN":30,"el":59,"az":312,"ss":44,"used":true}]} +$GPRMC,095413.787,A,2712.6403,S,15303.1187,E,2.47,79.51,080407,,,A*4D +{"class":"TPV","tag":"RMC","time":1176026053.787,"ept":0.005,"lat":-27.210671667,"lon":153.051978333,"alt":3.100,"epx":11.661,"epy":9.666,"epv":40.350,"track":79.5100,"speed":1.271,"climb":0.100,"eps":23.32,"mode":3} +$GPVTG,79.51,T,,,2.47,N,4.57,K,A*4D +$GPGGA,095414.787,2712.6403,S,15303.1194,E,1,09,01.1,3.2,M,42.2,M,,*76 +$GPRMC,095414.787,A,2712.6403,S,15303.1194,E,2.20,86.03,080407,,,A*4E +{"class":"TPV","tag":"RMC","time":1176026054.787,"ept":0.005,"lat":-27.210671667,"lon":153.051990000,"alt":3.200,"epx":11.782,"epy":9.803,"epv":42.197,"track":86.0300,"speed":1.132,"climb":0.100,"eps":23.44,"mode":3} +$GPVTG,86.03,T,,,2.20,N,4.07,K,A*4E +$GPGGA,095415.787,2712.6404,S,15303.1200,E,1,06,01.8,3.5,M,42.2,M,,*7F +$GPRMC,095415.787,A,2712.6404,S,15303.1200,E,2.11,96.86,080407,,,A*48 +{"class":"TPV","tag":"RMC","time":1176026055.787,"ept":0.005,"lat":-27.210673333,"lon":153.052000000,"alt":3.500,"epx":11.782,"epy":9.803,"epv":42.197,"track":96.8600,"speed":1.085,"climb":0.300,"eps":23.56,"mode":3} diff --git a/test/daemon/holux-gm-210.log b/test/daemon/holux-gm-210.log new file mode 100644 index 0000000..fd639d0 --- /dev/null +++ b/test/daemon/holux-gm-210.log @@ -0,0 +1,48 @@ +# Name: Holux GM-210 +# Chipset: SiRF-II +# Submitted-by: "Patrick L. McGillan" +# Date: 4 Apr 2005 +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGGA,012519.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*7D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,012519.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*14 +$GPGGA,012520.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*77 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,09,14,65,034,00,01,55,291,43,25,53,210,37,22,45,125,00*7E +$GPGSV,3,2,09,30,29,096,00,11,25,294,32,05,20,056,00,18,14,127,00*73 +$GPGSV,3,3,09,15,08,176,00*4C +$GPRMC,012520.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1E +$GPGGA,012521.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*76 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,012521.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1F +$GPGGA,012522.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*75 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,012522.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1C +$GPGGA,012523.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*74 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,012523.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1D +$GPGGA,012524.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,012524.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1A +$GPGGA,012525.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,09,14,65,034,00,01,55,291,43,25,53,210,37,22,45,125,00*7E +$GPGSV,3,2,09,30,29,096,00,11,25,294,32,05,20,056,00,18,14,127,00*73 +$GPGSV,3,3,09,15,08,176,00*4C +$GPRMC,012525.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1B +$GPGGA,012526.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,012526.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*18 +$GPGGA,012527.562,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,012527.562,V,4131.7353,N,09336.8150,W,0.00,,050405,,*18 +$GPGGA,012528.562,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*7E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,012528.562,V,4131.7353,N,09336.8150,W,0.00,,050405,,*17 +$GPGGA,012529.562,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*7F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,012529.562,V,4131.7353,N,09336.8150,W,0.00,,050405,,*16 +$GPGGA,012530.562,4131.7353,N,09336.8150,W,0,00,50. diff --git a/test/daemon/holux-gm-210.log.chk b/test/daemon/holux-gm-210.log.chk new file mode 100644 index 0000000..84905ba --- /dev/null +++ b/test/daemon/holux-gm-210.log.chk @@ -0,0 +1,53 @@ +$GPGGA,012519.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*7D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,012519.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*14 +$GPGGA,012520.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*77 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,09,14,65,034,00,01,55,291,43,25,53,210,37,22,45,125,00*7E +$GPGSV,3,2,09,30,29,096,00,11,25,294,32,05,20,056,00,18,14,127,00*73 +$GPGSV,3,3,09,15,08,176,00*4C +{"class":"SKY","tag":"GSV","satellites":[{"PRN":14,"el":65,"az":34,"ss":0,"used":false},{"PRN":1,"el":55,"az":291,"ss":43,"used":false},{"PRN":25,"el":53,"az":210,"ss":37,"used":false},{"PRN":22,"el":45,"az":125,"ss":0,"used":false},{"PRN":30,"el":29,"az":96,"ss":0,"used":false},{"PRN":11,"el":25,"az":294,"ss":32,"used":false},{"PRN":5,"el":20,"az":56,"ss":0,"used":false},{"PRN":18,"el":14,"az":127,"ss":0,"used":false},{"PRN":15,"el":8,"az":176,"ss":0,"used":false}]} +$GPRMC,012520.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1E +$GPGGA,012521.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*76 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,012521.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1F +$GPGGA,012522.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*75 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,012522.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1C +$GPGGA,012523.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*74 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,012523.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1D +$GPGGA,012524.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,012524.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1A +$GPGGA,012525.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,09,14,65,034,00,01,55,291,43,25,53,210,37,22,45,125,00*7E +$GPGSV,3,2,09,30,29,096,00,11,25,294,32,05,20,056,00,18,14,127,00*73 +$GPGSV,3,3,09,15,08,176,00*4C +{"class":"SKY","tag":"GSV","satellites":[{"PRN":14,"el":65,"az":34,"ss":0,"used":false},{"PRN":1,"el":55,"az":291,"ss":43,"used":false},{"PRN":25,"el":53,"az":210,"ss":37,"used":false},{"PRN":22,"el":45,"az":125,"ss":0,"used":false},{"PRN":30,"el":29,"az":96,"ss":0,"used":false},{"PRN":11,"el":25,"az":294,"ss":32,"used":false},{"PRN":5,"el":20,"az":56,"ss":0,"used":false},{"PRN":18,"el":14,"az":127,"ss":0,"used":false},{"PRN":15,"el":8,"az":176,"ss":0,"used":false}]} +$GPRMC,012525.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*1B +$GPGGA,012526.563,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,012526.563,V,4131.7353,N,09336.8150,W,0.00,,050405,,*18 +$GPGGA,012527.562,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,012527.562,V,4131.7353,N,09336.8150,W,0.00,,050405,,*18 +$GPGGA,012528.562,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*7E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,012528.562,V,4131.7353,N,09336.8150,W,0.00,,050405,,*17 +$GPGGA,012529.562,4131.7353,N,09336.8150,W,0,00,50.0,280.2,M,-31.6,M,0.0,0000*7F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,012529.562,V,4131.7353,N,09336.8150,W,0.00,,050405,,*16 +$GPGGA,012530.562,4131.7353,N,09336.8150,W,0,00,50. diff --git a/test/daemon/humminbird-M37.log b/test/daemon/humminbird-M37.log new file mode 100644 index 0000000..bb17675 --- /dev/null +++ b/test/daemon/humminbird-M37.log @@ -0,0 +1,1044 @@ +# Name: Humminbird Matrix 37 Fishing System, Humminbird GR16 Receiver +# Submitted-by: "Carl Brown" +# Date: 16 September 2006 +# Location: Connecticut River, New Hampshire, USA, 44N71W +# Comments: Powerboat track with NMEA depth (DPT) and water temperature (MTW) sentences +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$INDPT,2.2,0.0*47 +$INRMC,194101,A,4426.1130,N,07140.5596,W,5.2,77.3,160906,15.8,W*60 +$INDPT,2.1,0.0*44 +$INGLL,4426.1130,N,07140.5579,W,194102,A*2C +$INVTG,77.5,T,93.3,M,5.2,N,9.7,K*5B +$INMTW,17.9,C*1B +$INDPT,2.1,0.0*44 +$INRMC,194103,A,4426.1134,N,07140.5558,W,5.3,77.0,160906,15.8,W*66 +$INDPT,2.0,0.0*45 +$INGGA,194104,4426.1138,N,07140.5536,W,2,10,0.9,267.9,M,,,,*13 +$INZDA,194104,16,09,2006,-05,00*73 +$INMTW,17.9,C*1B +$INDPT,2.1,0.0*44 +$INRMC,194105,A,4426.1142,N,07140.5515,W,5.3,76.8,160906,15.8,W*61 +$INDPT,2.1,0.0*44 +$INGLL,4426.1146,N,07140.5499,W,194106,A*26 +$INVTG,76.3,T,92.1,M,5.3,N,9.7,K*5E +$INMTW,17.9,C*1B +$INDPT,2.2,0.0*47 +$INRMC,194107,A,4426.1149,N,07140.5477,W,5.3,76.6,160906,15.8,W*63 +$INDPT,2.1,0.0*44 +$INGGA,194108,4426.1149,N,07140.5455,W,2,10,0.9,268.0,M,,,,*1B +$INZDA,194108,16,09,2006,-05,00*7F +$INMTW,17.9,C*1B +$INDPT,2.2,0.0*47 +$INRMC,194109,A,4426.1153,N,07140.5439,W,5.2,76.5,160906,15.8,W*6E +$INDPT,2.3,0.0*46 +$INGLL,4426.1157,N,07140.5418,W,194110,A*28 +$INVTG,77.2,T,93.0,M,5.2,N,9.7,K*5F +$INMTW,17.9,C*1B +$INDPT,2.2,0.0*47 +$INRMC,194111,A,4426.1161,N,07140.5396,W,5.3,77.6,160906,15.8,W*67 +$INDPT,2.3,0.0*46 +$INGGA,194112,4426.1165,N,07140.5380,W,2,10,0.9,268.0,M,,,,*11 +$INZDA,194112,16,09,2006,-05,00*74 +$INMTW,17.9,C*1B +$INDPT,2.3,0.0*46 +$INRMC,194113,A,4426.1169,N,07140.5358,W,5.2,75.6,160906,15.8,W*6C +$INDPT,2.4,0.0*41 +$INGLL,4426.1173,N,07140.5337,W,194114,A*20 +$INVTG,76.0,T,91.8,M,5.2,N,9.6,K*57 +$INMTW,17.9,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194115,A,4426.1176,N,07140.5321,W,5.2,77.3,160906,15.8,W*6D +$INDPT,2.4,0.0*41 +$INGGA,194116,4426.1176,N,07140.5299,W,2,10,0.9,268.0,M,,,,*1E +$INZDA,194116,16,09,2006,-05,00*70 +$INMTW,18.0,C*1D +$INDPT,2.4,0.0*41 +$INRMC,194117,A,4426.1180,N,07140.5278,W,5.2,76.8,160906,15.8,W*61 +$INDPT,2.5,0.0*40 +$INGLL,4426.1184,N,07140.5261,W,194118,A*26 +$INVTG,76.4,T,92.2,M,5.2,N,9.7,K*5B +$INMTW,18.0,C*1D +$INDPT,2.6,0.0*43 +$INRMC,194119,A,4426.1188,N,07140.5240,W,5.2,77.5,160906,15.8,W*60 +$INDPT,2.4,0.0*41 +$INGGA,194120,4426.1192,N,07140.5218,W,2,10,0.9,268.2,M,,,,*1A +$INZDA,194120,16,09,2006,-05,00*75 +$INMTW,17.9,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194121,A,4426.1192,N,07140.5202,W,5.2,79.3,160906,15.8,W*6E +$INDPT,2.4,0.0*41 +$INGLL,4426.1196,N,07140.5181,W,194122,A*21 +$INVTG,78.6,T,94.4,M,5.3,N,9.7,K*56 +$INMTW,18.0,C*1D +$INDPT,2.4,0.0*41 +$INRMC,194123,A,4426.1200,N,07140.5159,W,5.2,79.0,160906,15.8,W*6A +$INDPT,2.4,0.0*41 +$INGGA,194124,4426.1200,N,07140.5143,W,2,10,0.9,268.2,M,,,,*1B +$INZDA,194124,16,09,2006,-05,00*71 +$INMTW,17.9,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194111,A,4426.1203,N,07140.5121,W,5.2,81.5,160906,15.8,W*65 +$INDPT,2.4,0.0*41 +$INGLL,4426.1203,N,07140.5100,W,194112,A*24 +$INVTG,81.4,T,97.2,M,5.2,N,9.6,K*57 +$INMTW,18.0,C*1D +$INDPT,2.3,0.0*46 +$INRMC,194113,A,4426.1207,N,07140.5084,W,5.2,81.9,160906,15.8,W*61 +$INDPT,2.3,0.0*46 +$INGGA,194114,4426.1211,N,07140.5062,W,2,10,0.9,268.4,M,,,,*1C +$INZDA,194114,16,09,2006,-05,00*72 +$INMTW,18.0,C*1D +$INDPT,2.4,0.0*41 +$INRMC,194115,A,4426.1211,N,07140.5040,W,5.2,83.9,160906,15.8,W*6A +$INDPT,2.4,0.0*41 +$INGLL,4426.1211,N,07140.5024,W,194116,A*24 +$INVTG,83.7,T,99.5,M,5.2,N,9.6,K*5F +$INMTW,18.1,C*1C +$INDPT,2.4,0.0*41 +$INRMC,194117,A,4426.1215,N,07140.5003,W,5.2,83.8,160906,15.8,W*6A +$INDPT,2.4,0.0*41 +$INGGA,194118,4426.1215,N,07140.4987,W,2,10,0.9,268.5,M,,,,*16 +$INZDA,194118,16,09,2006,-05,00*7E +$INMTW,18.0,C*1D +$INDPT,2.3,0.0*46 +$INRMC,194119,A,4426.1219,N,07140.4965,W,5.1,85.4,160906,15.8,W*69 +$INDPT,2.4,0.0*41 +$INGLL,4426.1219,N,07140.4943,W,194120,A*20 +$INVTG,85.6,T,101.4,M,5.2,N,9.5,K*6A +$INMTW,18.1,C*1C +$INDPT,2.4,0.0*41 +$INRMC,194121,A,4426.1219,N,07140.4927,W,5.2,85.5,160906,15.8,W*66 +$INDPT,2.5,0.0*40 +$INGGA,194122,4426.1223,N,07140.4906,W,2,10,0.9,268.4,M,,,,*12 +$INZDA,194122,16,09,2006,-05,00*77 +$INMTW,18.2,C*1F +$INDPT,2.4,0.0*41 +$INRMC,194123,A,4426.1223,N,07140.4884,W,5.1,86.8,160906,15.8,W*68 +$INDPT,2.4,0.0*41 +$INGLL,4426.1223,N,07140.4868,W,194124,A*25 +$INVTG,87.0,T,102.7,M,5.1,N,9.5,K*6D +$INMTW,18.2,C*1F +$INDPT,2.5,0.0*40 +$INRMC,194125,A,4426.1223,N,07140.4846,W,5.2,86.2,160906,15.8,W*69 +$INDPT,2.4,0.0*41 +$INGGA,194126,4426.1227,N,07140.4825,W,2,10,0.9,268.2,M,,,,*14 +$INZDA,194126,16,09,2006,-05,00*73 +$INMTW,18.1,C*1C +$INDPT,2.4,0.0*41 +$INRMC,194127,A,4426.1227,N,07140.4803,W,5.1,87.4,160906,15.8,W*6A +$INDPT,2.4,0.0*41 +$INGLL,4426.1227,N,07140.4787,W,194128,A*23 +$INVTG,88.3,T,104.1,M,5.1,N,9.5,K*61 +$INMTW,18.5,C*18 +$INDPT,2.4,0.0*41 +$INRMC,194129,A,4426.1227,N,07140.4766,W,5.2,87.6,160906,15.8,W*69 +$INDPT,2.4,0.0*41 +$INGGA,194130,4426.1227,N,07140.4744,W,2,10,0.9,268.0,M,,,,*19 +$INZDA,194130,16,09,2006,-05,00*74 +$INMTW,18.5,C*18 +$INDPT,2.4,0.0*41 +$INRMC,194131,A,4426.1230,N,07140.4728,W,5.1,86.6,160906,15.8,W*6E +$INDPT,2.4,0.0*41 +$INGLL,4426.1230,N,07140.4706,W,194132,A*27 +$INVTG,87.4,T,103.2,M,5.1,N,9.5,K*6D +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194133,A,4426.1230,N,07140.4685,W,5.1,88.1,160906,15.8,W*63 +$INDPT,2.4,0.0*41 +$INGGA,194134,4426.1230,N,07140.4669,W,2,10,0.9,267.8,M,,,,*12 +$INZDA,194134,16,09,2006,-05,00*70 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194135,A,4426.1230,N,07140.4647,W,5.2,87.5,160906,15.8,W*63 +$INDPT,2.5,0.0*40 +$INGLL,4426.1230,N,07140.4625,W,194136,A*23 +$INVTG,87.5,T,103.3,M,5.1,N,9.5,K*6D +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194137,A,4426.1230,N,07140.4609,W,5.1,87.9,160906,15.8,W*64 +$INDPT,2.5,0.0*40 +$INGGA,194138,4426.1230,N,07140.4588,W,2,09,0.9,267.7,M,,,,*15 +$INZDA,194138,16,09,2006,-05,00*7C +$INMTW,18.6,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194139,A,4426.1230,N,07140.4566,W,5.2,87.3,160906,15.8,W*69 +$INDPT,2.6,0.0*43 +$INGLL,4426.1234,N,07140.4545,W,194140,A*23 +$INVTG,87.4,T,103.2,M,5.2,N,9.6,K*6D +$INMTW,18.7,C*1A +$INDPT,2.6,0.0*43 +$INRMC,194141,A,4426.1234,N,07140.4528,W,5.1,88.0,160906,15.8,W*67 +$INDPT,2.6,0.0*43 +$INGGA,194142,4426.1234,N,07140.4507,W,2,10,0.9,267.5,M,,,,*11 +$INZDA,194142,16,09,2006,-05,00*71 +$INMTW,18.6,C*1B +$INDPT,2.7,0.0*42 +$INRMC,194143,A,4426.1234,N,07140.4485,W,5.1,88.3,160906,15.8,W*60 +$INDPT,2.7,0.0*42 +$INGLL,4426.1234,N,07140.4469,W,194144,A*28 +$INVTG,87.5,T,103.3,M,5.1,N,9.5,K*6D +$INMTW,18.7,C*1A +$INDPT,2.8,0.0*4D +$INRMC,194145,A,4426.1234,N,07140.4448,W,5.1,87.9,160906,15.8,W*62 +$INDPT,2.8,0.0*4D +$INGGA,194146,4426.1234,N,07140.4426,W,2,09,0.9,267.2,M,,,,*18 +$INZDA,194146,16,09,2006,-05,00*75 +$INMTW,18.7,C*1A +$INDPT,3.0,0.0*44 +$INRMC,194147,A,4426.1238,N,07140.4410,W,5.1,87.6,160906,15.8,W*6E +$INDPT,2.9,0.0*4C +$INGLL,4426.1238,N,07140.4388,W,194148,A*20 +$INVTG,87.0,T,102.7,M,5.2,N,9.5,K*6E +$INMTW,18.7,C*1A +$INDPT,2.9,0.0*4C +$INRMC,194149,A,4426.1238,N,07140.4367,W,5.1,87.2,160906,15.8,W*63 +$INDPT,3.0,0.0*44 +$INGGA,194150,4426.1238,N,07140.4351,W,2,10,0.9,267.0,M,,,,*1E +$INZDA,194150,16,09,2006,-05,00*72 +$INMTW,18.7,C*1A +$INDPT,3.0,0.0*44 +$INRMC,194151,A,4426.1238,N,07140.4329,W,5.1,88.3,160906,15.8,W*6E +$INDPT,2.9,0.0*4C +$INGLL,4426.1238,N,07140.4307,W,194152,A*2C +$INVTG,87.8,T,103.6,M,5.1,N,9.5,K*65 +$INMTW,18.7,C*1A +$INDPT,2.7,0.0*42 +$INRMC,194153,A,4426.1238,N,07140.4291,W,5.1,88.1,160906,15.8,W*6C +$INDPT,2.7,0.0*42 +$INGGA,194154,4426.1242,N,07140.4270,W,2,10,0.9,266.8,M,,,,*1C +$INZDA,194154,16,09,2006,-05,00*76 +$INMTW,18.8,C*15 +$INDPT,2.9,0.0*4C +$INRMC,194155,A,4426.1242,N,07140.4248,W,5.1,88.6,160906,15.8,W*64 +$INDPT,2.9,0.0*4C +$INGLL,4426.1242,N,07140.4232,W,194156,A*22 +$INVTG,88.8,T,104.6,M,5.1,N,9.4,K*6C +$INMTW,18.7,C*1A +$INDPT,3.0,0.0*44 +$INRMC,194157,A,4426.1242,N,07140.4210,W,5.1,88.2,160906,15.8,W*6F +$INDPT,3.0,0.0*44 +$INGGA,194158,4426.1242,N,07140.4189,W,2,09,0.9,266.6,M,,,,*13 +$INZDA,194158,16,09,2006,-05,00*7A +$INMTW,18.8,C*15 +$INDPT,3.1,0.0*45 +$INRMC,194159,A,4426.1242,N,07140.4173,W,5.1,88.9,160906,15.8,W*6C +$INDPT,3.3,0.0*47 +$INGLL,4426.1242,N,07140.4151,W,194200,A*24 +$INVTG,89.6,T,105.3,M,5.1,N,9.5,K*66 +$INMTW,18.6,C*1B +$INDPT,2.9,0.0*4C +$INRMC,194201,A,4426.1242,N,07140.4130,W,5.1,89.2,160906,15.8,W*6F +$INDPT,2.7,0.0*42 +$INGGA,194202,4426.1242,N,07140.4113,W,2,09,0.9,266.6,M,,,,*1C +$INZDA,194202,16,09,2006,-05,00*76 +$INMTW,18.8,C*15 +$INDPT,2.8,0.0*4D +$INRMC,194203,A,4426.1242,N,07140.4092,W,5.1,89.0,160906,15.8,W*66 +$INDPT,2.9,0.0*4C +$INGLL,4426.1242,N,07140.4070,W,194204,A*22 +$INVTG,89.6,T,105.4,M,5.1,N,9.5,K*61 +$INMTW,18.6,C*1B +$INDPT,3.0,0.0*44 +$INRMC,194205,A,4426.1242,N,07140.4054,W,5.1,89.9,160906,15.8,W*63 +$INDPT,3.0,0.0*44 +$INGGA,194206,4426.1242,N,07140.4033,W,2,10,0.9,266.5,M,,,,*10 +$INZDA,194206,16,09,2006,-05,00*72 +$INMTW,18.7,C*1A +$INDPT,3.1,0.0*45 +$INRMC,194207,A,4426.1242,N,07140.4011,W,5.1,88.4,160906,15.8,W*6C +$INDPT,3.1,0.0*45 +$INGLL,4426.1242,N,07140.3995,W,194208,A*2B +$INVTG,88.9,T,104.7,M,5.1,N,9.5,K*6D +$INMTW,18.7,C*1A +$INDPT,2.9,0.0*4C +$INRMC,194209,A,4426.1242,N,07140.3973,W,5.1,89.8,160906,15.8,W*65 +$INDPT,2.9,0.0*4C +$INGGA,194210,4426.1242,N,07140.3952,W,2,09,0.9,266.4,M,,,,*17 +$INZDA,194210,16,09,2006,-05,00*75 +$INMTW,18.6,C*1B +$INDPT,2.9,0.0*4C +$INRMC,194211,A,4426.1242,N,07140.3930,W,5.2,88.3,160906,15.8,W*62 +$INDPT,3.1,0.0*45 +$INGLL,4426.1242,N,07140.3914,W,194212,A*29 +$INVTG,88.6,T,104.4,M,5.2,N,9.6,K*61 +$INMTW,18.6,C*1B +$INDPT,3.1,0.0*45 +$INRMC,194213,A,4426.1242,N,07140.3892,W,5.1,89.2,160906,15.8,W*6A +$INDPT,3.1,0.0*45 +$INGGA,194214,4426.1242,N,07140.3871,W,2,09,0.9,266.3,M,,,,*14 +$INZDA,194214,16,09,2006,-05,00*71 +$INMTW,18.6,C*1B +$INDPT,3.0,0.0*44 +$INRMC,194215,A,4426.1242,N,07140.3849,W,5.2,88.0,160906,15.8,W*6A +$INDPT,3.2,0.0*46 +$INGLL,4426.1242,N,07140.3833,W,194216,A*29 +$INVTG,87.9,T,103.7,M,5.2,N,9.6,K*65 +$INMTW,18.6,C*1B +$INDPT,4.8,0.0*4B +$INRMC,194217,A,4426.1246,N,07140.3812,W,5.2,88.8,160906,15.8,W*6A +$INDPT,2.8,0.0*4D +$INGGA,194218,4426.1246,N,07140.3790,W,2,09,0.9,266.2,M,,,,*1D +$INZDA,194218,16,09,2006,-05,00*7D +$INMTW,18.6,C*1B +$INDPT,2.8,0.0*4D +$INRMC,194219,A,4426.1246,N,07140.3774,W,5.2,88.0,160906,15.8,W*63 +$INDPT,2.8,0.0*4D +$INGLL,4426.1246,N,07140.3752,W,194220,A*20 +$INVTG,87.4,T,103.1,M,5.2,N,9.6,K*6E +$INMTW,18.5,C*18 +$INDPT,2.7,0.0*42 +$INRMC,194221,A,4426.1246,N,07140.3731,W,5.1,87.9,160906,15.8,W*6C +$INDPT,2.7,0.0*42 +$INGGA,194222,4426.1246,N,07140.3715,W,2,09,0.9,266.1,M,,,,*1A +$INZDA,194222,16,09,2006,-05,00*74 +$INMTW,18.4,C*19 +$INDPT,2.6,0.0*43 +$INRMC,194223,A,4426.1246,N,07140.3693,W,5.1,88.4,160906,15.8,W*65 +$INDPT,2.6,0.0*43 +$INGLL,4426.1246,N,07140.3671,W,194224,A*24 +$INVTG,87.2,T,103.0,M,5.2,N,9.6,K*69 +$INMTW,18.5,C*18 +$INDPT,2.6,0.0*43 +$INRMC,194225,A,4426.1250,N,07140.3650,W,5.2,86.8,160906,15.8,W*6A +$INDPT,2.7,0.0*42 +$INGGA,194226,4426.1250,N,07140.3634,W,2,09,0.9,266.0,M,,,,*1A +$INZDA,194226,16,09,2006,-05,00*70 +$INMTW,18.4,C*19 +$INDPT,2.8,0.0*4D +$INRMC,194227,A,4426.1250,N,07140.3612,W,5.1,87.7,160906,15.8,W*63 +$INDPT,2.9,0.0*4C +$INGLL,4426.1250,N,07140.3591,W,194228,A*22 +$INVTG,87.4,T,103.2,M,5.1,N,9.5,K*6D +$INMTW,18.6,C*1B +$INDPT,3.0,0.0*44 +$INRMC,194229,A,4426.1250,N,07140.3569,W,5.2,87.0,160906,15.8,W*66 +$INDPT,2.7,0.0*42 +$INGGA,194230,4426.1250,N,07140.3553,W,2,09,0.9,265.9,M,,,,*15 +$INZDA,194230,16,09,2006,-05,00*77 +$INMTW,18.6,C*1B +$INDPT,2.6,0.0*43 +$INRMC,194231,A,4426.1254,N,07140.3531,W,5.1,87.8,160906,15.8,W*6D +$INDPT,2.6,0.0*43 +$INGLL,4426.1254,N,07140.3510,W,194232,A*24 +$INVTG,86.9,T,102.7,M,5.2,N,9.6,K*65 +$INMTW,18.6,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194233,A,4426.1254,N,07140.3494,W,5.2,86.7,160906,15.8,W*6C +$INDPT,2.5,0.0*40 +$INGGA,194234,4426.1254,N,07140.3472,W,2,09,0.9,265.8,M,,,,*16 +$INZDA,194234,16,09,2006,-05,00*73 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194235,A,4426.1254,N,07140.3450,W,5.2,87.4,160906,15.8,W*60 +$INDPT,2.4,0.0*41 +$INGLL,4426.1258,N,07140.3429,W,194236,A*27 +$INVTG,87.4,T,103.2,M,5.2,N,9.6,K*6D +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194237,A,4426.1258,N,07140.3413,W,5.2,86.6,160906,15.8,W*6A +$INDPT,2.5,0.0*40 +$INGGA,194238,4426.1258,N,07140.3391,W,2,09,0.9,265.7,M,,,,*13 +$INZDA,194238,16,09,2006,-05,00*7F +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194239,A,4426.1258,N,07140.3370,W,5.2,87.3,160906,15.8,W*62 +$INDPT,2.6,0.0*43 +$INGLL,4426.1258,N,07140.3353,W,194240,A*2C +$INVTG,88.0,T,103.8,M,5.2,N,9.6,K*6C +$INMTW,18.7,C*1A +$INDPT,2.6,0.0*43 +$INRMC,194241,A,4426.1261,N,07140.3332,W,5.2,87.7,160906,15.8,W*65 +$INDPT,2.7,0.0*42 +$INGGA,194242,4426.1261,N,07140.3310,W,2,09,0.9,265.5,M,,,,*1F +$INZDA,194242,16,09,2006,-05,00*72 +$INMTW,18.6,C*1B +$INDPT,2.6,0.0*43 +$INRMC,194243,A,4426.1261,N,07140.3289,W,5.2,88.0,160906,15.8,W*6E +$INDPT,2.5,0.0*40 +$INGLL,4426.1261,N,07140.3267,W,194244,A*24 +$INVTG,88.5,T,104.3,M,5.2,N,9.7,K*64 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194245,A,4426.1261,N,07140.3246,W,5.2,88.3,160906,15.8,W*68 +$INDPT,2.4,0.0*41 +$INGGA,194246,4426.1261,N,07140.3230,W,2,09,0.9,264.9,M,,,,*15 +$INZDA,194246,16,09,2006,-05,00*76 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194247,A,4426.1265,N,07140.3208,W,5.2,87.6,160906,15.8,W*6E +$INDPT,2.4,0.0*41 +$INGLL,4426.1265,N,07140.3186,W,194248,A*20 +$INVTG,88.1,T,103.9,M,5.2,N,9.6,K*6C +$INMTW,18.6,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194249,A,4426.1265,N,07140.3165,W,5.2,88.7,160906,15.8,W*66 +$INDPT,2.6,0.0*43 +$INGGA,194250,4426.1265,N,07140.3149,W,2,09,0.9,263.8,M,,,,*1D +$INZDA,194250,16,09,2006,-05,00*71 +$INMTW,18.6,C*1B +$INDPT,2.7,0.0*42 +$INRMC,194251,A,4426.1265,N,07140.3127,W,5.2,88.4,160906,15.8,W*6A +$INDPT,2.5,0.0*40 +$INGLL,4426.1265,N,07140.3106,W,194252,A*23 +$INVTG,87.8,T,103.5,M,5.2,N,9.7,K*67 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194253,A,4426.1265,N,07140.3089,W,5.2,88.3,160906,15.8,W*6A +$INDPT,2.4,0.0*41 +$INGGA,194254,4426.1265,N,07140.3068,W,2,09,0.9,262.8,M,,,,*1A +$INZDA,194254,16,09,2006,-05,00*75 +$INMTW,18.6,C*1B +$INDPT,2.3,0.0*46 +$INRMC,194255,A,4426.1265,N,07140.3046,W,5.2,89.0,160906,15.8,W*6D +$INDPT,2.2,0.0*47 +$INGLL,4426.1265,N,07140.3025,W,194256,A*27 +$INVTG,88.6,T,104.4,M,5.2,N,9.7,K*60 +$INMTW,18.6,C*1B +$INDPT,2.1,0.0*44 +$INRMC,194257,A,4426.1265,N,07140.3009,W,5.2,88.6,160906,15.8,W*63 +$INDPT,2.1,0.0*44 +$INGGA,194258,4426.1265,N,07140.2987,W,2,09,0.9,262.0,M,,,,*17 +$INZDA,194258,16,09,2006,-05,00*79 +$INMTW,18.6,C*1B +$INDPT,2.3,0.0*46 +$INRMC,194259,A,4426.1265,N,07140.2965,W,5.1,89.1,160906,15.8,W*6A +$INDPT,2.4,0.0*41 +$INGLL,4426.1265,N,07140.2944,W,194300,A*2A +$INVTG,89.3,T,105.1,M,5.2,N,9.5,K*62 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194301,A,4426.1269,N,07140.2922,W,5.2,89.7,160906,15.8,W*6C +$INDPT,2.4,0.0*41 +$INGGA,194302,4426.1269,N,07140.2901,W,2,09,0.9,261.3,M,,,,*1B +$INZDA,194302,16,09,2006,-05,00*77 +$INMTW,18.6,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194303,A,4426.1269,N,07140.2879,W,5.2,90.3,160906,15.8,W*6D +$INDPT,2.5,0.0*40 +$INGLL,4426.1265,N,07140.2863,W,194304,A*2A +$INVTG,91.4,T,107.2,M,5.2,N,9.7,K*6F +$INMTW,18.5,C*18 +$INDPT,2.4,0.0*41 +$INRMC,194304,A,4426.1265,N,07140.2863,W,5.2,91.4,160906,15.8,W*6B +$INDPT,2.4,0.0*41 +$INGGA,194306,4426.1265,N,07140.2820,W,2,09,0.9,261.0,M,,,,*12 +$INZDA,194306,16,09,2006,-05,00*73 +$INMTW,18.2,C*1F +$INDPT,2.5,0.0*40 +$INRMC,194306,A,4426.1265,N,07140.2820,W,5.2,88.5,160906,15.8,W*67 +$INDPT,1.9,0.0*4F +$INGLL,4426.1269,N,07140.2782,W,194308,A*2A +$INVTG,87.0,T,102.7,M,5.2,N,9.6,K*6D +$INMTW,18.5,C*18 +$INDPT,1.7,0.0*41 +$INRMC,194308,A,4426.1269,N,07140.2782,W,5.2,87.0,160906,15.8,W*68 +$INDPT,1.6,0.0*40 +$INGGA,194310,4426.1269,N,07140.2739,W,2,10,0.9,260.8,M,,,,*1F +$INZDA,194310,16,09,2006,-05,00*74 +$INMTW,18.6,C*1B +$INDPT,1.7,0.0*41 +$INRMC,194310,A,4426.1269,N,07140.2739,W,5.2,85.4,160906,15.8,W*67 +$INDPT,1.8,0.0*4E +$INGLL,4426.1273,N,07140.2701,W,194312,A*21 +$INVTG,83.4,T,99.2,M,5.2,N,9.6,K*5B +$INMTW,18.5,C*18 +$INDPT,2.0,0.0*45 +$INRMC,194312,A,4426.1273,N,07140.2701,W,5.1,83.4,160906,15.8,W*60 +$INDPT,1.9,0.0*4F +$INGGA,194314,4426.1277,N,07140.2664,W,2,09,0.9,260.7,M,,,,*1A +$INZDA,194314,16,09,2006,-05,00*70 +$INMTW,18.5,C*18 +$INDPT,1.7,0.0*41 +$INRMC,194314,A,4426.1277,N,07140.2664,W,5.2,84.5,160906,15.8,W*65 +$INDPT,1.6,0.0*40 +$INGLL,4426.1277,N,07140.2620,W,194316,A*23 +$INVTG,83.3,T,99.1,M,5.2,N,9.6,K*5F +$INMTW,18.6,C*1B +$INDPT,1.6,0.0*40 +$INRMC,194316,A,4426.1277,N,07140.2620,W,5.1,83.3,160906,15.8,W*65 +$INDPT,1.5,0.0*43 +$INGGA,194318,4426.1281,N,07140.2583,W,2,09,0.9,260.7,M,,,,*15 +$INZDA,194318,16,09,2006,-05,00*7C +$INMTW,18.5,C*18 +$INDPT,1.6,0.0*40 +$INRMC,194318,A,4426.1281,N,07140.2583,W,5.1,84.5,160906,15.8,W*69 +$INDPT,1.7,0.0*41 +$INGLL,4426.1285,N,07140.2545,W,194320,A*2B +$INVTG,84.3,T,100.1,M,5.2,N,9.5,K*6A +$INMTW,18.5,C*18 +$INDPT,1.7,0.0*41 +$INRMC,194320,A,4426.1285,N,07140.2545,W,5.1,84.3,160906,15.8,W*6A +$INDPT,1.7,0.0*41 +$INGGA,194322,4426.1288,N,07140.2502,W,2,10,0.9,260.6,M,,,,*15 +$INZDA,194322,16,09,2006,-05,00*75 +$INMTW,18.5,C*18 +$INDPT,1.8,0.0*4E +$INRMC,194322,A,4426.1288,N,07140.2502,W,5.1,84.7,160906,15.8,W*62 +$INDPT,2.0,0.0*45 +$INGLL,4426.1288,N,07140.2464,W,194324,A*20 +$INVTG,84.5,T,100.3,M,5.1,N,9.5,K*6D +$INMTW,18.5,C*18 +$INDPT,2.0,0.0*45 +$INRMC,194324,A,4426.1288,N,07140.2464,W,5.2,84.5,160906,15.8,W*64 +$INDPT,2.2,0.0*47 +$INGGA,194326,4426.1292,N,07140.2421,W,2,09,0.9,260.7,M,,,,*13 +$INZDA,194326,16,09,2006,-05,00*71 +$INMTW,18.4,C*19 +$INDPT,2.2,0.0*47 +$INRMC,194326,A,4426.1292,N,07140.2421,W,5.2,84.7,160906,15.8,W*6E +$INDPT,2.3,0.0*46 +$INGLL,4426.1296,N,07140.2383,W,194328,A*2D +$INVTG,84.7,T,100.5,M,5.2,N,9.7,K*68 +$INMTW,18.4,C*19 +$INDPT,2.3,0.0*46 +$INRMC,194328,A,4426.1296,N,07140.2383,W,5.2,84.7,160906,15.8,W*6B +$INDPT,2.5,0.0*40 +$INGGA,194330,4426.1300,N,07140.2346,W,2,09,0.9,260.7,M,,,,*18 +$INZDA,194330,16,09,2006,-05,00*76 +$INMTW,18.5,C*18 +$INDPT,2.6,0.0*43 +$INRMC,194330,A,4426.1300,N,07140.2346,W,5.2,84.3,160906,15.8,W*61 +$INDPT,2.7,0.0*42 +$INGLL,4426.1300,N,07140.2302,W,194332,A*21 +$INVTG,85.4,T,101.2,M,5.2,N,9.7,K*6C +$INMTW,18.5,C*18 +$INDPT,2.8,0.0*4D +$INRMC,194332,A,4426.1300,N,07140.2302,W,5.2,85.4,160906,15.8,W*65 +$INDPT,2.9,0.0*4C +$INGGA,194334,4426.1304,N,07140.2265,W,2,09,0.9,260.7,M,,,,*18 +$INZDA,194334,16,09,2006,-05,00*72 +$INMTW,18.3,C*1E +$INDPT,3.1,0.0*45 +$INRMC,194334,A,4426.1304,N,07140.2265,W,5.2,84.2,160906,15.8,W*60 +$INDPT,3.3,0.0*47 +$INGLL,4426.1308,N,07140.2222,W,194336,A*2E +$INVTG,84.3,T,100.1,M,5.2,N,9.7,K*68 +$INMTW,18.4,C*19 +$INDPT,3.3,0.0*47 +$INRMC,194336,A,4426.1308,N,07140.2222,W,5.2,84.3,160906,15.8,W*6C +$INDPT,3.6,0.0*42 +$INGGA,194338,4426.1308,N,07140.2179,W,2,09,0.9,260.6,M,,,,*17 +$INZDA,194338,16,09,2006,-05,00*7E +$INMTW,18.3,C*1E +$INDPT,3.7,0.0*43 +$INRMC,194338,A,4426.1308,N,07140.2179,W,5.3,85.1,160906,15.8,W*6D +$INDPT,3.5,0.0*41 +$INGLL,4426.1312,N,07140.2141,W,194340,A*22 +$INVTG,84.2,T,100.0,M,5.3,N,9.8,K*66 +$INMTW,18.3,C*1E +$INDPT,2.3,0.0*46 +$INRMC,194340,A,4426.1312,N,07140.2141,W,5.2,84.2,160906,15.8,W*61 +$INDPT,2.2,0.0*47 +$INGGA,194342,4426.1315,N,07140.2103,W,2,09,0.9,260.6,M,,,,*1B +$INZDA,194342,16,09,2006,-05,00*73 +$INMTW,18.2,C*1F +$INDPT,2.3,0.0*46 +$INRMC,194342,A,4426.1315,N,07140.2103,W,5.2,84.3,160906,15.8,W*63 +$INDPT,2.3,0.0*46 +$INGLL,4426.1315,N,07140.2060,W,194344,A*23 +$INVTG,84.4,T,100.2,M,5.2,N,9.6,K*6D +$INMTW,18.2,C*1F +$INDPT,2.4,0.0*41 +$INRMC,194344,A,4426.1315,N,07140.2060,W,5.1,84.4,160906,15.8,W*65 +$INDPT,2.6,0.0*43 +$INGGA,194346,4426.1319,N,07140.2022,W,2,09,0.9,260.7,M,,,,*10 +$INZDA,194346,16,09,2006,-05,00*77 +$INMTW,18.3,C*1E +$INDPT,2.7,0.0*42 +$INRMC,194346,A,4426.1319,N,07140.2022,W,5.2,84.2,160906,15.8,W*68 +$INDPT,2.1,0.0*44 +$INGLL,4426.1323,N,07140.1979,W,194348,A*28 +$INVTG,84.7,T,100.5,M,5.2,N,9.7,K*68 +$INMTW,18.3,C*1E +$INDPT,2.1,0.0*44 +$INRMC,194348,A,4426.1323,N,07140.1979,W,5.3,84.7,160906,15.8,W*6F +$INDPT,2.0,0.0*45 +$INGGA,194350,4426.1327,N,07140.1941,W,2,09,0.9,260.7,M,,,,*15 +$INZDA,194350,16,09,2006,-05,00*70 +$INMTW,18.4,C*19 +$INDPT,2.0,0.0*45 +$INRMC,194350,A,4426.1327,N,07140.1941,W,5.2,84.7,160906,15.8,W*68 +$INDPT,2.3,0.0*46 +$INGLL,4426.1327,N,07140.1898,W,194352,A*29 +$INVTG,85.0,T,100.8,M,5.2,N,9.6,K*62 +$INMTW,18.4,C*19 +$INDPT,2.2,0.0*47 +$INRMC,194352,A,4426.1327,N,07140.1898,W,5.2,85.0,160906,15.8,W*69 +$INDPT,2.1,0.0*44 +$INGGA,194354,4426.1331,N,07140.1861,W,2,09,0.9,260.6,M,,,,*14 +$INZDA,194354,16,09,2006,-05,00*74 +$INMTW,18.3,C*1E +$INDPT,2.1,0.0*44 +$INRMC,194354,A,4426.1331,N,07140.1861,W,5.2,81.5,160906,15.8,W*6F +$INDPT,2.1,0.0*44 +$INGLL,4426.1335,N,07140.1817,W,194356,A*29 +$INVTG,81.8,T,97.6,M,5.2,N,9.6,K*5F +$INMTW,18.4,C*19 +$INDPT,2.0,0.0*45 +$INRMC,194356,A,4426.1335,N,07140.1817,W,5.2,81.8,160906,15.8,W*65 +$INDPT,1.9,0.0*4F +$INGGA,194358,4426.1339,N,07140.1780,W,2,09,0.9,260.7,M,,,,*11 +$INZDA,194358,16,09,2006,-05,00*78 +$INMTW,18.4,C*19 +$INDPT,1.9,0.0*4F +$INRMC,194358,A,4426.1339,N,07140.1780,W,5.2,78.8,160906,15.8,W*60 +$INDPT,2.1,0.0*44 +$INGLL,4426.1346,N,07140.1737,W,194400,A*24 +$INVTG,79.6,T,95.4,M,5.2,N,9.6,K*56 +$INMTW,18.4,C*19 +$INDPT,2.1,0.0*44 +$INRMC,194400,A,4426.1346,N,07140.1737,W,5.2,79.6,160906,15.8,W*61 +$INDPT,2.1,0.0*44 +$INGGA,194402,4426.1350,N,07140.1699,W,2,09,0.9,260.9,M,,,,*11 +$INZDA,194402,16,09,2006,-05,00*70 +$INMTW,18.4,C*19 +$INDPT,2.1,0.0*44 +$INRMC,194402,A,4426.1350,N,07140.1699,W,5.2,75.8,160906,15.8,W*63 +$INDPT,2.3,0.0*46 +$INGLL,4426.1358,N,07140.1661,W,194404,A*2D +$INVTG,78.1,T,93.9,M,5.2,N,9.5,K*58 +$INMTW,18.3,C*1E +$INDPT,2.4,0.0*41 +$INRMC,194404,A,4426.1358,N,07140.1661,W,5.2,78.1,160906,15.8,W*6E +$INDPT,2.3,0.0*46 +$INGGA,194406,4426.1362,N,07140.1618,W,2,09,0.9,260.9,M,,,,*1D +$INZDA,194406,16,09,2006,-05,00*74 +$INMTW,18.3,C*1E +$INDPT,2.3,0.0*46 +$INRMC,194406,A,4426.1362,N,07140.1618,W,5.3,79.1,160906,15.8,W*6B +$INDPT,2.3,0.0*46 +$INGLL,4426.1370,N,07140.1580,W,194408,A*27 +$INVTG,78.7,T,94.5,M,5.3,N,9.8,K*59 +$INMTW,18.2,C*1F +$INDPT,2.1,0.0*44 +$INRMC,194408,A,4426.1370,N,07140.1580,W,5.2,78.7,160906,15.8,W*62 +$INDPT,2.0,0.0*45 +$INGGA,194410,4426.1373,N,07140.1537,W,2,09,0.9,261.1,M,,,,*1D +$INZDA,194410,16,09,2006,-05,00*73 +$INMTW,18.2,C*1F +$INDPT,2.0,0.0*45 +$INRMC,194410,A,4426.1373,N,07140.1537,W,5.2,80.2,160906,15.8,W*66 +$INDPT,2.0,0.0*45 +$INGLL,4426.1377,N,07140.1499,W,194412,A*22 +$INVTG,79.6,T,95.3,M,5.2,N,9.7,K*50 +$INMTW,18.1,C*1C +$INDPT,2.3,0.0*46 +$INRMC,194412,A,4426.1377,N,07140.1499,W,5.2,79.6,160906,15.8,W*67 +$INDPT,2.2,0.0*47 +$INGGA,194414,4426.1381,N,07140.1462,W,2,09,0.9,261.1,M,,,,*15 +$INZDA,194414,16,09,2006,-05,00*77 +$INMTW,18.2,C*1F +$INDPT,1.8,0.0*4E +$INRMC,194414,A,4426.1381,N,07140.1462,W,5.2,79.9,160906,15.8,W*63 +$INDPT,1.8,0.0*4E +$INGLL,4426.1389,N,07140.1419,W,194416,A*2F +$INVTG,80.2,T,96.0,M,5.2,N,9.7,K*52 +$INMTW,18.1,C*1C +$INDPT,1.8,0.0*4E +$INRMC,194416,A,4426.1389,N,07140.1419,W,5.2,80.2,160906,15.8,W*68 +$INDPT,2.0,0.0*45 +$INGGA,194418,4426.1393,N,07140.1381,W,2,10,0.9,261.1,M,,,,*18 +$INZDA,194418,16,09,2006,-05,00*7B +$INMTW,18.0,C*1D +$INDPT,2.1,0.0*44 +$INRMC,194418,A,4426.1393,N,07140.1381,W,5.2,81.2,160906,15.8,W*6A +$INDPT,2.3,0.0*46 +$INGLL,4426.1397,N,07140.1338,W,194420,A*21 +$INVTG,81.6,T,97.4,M,5.2,N,9.6,K*53 +$INMTW,18.1,C*1C +$INDPT,1.9,0.0*4F +$INRMC,194420,A,4426.1397,N,07140.1338,W,5.2,81.6,160906,15.8,W*63 +$INDPT,1.9,0.0*4F +$INGGA,194422,4426.1400,N,07140.1300,W,2,10,1.1,261.4,M,,,,*19 +$INZDA,194422,16,09,2006,-05,00*72 +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194422,A,4426.1400,N,07140.1300,W,5.2,80.4,160906,15.8,W*60 +$INDPT,1.9,0.0*4F +$INGLL,4426.1404,N,07140.1257,W,194424,A*20 +$INVTG,80.0,T,95.8,M,5.2,N,9.6,K*5A +$INMTW,18.0,C*1D +$INDPT,2.0,0.0*45 +$INRMC,194424,A,4426.1404,N,07140.1257,W,5.2,80.0,160906,15.8,W*65 +$INDPT,2.1,0.0*44 +$INGGA,194426,4426.1412,N,07140.1219,W,2,10,0.9,261.4,M,,,,*1E +$INZDA,194426,16,09,2006,-05,00*76 +$INMTW,17.9,C*1B +$INDPT,2.1,0.0*44 +$INRMC,194426,A,4426.1412,N,07140.1219,W,5.2,79.4,160906,15.8,W*68 +$INDPT,1.9,0.0*4F +$INGLL,4426.1416,N,07140.1181,W,194428,A*27 +$INVTG,78.2,T,93.9,M,5.2,N,9.7,K*59 +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194428,A,4426.1416,N,07140.1181,W,5.2,78.2,160906,15.8,W*67 +$INDPT,1.9,0.0*4F +$INGGA,194430,4426.1424,N,07140.1138,W,2,10,0.9,261.3,M,,,,*1B +$INZDA,194430,16,09,2006,-05,00*71 +$INMTW,17.9,C*1B +$INDPT,2.0,0.0*45 +$INRMC,194430,A,4426.1424,N,07140.1138,W,5.2,78.4,160906,15.8,W*6B +$INDPT,2.0,0.0*45 +$INGLL,4426.1431,N,07140.1101,W,194432,A*21 +$INVTG,76.1,T,91.8,M,5.2,N,9.7,K*57 +$INMTW,17.9,C*1B +$INDPT,2.1,0.0*44 +$INRMC,194432,A,4426.1431,N,07140.1101,W,5.2,76.1,160906,15.8,W*6C +$INDPT,2.1,0.0*44 +$INGGA,194434,4426.1435,N,07140.1063,W,2,10,0.9,261.5,M,,,,*16 +$INZDA,194434,16,09,2006,-05,00*75 +$INMTW,17.9,C*1B +$INDPT,2.2,0.0*47 +$INRMC,194434,A,4426.1435,N,07140.1063,W,5.2,75.9,160906,15.8,W*60 +$INDPT,2.1,0.0*44 +$INGLL,4426.1443,N,07140.1020,W,194436,A*22 +$INVTG,75.1,T,90.9,M,5.2,N,9.6,K*55 +$INMTW,18.0,C*1D +$INDPT,2.1,0.0*44 +$INRMC,194436,A,4426.1443,N,07140.1020,W,5.2,75.1,160906,15.8,W*6C +$INDPT,2.1,0.0*44 +$INGGA,194438,4426.1451,N,07140.0982,W,2,10,0.9,261.7,M,,,,*1D +$INZDA,194438,16,09,2006,-05,00*79 +$INMTW,17.9,C*1B +$INDPT,1.5,0.0*43 +$INRMC,194438,A,4426.1451,N,07140.0982,W,5.1,74.2,160906,15.8,W*60 +$INDPT,1.5,0.0*43 +$INGLL,4426.1458,N,07140.0944,W,194440,A*23 +$INVTG,73.9,T,89.7,M,5.1,N,9.5,K*5D +$INMTW,17.9,C*1B +$INDPT,1.5,0.0*43 +$INRMC,194440,A,4426.1458,N,07140.0944,W,5.2,73.9,160906,15.8,W*63 +$INDPT,1.5,0.0*43 +$INGGA,194442,4426.1466,N,07140.0907,W,2,09,1.1,261.7,M,,,,*18 +$INZDA,194442,16,09,2006,-05,00*74 +$INMTW,17.9,C*1B +$INDPT,1.5,0.0*43 +$INRMC,194442,A,4426.1466,N,07140.0907,W,5.1,73.5,160906,15.8,W*64 +$INDPT,1.5,0.0*43 +$INGLL,4426.1474,N,07140.0869,W,194444,A*27 +$INVTG,73.2,T,89.0,M,5.1,N,9.5,K*51 +$INMTW,17.9,C*1B +$INDPT,1.6,0.0*40 +$INRMC,194444,A,4426.1474,N,07140.0869,W,5.1,73.2,160906,15.8,W*6F +$INDPT,1.7,0.0*41 +$INGGA,194446,4426.1482,N,07140.0831,W,2,10,1.1,261.8,M,,,,*15 +$INZDA,194446,16,09,2006,-05,00*70 +$INMTW,17.8,C*1A +$INDPT,1.6,0.0*40 +$INRMC,194446,A,4426.1482,N,07140.0831,W,5.1,71.7,160906,15.8,W*6E +$INDPT,1.7,0.0*41 +$INGLL,4426.1493,N,07140.0793,W,194448,A*28 +$INVTG,72.0,T,87.8,M,5.1,N,9.5,K*54 +$INMTW,17.9,C*1B +$INDPT,1.8,0.0*4E +$INRMC,194448,A,4426.1493,N,07140.0793,W,5.2,72.0,160906,15.8,W*60 +$INDPT,1.8,0.0*4E +$INGGA,194450,4426.1501,N,07140.0756,W,2,10,1.1,261.9,M,,,,*17 +$INZDA,194450,16,09,2006,-05,00*77 +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194450,A,4426.1501,N,07140.0756,W,5.2,70.4,160906,15.8,W*6C +$INDPT,1.8,0.0*4E +$INGLL,4426.1512,N,07140.0718,W,194452,A*28 +$INVTG,70.7,T,86.5,M,5.2,N,9.6,K*5D +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194452,A,4426.1512,N,07140.0718,W,5.2,70.7,160906,15.8,W*65 +$INDPT,1.8,0.0*4E +$INGGA,194454,4426.1520,N,07140.0680,W,2,11,0.9,261.9,M,,,,*12 +$INZDA,194454,16,09,2006,-05,00*73 +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194454,A,4426.1520,N,07140.0680,W,5.3,69.4,160906,15.8,W*68 +$INDPT,2.0,0.0*45 +$INGLL,4426.1532,N,07140.0642,W,194456,A*20 +$INVTG,68.7,T,84.5,M,5.3,N,9.7,K*56 +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194456,A,4426.1532,N,07140.0642,W,5.2,68.7,160906,15.8,W*64 +$INDPT,1.8,0.0*4E +$INGGA,194458,4426.1543,N,07140.0605,W,2,10,1.1,262.0,M,,,,*14 +$INZDA,194458,16,09,2006,-05,00*7F +$INMTW,17.9,C*1B +$INDPT,1.8,0.0*4E +$INRMC,194458,A,4426.1543,N,07140.0605,W,5.3,68.4,160906,15.8,W*6D +$INDPT,1.9,0.0*4F +$INGLL,4426.1555,N,07140.0567,W,194500,A*27 +$INVTG,67.8,T,83.6,M,5.3,N,9.8,K*5D +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194500,A,4426.1555,N,07140.0567,W,5.2,67.8,160906,15.8,W*63 +$INDPT,1.9,0.0*4F +$INGGA,194502,4426.1563,N,07140.0529,W,2,10,1.1,262.0,M,,,,*15 +$INZDA,194502,16,09,2006,-05,00*71 +$INMTW,17.8,C*1A +$INDPT,1.9,0.0*4F +$INRMC,194502,A,4426.1563,N,07140.0529,W,5.2,68.6,160906,15.8,W*6F +$INDPT,1.9,0.0*4F +$INGLL,4426.1574,N,07140.0492,W,194504,A*2B +$INVTG,67.6,T,83.4,M,5.2,N,9.7,K*5F +$INMTW,17.8,C*1A +$INDPT,1.9,0.0*4F +$INRMC,194504,A,4426.1574,N,07140.0492,W,5.2,67.6,160906,15.8,W*61 +$INDPT,1.8,0.0*4E +$INGGA,194506,4426.1586,N,07140.0454,W,2,10,1.1,261.9,M,,,,*1B +$INZDA,194506,16,09,2006,-05,00*75 +$INMTW,17.7,C*15 +$INDPT,1.8,0.0*4E +$INRMC,194506,A,4426.1586,N,07140.0454,W,5.3,68.6,160906,15.8,W*6A +$INDPT,1.8,0.0*4E +$INGLL,4426.1597,N,07140.0416,W,194508,A*26 +$INVTG,68.2,T,84.0,M,5.3,N,9.7,K*56 +$INMTW,17.8,C*1A +$INDPT,1.9,0.0*4F +$INRMC,194508,A,4426.1597,N,07140.0416,W,5.2,68.2,160906,15.8,W*67 +$INDPT,1.9,0.0*4F +$INGGA,194510,4426.1609,N,07140.0378,W,2,10,1.1,262.0,M,,,,*1B +$INZDA,194510,16,09,2006,-05,00*72 +$INMTW,17.9,C*1B +$INDPT,1.6,0.0*40 +$INRMC,194510,A,4426.1609,N,07140.0378,W,5.2,68.1,160906,15.8,W*66 +$INDPT,1.6,0.0*40 +$INGLL,4426.1617,N,07140.0341,W,194512,A*23 +$INVTG,68.0,T,83.8,M,5.2,N,9.7,K*5A +$INMTW,17.8,C*1A +$INDPT,1.7,0.0*41 +$INRMC,194512,A,4426.1617,N,07140.0341,W,5.2,68.0,160906,15.8,W*60 +$INDPT,1.7,0.0*41 +$INGGA,194514,4426.1628,N,07140.0303,W,2,10,1.1,262.0,M,,,,*10 +$INZDA,194514,16,09,2006,-05,00*76 +$INMTW,17.8,C*1A +$INDPT,1.8,0.0*4E +$INRMC,194514,A,4426.1628,N,07140.0303,W,5.2,67.6,160906,15.8,W*65 +$INDPT,1.9,0.0*4F +$INGLL,4426.1636,N,07140.0281,W,194515,A*2A +$INVTG,67.5,T,83.3,M,5.2,N,9.6,K*5A +$INMTW,17.9,C*1B +$INDPT,1.6,0.0*40 +$INRMC,194516,A,4426.1640,N,07140.0265,W,5.2,68.1,160906,15.8,W*60 +$INDPT,1.6,0.0*40 +$INGGA,194517,4426.1644,N,07140.0244,W,2,10,1.1,262.0,M,,,,*1B +$INZDA,194517,16,09,2006,-05,00*75 +$INMTW,17.7,C*15 +$INDPT,1.6,0.0*40 +$INRMC,194518,A,4426.1651,N,07140.0227,W,5.2,69.2,160906,15.8,W*6A +$INDPT,1.6,0.0*40 +$INGLL,4426.1655,N,07140.0206,W,194519,A*2C +$INVTG,69.0,T,84.8,M,5.2,N,9.7,K*5C +$INMTW,17.9,C*1B +$INDPT,1.7,0.0*41 +$INRMC,194520,A,4426.1663,N,07140.0190,W,5.2,68.6,160906,15.8,W*6A +$INDPT,1.7,0.0*41 +$INGGA,194521,4426.1667,N,07140.0168,W,2,10,1.1,261.9,M,,,,*18 +$INZDA,194521,16,09,2006,-05,00*70 +$INMTW,17.9,C*1B +$INDPT,1.8,0.0*4E +$INRMC,194522,A,4426.1671,N,07140.0152,W,5.2,69.5,160906,15.8,W*67 +$INDPT,1.6,0.0*40 +$INGLL,4426.1678,N,07140.0136,W,194523,A*2A +$INVTG,69.4,T,85.2,M,5.2,N,9.6,K*52 +$INMTW,17.9,C*1B +$INDPT,1.5,0.0*43 +$INRMC,194524,A,4426.1682,N,07140.0114,W,5.2,68.7,160906,15.8,W*6C +$INDPT,1.6,0.0*40 +$INGGA,194525,4426.1686,N,07140.0098,W,2,10,1.1,261.8,M,,,,*1C +$INZDA,194525,16,09,2006,-05,00*74 +$INMTW,17.9,C*1B +$INDPT,1.7,0.0*41 +$INRMC,194526,A,4426.1694,N,07140.0077,W,5.1,69.4,160906,15.8,W*6C +$INDPT,1.9,0.0*4F +$INGLL,4426.1698,N,07140.0060,W,194527,A*22 +$INVTG,70.2,T,86.0,M,5.1,N,9.5,K*5D +$INMTW,17.8,C*1A +$INDPT,1.9,0.0*4F +$INRMC,194528,A,4426.1702,N,07140.0039,W,5.2,70.5,160906,15.8,W*6C +$INDPT,1.4,0.0*42 +$INGGA,194529,4426.1705,N,07140.0023,W,2,11,0.9,261.8,M,,,,*12 +$INZDA,194529,16,09,2006,-05,00*78 +$INMTW,17.8,C*1A +$INDPT,1.3,0.0*45 +$INRMC,194530,A,4426.1713,N,07140.0001,W,5.2,69.8,160906,15.8,W*6B +$INDPT,1.3,0.0*45 +$INGLL,4426.1717,N,07139.9985,W,194531,A*26 +$INVTG,70.1,T,85.8,M,5.2,N,9.6,K*55 +$INMTW,17.6,C*14 +$INDPT,1.4,0.0*42 +$INRMC,194532,A,4426.1721,N,07139.9963,W,5.1,71.0,160906,15.8,W*60 +$INDPT,1.4,0.0*42 +$INGGA,194533,4426.1725,N,07139.9947,W,2,11,0.9,261.6,M,,,,*19 +$INZDA,194533,16,09,2006,-05,00*73 +$INMTW,17.6,C*14 +$INDPT,1.4,0.0*42 +$INRMC,194534,A,4426.1729,N,07139.9926,W,5.1,71.6,160906,15.8,W*69 +$INDPT,1.5,0.0*43 +$INGLL,4426.1736,N,07139.9909,W,194535,A*25 +$INVTG,71.0,T,86.8,M,5.1,N,9.5,K*56 +$INMTW,17.6,C*14 +$INDPT,1.5,0.0*43 +$INRMC,194536,A,4426.1740,N,07139.9888,W,5.1,70.9,160906,15.8,W*6F +$INDPT,1.5,0.0*43 +$INGGA,194537,4426.1744,N,07139.9872,W,2,11,0.9,261.6,M,,,,*1D +$INZDA,194537,16,09,2006,-05,00*77 +$INMTW,17.6,C*14 +$INDPT,1.6,0.0*40 +$INRMC,194538,A,4426.1748,N,07139.9850,W,5.2,73.3,160906,15.8,W*66 +$INDPT,1.8,0.0*4E +$INGLL,4426.1752,N,07139.9834,W,194539,A*24 +$INVTG,71.8,T,87.6,M,5.2,N,9.7,K*50 +$INMTW,17.5,C*17 +$INDPT,1.9,0.0*4F +$INRMC,194540,A,4426.1756,N,07139.9812,W,5.3,69.1,160906,15.8,W*68 +$INDPT,1.9,0.0*4F +$INGGA,194541,4426.1763,N,07139.9796,W,2,11,0.9,261.5,M,,,,*1F +$INZDA,194541,16,09,2006,-05,00*76 +$INMTW,17.6,C*14 +$INDPT,1.4,0.0*42 +$INRMC,194542,A,4426.1767,N,07139.9775,W,5.2,67.7,160906,15.8,W*6F +$INDPT,1.5,0.0*43 +$INGLL,4426.1775,N,07139.9759,W,194543,A*28 +$INVTG,67.9,T,83.7,M,5.2,N,9.6,K*52 +$INMTW,17.5,C*17 +$INDPT,1.6,0.0*40 +$INRMC,194544,A,4426.1779,N,07139.9737,W,5.2,67.3,160906,15.8,W*64 +$INDPT,1.7,0.0*41 +$INGGA,194545,4426.1787,N,07139.9721,W,2,11,0.9,261.3,M,,,,*1B +$INZDA,194545,16,09,2006,-05,00*72 +$INMTW,17.5,C*17 +$INDPT,1.7,0.0*41 +$INRMC,194546,A,4426.1790,N,07139.9705,W,5.1,65.9,160906,15.8,W*6B +$INDPT,1.7,0.0*41 +$INGLL,4426.1798,N,07139.9683,W,194547,A*29 +$INVTG,65.6,T,81.4,M,5.1,N,9.5,K*5E +$INMTW,17.5,C*17 +$INDPT,1.8,0.0*4E +$INRMC,194548,A,4426.1802,N,07139.9667,W,5.2,64.8,160906,15.8,W*67 +$INDPT,1.9,0.0*4F +$INGGA,194549,4426.1810,N,07139.9651,W,2,11,0.9,261.3,M,,,,*10 +$INZDA,194549,16,09,2006,-05,00*7E +$INMTW,17.5,C*17 +$INDPT,1.7,0.0*41 +$INRMC,194550,A,4426.1817,N,07139.9629,W,5.2,63.6,160906,15.8,W*69 +$INDPT,1.7,0.0*41 +$INGLL,4426.1825,N,07139.9613,W,194551,A*2E +$INVTG,63.3,T,79.1,M,5.2,N,9.7,K*5E +$INMTW,17.5,C*17 +$INDPT,1.6,0.0*40 +$INRMC,194552,A,4426.1829,N,07139.9597,W,5.2,62.8,160906,15.8,W*6F +$INDPT,1.6,0.0*40 +$INGGA,194553,4426.1837,N,07139.9575,W,2,11,0.9,261.2,M,,,,*1A +$INZDA,194553,16,09,2006,-05,00*75 +$INMTW,17.5,C*17 +$INDPT,1.7,0.0*41 +$INRMC,194554,A,4426.1844,N,07139.9559,W,5.2,61.3,160906,15.8,W*68 +$INDPT,1.8,0.0*4E +$INGLL,4426.1852,N,07139.9543,W,194555,A*2C +$INVTG,61.6,T,77.4,M,5.1,N,9.5,K*53 +$INMTW,17.4,C*16 +$INDPT,1.8,0.0*4E +$INRMC,194556,A,4426.1860,N,07139.9527,W,5.1,62.3,160906,15.8,W*65 +$INDPT,1.9,0.0*4F +$INGGA,194557,4426.1864,N,07139.9505,W,2,11,0.9,261.1,M,,,,*1C +$INZDA,194557,16,09,2006,-05,00*71 +$INMTW,17.5,C*17 +$INDPT,2.0,0.0*45 +$INRMC,194558,A,4426.1872,N,07139.9489,W,5.2,62.5,160906,15.8,W*68 +$INDPT,2.0,0.0*45 +$INGLL,4426.1879,N,07139.9473,W,194559,A*2B +$INVTG,61.9,T,77.7,M,5.2,N,9.7,K*5E +$INMTW,17.6,C*14 +$INDPT,1.6,0.0*40 +$INRMC,194600,A,4426.1887,N,07139.9451,W,5.2,61.4,160906,15.8,W*6B +$INDPT,1.6,0.0*40 +$INGGA,194601,4426.1895,N,07139.9435,W,2,11,0.9,261.1,M,,,,*10 +$INZDA,194601,16,09,2006,-05,00*71 +$INMTW,17.5,C*17 +$INDPT,1.7,0.0*41 +$INRMC,194602,A,4426.1899,N,07139.9419,W,5.2,62.4,160906,15.8,W*69 +$INDPT,1.6,0.0*40 +$INGLL,4426.1906,N,07139.9403,W,194603,A*29 +$INVTG,62.3,T,78.1,M,5.1,N,9.5,K*5F +$INMTW,17.5,C*17 +$INDPT,1.6,0.0*40 +$INRMC,194604,A,4426.1914,N,07139.9387,W,5.1,61.9,160906,15.8,W*66 +$INDPT,1.6,0.0*40 +$INGGA,194605,4426.1922,N,07139.9365,W,2,11,0.9,261.0,M,,,,*1A +$INZDA,194605,16,09,2006,-05,00*75 +$INMTW,17.6,C*14 +$INDPT,1.7,0.0*41 +$INRMC,194606,A,4426.1926,N,07139.9349,W,5.1,62.0,160906,15.8,W*6D +$INDPT,1.7,0.0*41 +$INGLL,4426.1933,N,07139.9333,W,194607,A*2F +$INVTG,62.6,T,78.4,M,5.1,N,9.5,K*5F +$INMTW,17.6,C*14 +$INDPT,1.7,0.0*41 +$INRMC,194608,A,4426.1941,N,07139.9311,W,5.2,62.6,160906,15.8,W*6A +$INDPT,1.7,0.0*41 +$INGGA,194609,4426.1949,N,07139.9295,W,2,11,0.9,260.9,M,,,,*1D +$INZDA,194609,16,09,2006,-05,00*79 +$INMTW,17.5,C*17 +$INDPT,1.8,0.0*4E +$INRMC,194610,A,4426.1953,N,07139.9279,W,5.1,62.0,160906,15.8,W*6A +$INDPT,1.8,0.0*4E +$INGLL,4426.1960,N,07139.9263,W,194611,A*2A +$INVTG,62.3,T,78.1,M,5.1,N,9.5,K*5F +$INMTW,17.4,C*16 +$INDPT,1.9,0.0*4F +$INRMC,194612,A,4426.1968,N,07139.9241,W,5.1,62.3,160906,15.8,W*68 +$INDPT,1.8,0.0*4E +$INGGA,194613,4426.1976,N,07139.9225,W,2,11,0.9,260.9,M,,,,*11 +$INZDA,194613,16,09,2006,-05,00*72 +$INMTW,17.4,C*16 +$INDPT,1.9,0.0*4F +$INRMC,194614,A,4426.1980,N,07139.9209,W,5.2,63.0,160906,15.8,W*65 +$INDPT,2.0,0.0*45 +$INGLL,4426.1987,N,07139.9187,W,194615,A*2E +$INVTG,63.2,T,79.0,M,5.2,N,9.6,K*5F +$INMTW,17.4,C*16 +$INDPT,1.6,0.0*40 +$INRMC,194616,A,4426.1995,N,07139.9171,W,5.1,63.3,160906,15.8,W*6F +$INDPT,1.7,0.0*41 +$INGGA,194617,4426.1999,N,07139.9155,W,2,11,0.9,260.8,M,,,,*11 +$INZDA,194617,16,09,2006,-05,00*76 +$INMTW,17.4,C*16 +$INDPT,1.8,0.0*4E +$INRMC,194618,A,4426.2007,N,07139.9139,W,5.2,62.6,160906,15.8,W*6B +$INDPT,1.9,0.0*4F +$INGLL,4426.2014,N,07139.9117,W,194619,A*2B +$INVTG,63.1,T,78.9,M,5.1,N,9.5,K*54 +$INMTW,17.2,C*10 +$INDPT,1.6,0.0*40 +$INRMC,194620,A,4426.2018,N,07139.9101,W,5.1,62.8,160906,15.8,W*68 +$INDPT,1.7,0.0*41 +$INGGA,194621,4426.2026,N,07139.9085,W,2,11,0.9,260.8,M,,,,*16 +$INZDA,194621,16,09,2006,-05,00*73 +$INMTW,17.4,C*16 +$INDPT,1.8,0.0*4E +$INRMC,194622,A,4426.2034,N,07139.9063,W,5.2,62.6,160906,15.8,W*6C +$INDPT,1.9,0.0*4F +$INGLL,4426.2038,N,07139.9047,W,194623,A*28 +$INVTG,62.5,T,78.2,M,5.2,N,9.6,K*5A +$INMTW,17.4,C*16 +$INDPT,1.7,0.0*41 +$INRMC,194624,A,4426.2045,N,07139.9031,W,5.2,62.5,160906,15.8,W*68 +$INDPT,1.6,0.0*40 +$INGGA,194625,4426.2053,N,07139.9009,W,2,11,0.9,260.8,M,,,,*14 +$INZDA,194625,16,09,2006,-05,00*77 +$INMTW,17.4,C*16 +$INDPT,1.7,0.0*41 +$INRMC,194626,A,4426.2061,N,07139.8993,W,5.1,61.5,160906,15.8,W*6C +$INDPT,1.7,0.0*41 +$INGLL,4426.2068,N,07139.8977,W,194627,A*22 +$INVTG,61.6,T,77.4,M,5.2,N,9.6,K*53 +$INMTW,17.4,C*16 +$INDPT,1.7,0.0*41 +$INRMC,194628,A,4426.2072,N,07139.8961,W,5.1,62.2,160906,15.8,W*69 +$INDPT,1.7,0.0*41 +$INGGA,194629,4426.2080,N,07139.8945,W,2,11,0.9,260.5,M,,,,*1B +$INZDA,194629,16,09,2006,-05,00*7B +$INMTW,17.3,C*11 +$INDPT,1.9,0.0*4F +$INRMC,194630,A,4426.2088,N,07139.8923,W,5.2,62.2,160906,15.8,W*60 +$INDPT,1.9,0.0*4F diff --git a/test/daemon/humminbird-M37.log.chk b/test/daemon/humminbird-M37.log.chk new file mode 100644 index 0000000..535fcfa --- /dev/null +++ b/test/daemon/humminbird-M37.log.chk @@ -0,0 +1,1378 @@ +$INDPT,2.2,0.0*47 +$INRMC,194101,A,4426.1130,N,07140.5596,W,5.2,77.3,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435661.000,"ept":0.005,"lat":44.435216667,"lon":-71.675993333,"track":77.3000,"speed":2.675,"mode":2} +$INDPT,2.1,0.0*44 +$INGLL,4426.1130,N,07140.5579,W,194102,A*2C +$INVTG,77.5,T,93.3,M,5.2,N,9.7,K*5B +$INMTW,17.9,C*1B +$INDPT,2.1,0.0*44 +$INRMC,194103,A,4426.1134,N,07140.5558,W,5.3,77.0,160906,15.8,W*66 +{"class":"TPV","tag":"RMC","time":1158435663.000,"ept":0.005,"lat":44.435223333,"lon":-71.675930000,"track":77.0000,"speed":2.727,"mode":2} +$INDPT,2.0,0.0*45 +$INGGA,194104,4426.1138,N,07140.5536,W,2,10,0.9,267.9,M,,,,*13 +$INZDA,194104,16,09,2006,-05,00*73 +$INMTW,17.9,C*1B +$INDPT,2.1,0.0*44 +$INRMC,194105,A,4426.1142,N,07140.5515,W,5.3,76.8,160906,15.8,W*61 +{"class":"TPV","tag":"RMC","time":1158435665.000,"ept":0.005,"lat":44.435236667,"lon":-71.675858333,"track":76.8000,"speed":2.727,"mode":2} +$INDPT,2.1,0.0*44 +$INGLL,4426.1146,N,07140.5499,W,194106,A*26 +{"class":"TPV","tag":"GLL","time":1158435666.000,"ept":0.005,"lat":44.435243333,"lon":-71.675831667,"speed":2.249,"mode":2} +$INVTG,76.3,T,92.1,M,5.3,N,9.7,K*5E +$INMTW,17.9,C*1B +$INDPT,2.2,0.0*47 +$INRMC,194107,A,4426.1149,N,07140.5477,W,5.3,76.6,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435667.000,"ept":0.005,"lat":44.435248333,"lon":-71.675795000,"track":76.6000,"speed":2.727,"mode":2} +$INDPT,2.1,0.0*44 +$INGGA,194108,4426.1149,N,07140.5455,W,2,10,0.9,268.0,M,,,,*1B +{"class":"TPV","tag":"GGA","time":1158435668.000,"ept":0.005,"lat":44.435248333,"lon":-71.675758333,"alt":268.000,"speed":2.919,"mode":3} +$INZDA,194108,16,09,2006,-05,00*7F +$INMTW,17.9,C*1B +$INDPT,2.2,0.0*47 +$INRMC,194109,A,4426.1153,N,07140.5439,W,5.2,76.5,160906,15.8,W*6E +{"class":"TPV","tag":"RMC","time":1158435669.000,"ept":0.005,"lat":44.435255000,"lon":-71.675731667,"track":76.5000,"speed":2.675,"mode":2} +$INDPT,2.3,0.0*46 +$INGLL,4426.1157,N,07140.5418,W,194110,A*28 +{"class":"TPV","tag":"GLL","time":1158435670.000,"ept":0.005,"lat":44.435261667,"lon":-71.675696667,"speed":2.883,"mode":2} +$INVTG,77.2,T,93.0,M,5.2,N,9.7,K*5F +$INMTW,17.9,C*1B +$INDPT,2.2,0.0*47 +$INRMC,194111,A,4426.1161,N,07140.5396,W,5.3,77.6,160906,15.8,W*67 +{"class":"TPV","tag":"RMC","time":1158435671.000,"ept":0.005,"lat":44.435268333,"lon":-71.675660000,"track":77.6000,"speed":2.727,"mode":2} +$INDPT,2.3,0.0*46 +$INGGA,194112,4426.1165,N,07140.5380,W,2,10,0.9,268.0,M,,,,*11 +{"class":"TPV","tag":"GGA","time":1158435672.000,"ept":0.005,"lat":44.435275000,"lon":-71.675633333,"alt":268.000,"speed":2.249,"mode":3} +$INZDA,194112,16,09,2006,-05,00*74 +$INMTW,17.9,C*1B +$INDPT,2.3,0.0*46 +$INRMC,194113,A,4426.1169,N,07140.5358,W,5.2,75.6,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435673.000,"ept":0.005,"lat":44.435281667,"lon":-71.675596667,"track":75.6000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1173,N,07140.5337,W,194114,A*20 +{"class":"TPV","tag":"GLL","time":1158435674.000,"ept":0.005,"lat":44.435288333,"lon":-71.675561667,"speed":2.883,"mode":2} +$INVTG,76.0,T,91.8,M,5.2,N,9.6,K*57 +$INMTW,17.9,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194115,A,4426.1176,N,07140.5321,W,5.2,77.3,160906,15.8,W*6D +{"class":"TPV","tag":"RMC","time":1158435675.000,"ept":0.005,"lat":44.435293333,"lon":-71.675535000,"track":77.3000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194116,4426.1176,N,07140.5299,W,2,10,0.9,268.0,M,,,,*1E +{"class":"TPV","tag":"GGA","time":1158435676.000,"ept":0.005,"lat":44.435293333,"lon":-71.675498333,"alt":268.000,"speed":2.919,"mode":3} +$INZDA,194116,16,09,2006,-05,00*70 +$INMTW,18.0,C*1D +$INDPT,2.4,0.0*41 +$INRMC,194117,A,4426.1180,N,07140.5278,W,5.2,76.8,160906,15.8,W*61 +{"class":"TPV","tag":"RMC","time":1158435677.000,"ept":0.005,"lat":44.435300000,"lon":-71.675463333,"track":76.8000,"speed":2.675,"mode":2} +$INDPT,2.5,0.0*40 +$INGLL,4426.1184,N,07140.5261,W,194118,A*26 +{"class":"TPV","tag":"GLL","time":1158435678.000,"ept":0.005,"lat":44.435306667,"lon":-71.675435000,"speed":2.374,"mode":2} +$INVTG,76.4,T,92.2,M,5.2,N,9.7,K*5B +$INMTW,18.0,C*1D +$INDPT,2.6,0.0*43 +$INRMC,194119,A,4426.1188,N,07140.5240,W,5.2,77.5,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435679.000,"ept":0.005,"lat":44.435313333,"lon":-71.675400000,"track":77.5000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194120,4426.1192,N,07140.5218,W,2,10,0.9,268.2,M,,,,*1A +{"class":"TPV","tag":"GGA","time":1158435680.000,"ept":0.005,"lat":44.435320000,"lon":-71.675363333,"alt":268.200,"speed":3.012,"mode":3} +$INZDA,194120,16,09,2006,-05,00*75 +$INMTW,17.9,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194121,A,4426.1192,N,07140.5202,W,5.2,79.3,160906,15.8,W*6E +{"class":"TPV","tag":"RMC","time":1158435681.000,"ept":0.005,"lat":44.435320000,"lon":-71.675336667,"track":79.3000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1196,N,07140.5181,W,194122,A*21 +{"class":"TPV","tag":"GLL","time":1158435682.000,"ept":0.005,"lat":44.435326667,"lon":-71.675301667,"speed":2.883,"mode":2} +$INVTG,78.6,T,94.4,M,5.3,N,9.7,K*56 +$INMTW,18.0,C*1D +$INDPT,2.4,0.0*41 +$INRMC,194123,A,4426.1200,N,07140.5159,W,5.2,79.0,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435683.000,"ept":0.005,"lat":44.435333333,"lon":-71.675265000,"track":79.0000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194124,4426.1200,N,07140.5143,W,2,10,0.9,268.2,M,,,,*1B +{"class":"TPV","tag":"GGA","time":1158435684.000,"ept":0.005,"lat":44.435333333,"lon":-71.675238333,"alt":268.200,"speed":2.123,"mode":3} +$INZDA,194124,16,09,2006,-05,00*71 +$INMTW,17.9,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194111,A,4426.1203,N,07140.5121,W,5.2,81.5,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435671.000,"ept":0.005,"lat":44.435338333,"lon":-71.675201667,"track":81.5000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1203,N,07140.5100,W,194112,A*24 +{"class":"TPV","tag":"GLL","time":1158435672.000,"ept":0.005,"lat":44.435338333,"lon":-71.675166667,"speed":2.787,"mode":2} +$INVTG,81.4,T,97.2,M,5.2,N,9.6,K*57 +$INMTW,18.0,C*1D +$INDPT,2.3,0.0*46 +$INRMC,194113,A,4426.1207,N,07140.5084,W,5.2,81.9,160906,15.8,W*61 +{"class":"TPV","tag":"RMC","time":1158435673.000,"ept":0.005,"lat":44.435345000,"lon":-71.675140000,"track":81.9000,"speed":2.675,"mode":2} +$INDPT,2.3,0.0*46 +$INGGA,194114,4426.1211,N,07140.5062,W,2,10,0.9,268.4,M,,,,*1C +{"class":"TPV","tag":"GGA","time":1158435674.000,"ept":0.005,"lat":44.435351667,"lon":-71.675103333,"alt":268.400,"speed":3.012,"mode":3} +$INZDA,194114,16,09,2006,-05,00*72 +$INMTW,18.0,C*1D +$INDPT,2.4,0.0*41 +$INRMC,194115,A,4426.1211,N,07140.5040,W,5.2,83.9,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435675.000,"ept":0.005,"lat":44.435351667,"lon":-71.675066667,"track":83.9000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1211,N,07140.5024,W,194116,A*24 +{"class":"TPV","tag":"GLL","time":1158435676.000,"ept":0.005,"lat":44.435351667,"lon":-71.675040000,"speed":2.123,"mode":2} +$INVTG,83.7,T,99.5,M,5.2,N,9.6,K*5F +$INMTW,18.1,C*1C +$INDPT,2.4,0.0*41 +$INRMC,194117,A,4426.1215,N,07140.5003,W,5.2,83.8,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435677.000,"ept":0.005,"lat":44.435358333,"lon":-71.675005000,"track":83.8000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194118,4426.1215,N,07140.4987,W,2,10,0.9,268.5,M,,,,*16 +{"class":"TPV","tag":"GGA","time":1158435678.000,"ept":0.005,"lat":44.435358333,"lon":-71.674978333,"alt":268.500,"speed":2.123,"mode":3} +$INZDA,194118,16,09,2006,-05,00*7E +$INMTW,18.0,C*1D +$INDPT,2.3,0.0*46 +$INRMC,194119,A,4426.1219,N,07140.4965,W,5.1,85.4,160906,15.8,W*69 +{"class":"TPV","tag":"RMC","time":1158435679.000,"ept":0.005,"lat":44.435365000,"lon":-71.674941667,"track":85.4000,"speed":2.624,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1219,N,07140.4943,W,194120,A*20 +{"class":"TPV","tag":"GLL","time":1158435680.000,"ept":0.005,"lat":44.435365000,"lon":-71.674905000,"speed":2.919,"mode":2} +$INVTG,85.6,T,101.4,M,5.2,N,9.5,K*6A +$INMTW,18.1,C*1C +$INDPT,2.4,0.0*41 +$INRMC,194121,A,4426.1219,N,07140.4927,W,5.2,85.5,160906,15.8,W*66 +{"class":"TPV","tag":"RMC","time":1158435681.000,"ept":0.005,"lat":44.435365000,"lon":-71.674878333,"track":85.5000,"speed":2.675,"mode":2} +$INDPT,2.5,0.0*40 +$INGGA,194122,4426.1223,N,07140.4906,W,2,10,0.9,268.4,M,,,,*12 +{"class":"TPV","tag":"GGA","time":1158435682.000,"ept":0.005,"lat":44.435371667,"lon":-71.674843333,"alt":268.400,"speed":2.883,"mode":3} +$INZDA,194122,16,09,2006,-05,00*77 +$INMTW,18.2,C*1F +$INDPT,2.4,0.0*41 +$INRMC,194123,A,4426.1223,N,07140.4884,W,5.1,86.8,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435683.000,"ept":0.005,"lat":44.435371667,"lon":-71.674806667,"track":86.8000,"speed":2.624,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1223,N,07140.4868,W,194124,A*25 +{"class":"TPV","tag":"GLL","time":1158435684.000,"ept":0.005,"lat":44.435371667,"lon":-71.674780000,"speed":2.123,"mode":2} +$INVTG,87.0,T,102.7,M,5.1,N,9.5,K*6D +$INMTW,18.2,C*1F +$INDPT,2.5,0.0*40 +$INRMC,194125,A,4426.1223,N,07140.4846,W,5.2,86.2,160906,15.8,W*69 +{"class":"TPV","tag":"RMC","time":1158435685.000,"ept":0.005,"lat":44.435371667,"lon":-71.674743333,"track":86.2000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194126,4426.1227,N,07140.4825,W,2,10,0.9,268.2,M,,,,*14 +{"class":"TPV","tag":"GGA","time":1158435686.000,"ept":0.005,"lat":44.435378333,"lon":-71.674708333,"alt":268.200,"speed":2.883,"mode":3} +$INZDA,194126,16,09,2006,-05,00*73 +$INMTW,18.1,C*1C +$INDPT,2.4,0.0*41 +$INRMC,194127,A,4426.1227,N,07140.4803,W,5.1,87.4,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435687.000,"ept":0.005,"lat":44.435378333,"lon":-71.674671667,"track":87.4000,"speed":2.624,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1227,N,07140.4787,W,194128,A*23 +{"class":"TPV","tag":"GLL","time":1158435688.000,"ept":0.005,"lat":44.435378333,"lon":-71.674645000,"speed":2.123,"mode":2} +$INVTG,88.3,T,104.1,M,5.1,N,9.5,K*61 +$INMTW,18.5,C*18 +$INDPT,2.4,0.0*41 +$INRMC,194129,A,4426.1227,N,07140.4766,W,5.2,87.6,160906,15.8,W*69 +{"class":"TPV","tag":"RMC","time":1158435689.000,"ept":0.005,"lat":44.435378333,"lon":-71.674610000,"track":87.6000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194130,4426.1227,N,07140.4744,W,2,10,0.9,268.0,M,,,,*19 +{"class":"TPV","tag":"GGA","time":1158435690.000,"ept":0.005,"lat":44.435378333,"lon":-71.674573333,"alt":268.000,"speed":2.919,"mode":3} +$INZDA,194130,16,09,2006,-05,00*74 +$INMTW,18.5,C*18 +$INDPT,2.4,0.0*41 +$INRMC,194131,A,4426.1230,N,07140.4728,W,5.1,86.6,160906,15.8,W*6E +{"class":"TPV","tag":"RMC","time":1158435691.000,"ept":0.005,"lat":44.435383333,"lon":-71.674546667,"track":86.6000,"speed":2.624,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1230,N,07140.4706,W,194132,A*27 +{"class":"TPV","tag":"GLL","time":1158435692.000,"ept":0.005,"lat":44.435383333,"lon":-71.674510000,"speed":2.919,"mode":2} +$INVTG,87.4,T,103.2,M,5.1,N,9.5,K*6D +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194133,A,4426.1230,N,07140.4685,W,5.1,88.1,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435693.000,"ept":0.005,"lat":44.435383333,"lon":-71.674475000,"track":88.1000,"speed":2.624,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194134,4426.1230,N,07140.4669,W,2,10,0.9,267.8,M,,,,*12 +{"class":"TPV","tag":"GGA","time":1158435694.000,"ept":0.005,"lat":44.435383333,"lon":-71.674448333,"alt":267.800,"speed":2.123,"mode":3} +$INZDA,194134,16,09,2006,-05,00*70 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194135,A,4426.1230,N,07140.4647,W,5.2,87.5,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435695.000,"ept":0.005,"lat":44.435383333,"lon":-71.674411667,"track":87.5000,"speed":2.675,"mode":2} +$INDPT,2.5,0.0*40 +$INGLL,4426.1230,N,07140.4625,W,194136,A*23 +{"class":"TPV","tag":"GLL","time":1158435696.000,"ept":0.005,"lat":44.435383333,"lon":-71.674375000,"speed":2.919,"mode":2} +$INVTG,87.5,T,103.3,M,5.1,N,9.5,K*6D +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194137,A,4426.1230,N,07140.4609,W,5.1,87.9,160906,15.8,W*64 +{"class":"TPV","tag":"RMC","time":1158435697.000,"ept":0.005,"lat":44.435383333,"lon":-71.674348333,"track":87.9000,"speed":2.624,"mode":2} +$INDPT,2.5,0.0*40 +$INGGA,194138,4426.1230,N,07140.4588,W,2,09,0.9,267.7,M,,,,*15 +{"class":"TPV","tag":"GGA","time":1158435698.000,"ept":0.005,"lat":44.435383333,"lon":-71.674313333,"alt":267.700,"speed":2.787,"mode":3} +$INZDA,194138,16,09,2006,-05,00*7C +$INMTW,18.6,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194139,A,4426.1230,N,07140.4566,W,5.2,87.3,160906,15.8,W*69 +{"class":"TPV","tag":"RMC","time":1158435699.000,"ept":0.005,"lat":44.435383333,"lon":-71.674276667,"track":87.3000,"speed":2.675,"mode":2} +$INDPT,2.6,0.0*43 +$INGLL,4426.1234,N,07140.4545,W,194140,A*23 +{"class":"TPV","tag":"GLL","time":1158435700.000,"ept":0.005,"lat":44.435390000,"lon":-71.674241667,"speed":2.883,"mode":2} +$INVTG,87.4,T,103.2,M,5.2,N,9.6,K*6D +$INMTW,18.7,C*1A +$INDPT,2.6,0.0*43 +$INRMC,194141,A,4426.1234,N,07140.4528,W,5.1,88.0,160906,15.8,W*67 +{"class":"TPV","tag":"RMC","time":1158435701.000,"ept":0.005,"lat":44.435390000,"lon":-71.674213333,"track":88.0000,"speed":2.624,"mode":2} +$INDPT,2.6,0.0*43 +$INGGA,194142,4426.1234,N,07140.4507,W,2,10,0.9,267.5,M,,,,*11 +{"class":"TPV","tag":"GGA","time":1158435702.000,"ept":0.005,"lat":44.435390000,"lon":-71.674178333,"alt":267.500,"speed":2.787,"mode":3} +$INZDA,194142,16,09,2006,-05,00*71 +$INMTW,18.6,C*1B +$INDPT,2.7,0.0*42 +$INRMC,194143,A,4426.1234,N,07140.4485,W,5.1,88.3,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435703.000,"ept":0.005,"lat":44.435390000,"lon":-71.674141667,"track":88.3000,"speed":2.624,"mode":2} +$INDPT,2.7,0.0*42 +$INGLL,4426.1234,N,07140.4469,W,194144,A*28 +{"class":"TPV","tag":"GLL","time":1158435704.000,"ept":0.005,"lat":44.435390000,"lon":-71.674115000,"speed":2.123,"mode":2} +$INVTG,87.5,T,103.3,M,5.1,N,9.5,K*6D +$INMTW,18.7,C*1A +$INDPT,2.8,0.0*4D +$INRMC,194145,A,4426.1234,N,07140.4448,W,5.1,87.9,160906,15.8,W*62 +{"class":"TPV","tag":"RMC","time":1158435705.000,"ept":0.005,"lat":44.435390000,"lon":-71.674080000,"track":87.9000,"speed":2.624,"mode":2} +$INDPT,2.8,0.0*4D +$INGGA,194146,4426.1234,N,07140.4426,W,2,09,0.9,267.2,M,,,,*18 +{"class":"TPV","tag":"GGA","time":1158435706.000,"ept":0.005,"lat":44.435390000,"lon":-71.674043333,"alt":267.200,"speed":2.919,"mode":3} +$INZDA,194146,16,09,2006,-05,00*75 +$INMTW,18.7,C*1A +$INDPT,3.0,0.0*44 +$INRMC,194147,A,4426.1238,N,07140.4410,W,5.1,87.6,160906,15.8,W*6E +{"class":"TPV","tag":"RMC","time":1158435707.000,"ept":0.005,"lat":44.435396667,"lon":-71.674016667,"track":87.6000,"speed":2.624,"mode":2} +$INDPT,2.9,0.0*4C +$INGLL,4426.1238,N,07140.4388,W,194148,A*20 +{"class":"TPV","tag":"GLL","time":1158435708.000,"ept":0.005,"lat":44.435396667,"lon":-71.673980000,"speed":2.919,"mode":2} +$INVTG,87.0,T,102.7,M,5.2,N,9.5,K*6E +$INMTW,18.7,C*1A +$INDPT,2.9,0.0*4C +$INRMC,194149,A,4426.1238,N,07140.4367,W,5.1,87.2,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435709.000,"ept":0.005,"lat":44.435396667,"lon":-71.673945000,"track":87.2000,"speed":2.624,"mode":2} +$INDPT,3.0,0.0*44 +$INGGA,194150,4426.1238,N,07140.4351,W,2,10,0.9,267.0,M,,,,*1E +{"class":"TPV","tag":"GGA","time":1158435710.000,"ept":0.005,"lat":44.435396667,"lon":-71.673918333,"alt":267.000,"speed":2.123,"mode":3} +$INZDA,194150,16,09,2006,-05,00*72 +$INMTW,18.7,C*1A +$INDPT,3.0,0.0*44 +$INRMC,194151,A,4426.1238,N,07140.4329,W,5.1,88.3,160906,15.8,W*6E +{"class":"TPV","tag":"RMC","time":1158435711.000,"ept":0.005,"lat":44.435396667,"lon":-71.673881667,"track":88.3000,"speed":2.624,"mode":2} +$INDPT,2.9,0.0*4C +$INGLL,4426.1238,N,07140.4307,W,194152,A*2C +{"class":"TPV","tag":"GLL","time":1158435712.000,"ept":0.005,"lat":44.435396667,"lon":-71.673845000,"speed":2.919,"mode":2} +$INVTG,87.8,T,103.6,M,5.1,N,9.5,K*65 +$INMTW,18.7,C*1A +$INDPT,2.7,0.0*42 +$INRMC,194153,A,4426.1238,N,07140.4291,W,5.1,88.1,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435713.000,"ept":0.005,"lat":44.435396667,"lon":-71.673818333,"track":88.1000,"speed":2.624,"mode":2} +$INDPT,2.7,0.0*42 +$INGGA,194154,4426.1242,N,07140.4270,W,2,10,0.9,266.8,M,,,,*1C +{"class":"TPV","tag":"GGA","time":1158435714.000,"ept":0.005,"lat":44.435403333,"lon":-71.673783333,"alt":266.800,"speed":2.883,"mode":3} +$INZDA,194154,16,09,2006,-05,00*76 +$INMTW,18.8,C*15 +$INDPT,2.9,0.0*4C +$INRMC,194155,A,4426.1242,N,07140.4248,W,5.1,88.6,160906,15.8,W*64 +{"class":"TPV","tag":"RMC","time":1158435715.000,"ept":0.005,"lat":44.435403333,"lon":-71.673746667,"track":88.6000,"speed":2.624,"mode":2} +$INDPT,2.9,0.0*4C +$INGLL,4426.1242,N,07140.4232,W,194156,A*22 +{"class":"TPV","tag":"GLL","time":1158435716.000,"ept":0.005,"lat":44.435403333,"lon":-71.673720000,"speed":2.123,"mode":2} +$INVTG,88.8,T,104.6,M,5.1,N,9.4,K*6C +$INMTW,18.7,C*1A +$INDPT,3.0,0.0*44 +$INRMC,194157,A,4426.1242,N,07140.4210,W,5.1,88.2,160906,15.8,W*6F +{"class":"TPV","tag":"RMC","time":1158435717.000,"ept":0.005,"lat":44.435403333,"lon":-71.673683333,"track":88.2000,"speed":2.624,"mode":2} +$INDPT,3.0,0.0*44 +$INGGA,194158,4426.1242,N,07140.4189,W,2,09,0.9,266.6,M,,,,*13 +{"class":"TPV","tag":"GGA","time":1158435718.000,"ept":0.005,"lat":44.435403333,"lon":-71.673648333,"alt":266.600,"speed":2.787,"mode":3} +$INZDA,194158,16,09,2006,-05,00*7A +$INMTW,18.8,C*15 +$INDPT,3.1,0.0*45 +$INRMC,194159,A,4426.1242,N,07140.4173,W,5.1,88.9,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435719.000,"ept":0.005,"lat":44.435403333,"lon":-71.673621667,"track":88.9000,"speed":2.624,"mode":2} +$INDPT,3.3,0.0*47 +$INGLL,4426.1242,N,07140.4151,W,194200,A*24 +{"class":"TPV","tag":"GLL","time":1158435720.000,"ept":0.005,"lat":44.435403333,"lon":-71.673585000,"speed":2.919,"mode":2} +$INVTG,89.6,T,105.3,M,5.1,N,9.5,K*66 +$INMTW,18.6,C*1B +$INDPT,2.9,0.0*4C +$INRMC,194201,A,4426.1242,N,07140.4130,W,5.1,89.2,160906,15.8,W*6F +{"class":"TPV","tag":"RMC","time":1158435721.000,"ept":0.005,"lat":44.435403333,"lon":-71.673550000,"track":89.2000,"speed":2.624,"mode":2} +$INDPT,2.7,0.0*42 +$INGGA,194202,4426.1242,N,07140.4113,W,2,09,0.9,266.6,M,,,,*1C +{"class":"TPV","tag":"GGA","time":1158435722.000,"ept":0.005,"lat":44.435403333,"lon":-71.673521667,"alt":266.600,"speed":2.256,"mode":3} +$INZDA,194202,16,09,2006,-05,00*76 +$INMTW,18.8,C*15 +$INDPT,2.8,0.0*4D +$INRMC,194203,A,4426.1242,N,07140.4092,W,5.1,89.0,160906,15.8,W*66 +{"class":"TPV","tag":"RMC","time":1158435723.000,"ept":0.005,"lat":44.435403333,"lon":-71.673486667,"track":89.0000,"speed":2.624,"mode":2} +$INDPT,2.9,0.0*4C +$INGLL,4426.1242,N,07140.4070,W,194204,A*22 +{"class":"TPV","tag":"GLL","time":1158435724.000,"ept":0.005,"lat":44.435403333,"lon":-71.673450000,"speed":2.919,"mode":2} +$INVTG,89.6,T,105.4,M,5.1,N,9.5,K*61 +$INMTW,18.6,C*1B +$INDPT,3.0,0.0*44 +$INRMC,194205,A,4426.1242,N,07140.4054,W,5.1,89.9,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435725.000,"ept":0.005,"lat":44.435403333,"lon":-71.673423333,"track":89.9000,"speed":2.624,"mode":2} +$INDPT,3.0,0.0*44 +$INGGA,194206,4426.1242,N,07140.4033,W,2,10,0.9,266.5,M,,,,*10 +{"class":"TPV","tag":"GGA","time":1158435726.000,"ept":0.005,"lat":44.435403333,"lon":-71.673388333,"alt":266.500,"speed":2.787,"mode":3} +$INZDA,194206,16,09,2006,-05,00*72 +$INMTW,18.7,C*1A +$INDPT,3.1,0.0*45 +$INRMC,194207,A,4426.1242,N,07140.4011,W,5.1,88.4,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435727.000,"ept":0.005,"lat":44.435403333,"lon":-71.673351667,"track":88.4000,"speed":2.624,"mode":2} +$INDPT,3.1,0.0*45 +$INGLL,4426.1242,N,07140.3995,W,194208,A*2B +{"class":"TPV","tag":"GLL","time":1158435728.000,"ept":0.005,"lat":44.435403333,"lon":-71.673325000,"speed":2.123,"mode":2} +$INVTG,88.9,T,104.7,M,5.1,N,9.5,K*6D +$INMTW,18.7,C*1A +$INDPT,2.9,0.0*4C +$INRMC,194209,A,4426.1242,N,07140.3973,W,5.1,89.8,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435729.000,"ept":0.005,"lat":44.435403333,"lon":-71.673288333,"track":89.8000,"speed":2.624,"mode":2} +$INDPT,2.9,0.0*4C +$INGGA,194210,4426.1242,N,07140.3952,W,2,09,0.9,266.4,M,,,,*17 +{"class":"TPV","tag":"GGA","time":1158435730.000,"ept":0.005,"lat":44.435403333,"lon":-71.673253333,"alt":266.400,"speed":2.787,"mode":3} +$INZDA,194210,16,09,2006,-05,00*75 +$INMTW,18.6,C*1B +$INDPT,2.9,0.0*4C +$INRMC,194211,A,4426.1242,N,07140.3930,W,5.2,88.3,160906,15.8,W*62 +{"class":"TPV","tag":"RMC","time":1158435731.000,"ept":0.005,"lat":44.435403333,"lon":-71.673216667,"track":88.3000,"speed":2.675,"mode":2} +$INDPT,3.1,0.0*45 +$INGLL,4426.1242,N,07140.3914,W,194212,A*29 +{"class":"TPV","tag":"GLL","time":1158435732.000,"ept":0.005,"lat":44.435403333,"lon":-71.673190000,"speed":2.123,"mode":2} +$INVTG,88.6,T,104.4,M,5.2,N,9.6,K*61 +$INMTW,18.6,C*1B +$INDPT,3.1,0.0*45 +$INRMC,194213,A,4426.1242,N,07140.3892,W,5.1,89.2,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435733.000,"ept":0.005,"lat":44.435403333,"lon":-71.673153333,"track":89.2000,"speed":2.624,"mode":2} +$INDPT,3.1,0.0*45 +$INGGA,194214,4426.1242,N,07140.3871,W,2,09,0.9,266.3,M,,,,*14 +{"class":"TPV","tag":"GGA","time":1158435734.000,"ept":0.005,"lat":44.435403333,"lon":-71.673118333,"alt":266.300,"speed":2.787,"mode":3} +$INZDA,194214,16,09,2006,-05,00*71 +$INMTW,18.6,C*1B +$INDPT,3.0,0.0*44 +$INRMC,194215,A,4426.1242,N,07140.3849,W,5.2,88.0,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435735.000,"ept":0.005,"lat":44.435403333,"lon":-71.673081667,"track":88.0000,"speed":2.675,"mode":2} +$INDPT,3.2,0.0*46 +$INGLL,4426.1242,N,07140.3833,W,194216,A*29 +{"class":"TPV","tag":"GLL","time":1158435736.000,"ept":0.005,"lat":44.435403333,"lon":-71.673055000,"speed":2.123,"mode":2} +$INVTG,87.9,T,103.7,M,5.2,N,9.6,K*65 +$INMTW,18.6,C*1B +$INDPT,4.8,0.0*4B +$INRMC,194217,A,4426.1246,N,07140.3812,W,5.2,88.8,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435737.000,"ept":0.005,"lat":44.435410000,"lon":-71.673020000,"track":88.8000,"speed":2.675,"mode":2} +$INDPT,2.8,0.0*4D +$INGGA,194218,4426.1246,N,07140.3790,W,2,09,0.9,266.2,M,,,,*1D +{"class":"TPV","tag":"GGA","time":1158435738.000,"ept":0.005,"lat":44.435410000,"lon":-71.672983333,"alt":266.200,"speed":2.919,"mode":3} +$INZDA,194218,16,09,2006,-05,00*7D +$INMTW,18.6,C*1B +$INDPT,2.8,0.0*4D +$INRMC,194219,A,4426.1246,N,07140.3774,W,5.2,88.0,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435739.000,"ept":0.005,"lat":44.435410000,"lon":-71.672956667,"track":88.0000,"speed":2.675,"mode":2} +$INDPT,2.8,0.0*4D +$INGLL,4426.1246,N,07140.3752,W,194220,A*20 +{"class":"TPV","tag":"GLL","time":1158435740.000,"ept":0.005,"lat":44.435410000,"lon":-71.672920000,"speed":2.919,"mode":2} +$INVTG,87.4,T,103.1,M,5.2,N,9.6,K*6E +$INMTW,18.5,C*18 +$INDPT,2.7,0.0*42 +$INRMC,194221,A,4426.1246,N,07140.3731,W,5.1,87.9,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435741.000,"ept":0.005,"lat":44.435410000,"lon":-71.672885000,"track":87.9000,"speed":2.624,"mode":2} +$INDPT,2.7,0.0*42 +$INGGA,194222,4426.1246,N,07140.3715,W,2,09,0.9,266.1,M,,,,*1A +{"class":"TPV","tag":"GGA","time":1158435742.000,"ept":0.005,"lat":44.435410000,"lon":-71.672858333,"alt":266.100,"speed":2.123,"mode":3} +$INZDA,194222,16,09,2006,-05,00*74 +$INMTW,18.4,C*19 +$INDPT,2.6,0.0*43 +$INRMC,194223,A,4426.1246,N,07140.3693,W,5.1,88.4,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435743.000,"ept":0.005,"lat":44.435410000,"lon":-71.672821667,"track":88.4000,"speed":2.624,"mode":2} +$INDPT,2.6,0.0*43 +$INGLL,4426.1246,N,07140.3671,W,194224,A*24 +{"class":"TPV","tag":"GLL","time":1158435744.000,"ept":0.005,"lat":44.435410000,"lon":-71.672785000,"speed":2.919,"mode":2} +$INVTG,87.2,T,103.0,M,5.2,N,9.6,K*69 +$INMTW,18.5,C*18 +$INDPT,2.6,0.0*43 +$INRMC,194225,A,4426.1250,N,07140.3650,W,5.2,86.8,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435745.000,"ept":0.005,"lat":44.435416667,"lon":-71.672750000,"track":86.8000,"speed":2.675,"mode":2} +$INDPT,2.7,0.0*42 +$INGGA,194226,4426.1250,N,07140.3634,W,2,09,0.9,266.0,M,,,,*1A +{"class":"TPV","tag":"GGA","time":1158435746.000,"ept":0.005,"lat":44.435416667,"lon":-71.672723333,"alt":266.000,"speed":2.123,"mode":3} +$INZDA,194226,16,09,2006,-05,00*70 +$INMTW,18.4,C*19 +$INDPT,2.8,0.0*4D +$INRMC,194227,A,4426.1250,N,07140.3612,W,5.1,87.7,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435747.000,"ept":0.005,"lat":44.435416667,"lon":-71.672686667,"track":87.7000,"speed":2.624,"mode":2} +$INDPT,2.9,0.0*4C +$INGLL,4426.1250,N,07140.3591,W,194228,A*22 +{"class":"TPV","tag":"GLL","time":1158435748.000,"ept":0.005,"lat":44.435416667,"lon":-71.672651667,"speed":2.787,"mode":2} +$INVTG,87.4,T,103.2,M,5.1,N,9.5,K*6D +$INMTW,18.6,C*1B +$INDPT,3.0,0.0*44 +$INRMC,194229,A,4426.1250,N,07140.3569,W,5.2,87.0,160906,15.8,W*66 +{"class":"TPV","tag":"RMC","time":1158435749.000,"ept":0.005,"lat":44.435416667,"lon":-71.672615000,"track":87.0000,"speed":2.675,"mode":2} +$INDPT,2.7,0.0*42 +$INGGA,194230,4426.1250,N,07140.3553,W,2,09,0.9,265.9,M,,,,*15 +{"class":"TPV","tag":"GGA","time":1158435750.000,"ept":0.005,"lat":44.435416667,"lon":-71.672588333,"alt":265.900,"speed":2.123,"mode":3} +$INZDA,194230,16,09,2006,-05,00*77 +$INMTW,18.6,C*1B +$INDPT,2.6,0.0*43 +$INRMC,194231,A,4426.1254,N,07140.3531,W,5.1,87.8,160906,15.8,W*6D +{"class":"TPV","tag":"RMC","time":1158435751.000,"ept":0.005,"lat":44.435423333,"lon":-71.672551667,"track":87.8000,"speed":2.624,"mode":2} +$INDPT,2.6,0.0*43 +$INGLL,4426.1254,N,07140.3510,W,194232,A*24 +{"class":"TPV","tag":"GLL","time":1158435752.000,"ept":0.005,"lat":44.435423333,"lon":-71.672516667,"speed":2.787,"mode":2} +$INVTG,86.9,T,102.7,M,5.2,N,9.6,K*65 +$INMTW,18.6,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194233,A,4426.1254,N,07140.3494,W,5.2,86.7,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435753.000,"ept":0.005,"lat":44.435423333,"lon":-71.672490000,"track":86.7000,"speed":2.675,"mode":2} +$INDPT,2.5,0.0*40 +$INGGA,194234,4426.1254,N,07140.3472,W,2,09,0.9,265.8,M,,,,*16 +{"class":"TPV","tag":"GGA","time":1158435754.000,"ept":0.005,"lat":44.435423333,"lon":-71.672453333,"alt":265.800,"speed":2.919,"mode":3} +$INZDA,194234,16,09,2006,-05,00*73 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194235,A,4426.1254,N,07140.3450,W,5.2,87.4,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435755.000,"ept":0.005,"lat":44.435423333,"lon":-71.672416667,"track":87.4000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1258,N,07140.3429,W,194236,A*27 +{"class":"TPV","tag":"GLL","time":1158435756.000,"ept":0.005,"lat":44.435430000,"lon":-71.672381667,"speed":2.883,"mode":2} +$INVTG,87.4,T,103.2,M,5.2,N,9.6,K*6D +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194237,A,4426.1258,N,07140.3413,W,5.2,86.6,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435757.000,"ept":0.005,"lat":44.435430000,"lon":-71.672355000,"track":86.6000,"speed":2.675,"mode":2} +$INDPT,2.5,0.0*40 +$INGGA,194238,4426.1258,N,07140.3391,W,2,09,0.9,265.7,M,,,,*13 +{"class":"TPV","tag":"GGA","time":1158435758.000,"ept":0.005,"lat":44.435430000,"lon":-71.672318333,"alt":265.700,"speed":2.919,"mode":3} +$INZDA,194238,16,09,2006,-05,00*7F +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194239,A,4426.1258,N,07140.3370,W,5.2,87.3,160906,15.8,W*62 +{"class":"TPV","tag":"RMC","time":1158435759.000,"ept":0.005,"lat":44.435430000,"lon":-71.672283333,"track":87.3000,"speed":2.675,"mode":2} +$INDPT,2.6,0.0*43 +$INGLL,4426.1258,N,07140.3353,W,194240,A*2C +{"class":"TPV","tag":"GLL","time":1158435760.000,"ept":0.005,"lat":44.435430000,"lon":-71.672255000,"speed":2.256,"mode":2} +$INVTG,88.0,T,103.8,M,5.2,N,9.6,K*6C +$INMTW,18.7,C*1A +$INDPT,2.6,0.0*43 +$INRMC,194241,A,4426.1261,N,07140.3332,W,5.2,87.7,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435761.000,"ept":0.005,"lat":44.435435000,"lon":-71.672220000,"track":87.7000,"speed":2.675,"mode":2} +$INDPT,2.7,0.0*42 +$INGGA,194242,4426.1261,N,07140.3310,W,2,09,0.9,265.5,M,,,,*1F +{"class":"TPV","tag":"GGA","time":1158435762.000,"ept":0.005,"lat":44.435435000,"lon":-71.672183333,"alt":265.500,"speed":2.919,"mode":3} +$INZDA,194242,16,09,2006,-05,00*72 +$INMTW,18.6,C*1B +$INDPT,2.6,0.0*43 +$INRMC,194243,A,4426.1261,N,07140.3289,W,5.2,88.0,160906,15.8,W*6E +{"class":"TPV","tag":"RMC","time":1158435763.000,"ept":0.005,"lat":44.435435000,"lon":-71.672148333,"track":88.0000,"speed":2.675,"mode":2} +$INDPT,2.5,0.0*40 +$INGLL,4426.1261,N,07140.3267,W,194244,A*24 +{"class":"TPV","tag":"GLL","time":1158435764.000,"ept":0.005,"lat":44.435435000,"lon":-71.672111667,"speed":2.919,"mode":2} +$INVTG,88.5,T,104.3,M,5.2,N,9.7,K*64 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194245,A,4426.1261,N,07140.3246,W,5.2,88.3,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435765.000,"ept":0.005,"lat":44.435435000,"lon":-71.672076667,"track":88.3000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194246,4426.1261,N,07140.3230,W,2,09,0.9,264.9,M,,,,*15 +{"class":"TPV","tag":"GGA","time":1158435766.000,"ept":0.005,"lat":44.435435000,"lon":-71.672050000,"alt":264.900,"speed":2.123,"mode":3} +$INZDA,194246,16,09,2006,-05,00*76 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194247,A,4426.1265,N,07140.3208,W,5.2,87.6,160906,15.8,W*6E +{"class":"TPV","tag":"RMC","time":1158435767.000,"ept":0.005,"lat":44.435441667,"lon":-71.672013333,"track":87.6000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1265,N,07140.3186,W,194248,A*20 +{"class":"TPV","tag":"GLL","time":1158435768.000,"ept":0.005,"lat":44.435441667,"lon":-71.671976667,"speed":2.919,"mode":2} +$INVTG,88.1,T,103.9,M,5.2,N,9.6,K*6C +$INMTW,18.6,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194249,A,4426.1265,N,07140.3165,W,5.2,88.7,160906,15.8,W*66 +{"class":"TPV","tag":"RMC","time":1158435769.000,"ept":0.005,"lat":44.435441667,"lon":-71.671941667,"track":88.7000,"speed":2.675,"mode":2} +$INDPT,2.6,0.0*43 +$INGGA,194250,4426.1265,N,07140.3149,W,2,09,0.9,263.8,M,,,,*1D +{"class":"TPV","tag":"GGA","time":1158435770.000,"ept":0.005,"lat":44.435441667,"lon":-71.671915000,"alt":263.800,"speed":2.123,"mode":3} +$INZDA,194250,16,09,2006,-05,00*71 +$INMTW,18.6,C*1B +$INDPT,2.7,0.0*42 +$INRMC,194251,A,4426.1265,N,07140.3127,W,5.2,88.4,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435771.000,"ept":0.005,"lat":44.435441667,"lon":-71.671878333,"track":88.4000,"speed":2.675,"mode":2} +$INDPT,2.5,0.0*40 +$INGLL,4426.1265,N,07140.3106,W,194252,A*23 +{"class":"TPV","tag":"GLL","time":1158435772.000,"ept":0.005,"lat":44.435441667,"lon":-71.671843333,"speed":2.787,"mode":2} +$INVTG,87.8,T,103.5,M,5.2,N,9.7,K*67 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194253,A,4426.1265,N,07140.3089,W,5.2,88.3,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435773.000,"ept":0.005,"lat":44.435441667,"lon":-71.671815000,"track":88.3000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194254,4426.1265,N,07140.3068,W,2,09,0.9,262.8,M,,,,*1A +{"class":"TPV","tag":"GGA","time":1158435774.000,"ept":0.005,"lat":44.435441667,"lon":-71.671780000,"alt":262.800,"speed":2.787,"mode":3} +$INZDA,194254,16,09,2006,-05,00*75 +$INMTW,18.6,C*1B +$INDPT,2.3,0.0*46 +$INRMC,194255,A,4426.1265,N,07140.3046,W,5.2,89.0,160906,15.8,W*6D +{"class":"TPV","tag":"RMC","time":1158435775.000,"ept":0.005,"lat":44.435441667,"lon":-71.671743333,"track":89.0000,"speed":2.675,"mode":2} +$INDPT,2.2,0.0*47 +$INGLL,4426.1265,N,07140.3025,W,194256,A*27 +{"class":"TPV","tag":"GLL","time":1158435776.000,"ept":0.005,"lat":44.435441667,"lon":-71.671708333,"speed":2.787,"mode":2} +$INVTG,88.6,T,104.4,M,5.2,N,9.7,K*60 +$INMTW,18.6,C*1B +$INDPT,2.1,0.0*44 +$INRMC,194257,A,4426.1265,N,07140.3009,W,5.2,88.6,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435777.000,"ept":0.005,"lat":44.435441667,"lon":-71.671681667,"track":88.6000,"speed":2.675,"mode":2} +$INDPT,2.1,0.0*44 +$INGGA,194258,4426.1265,N,07140.2987,W,2,09,0.9,262.0,M,,,,*17 +{"class":"TPV","tag":"GGA","time":1158435778.000,"ept":0.005,"lat":44.435441667,"lon":-71.671645000,"alt":262.000,"speed":2.919,"mode":3} +$INZDA,194258,16,09,2006,-05,00*79 +$INMTW,18.6,C*1B +$INDPT,2.3,0.0*46 +$INRMC,194259,A,4426.1265,N,07140.2965,W,5.1,89.1,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435779.000,"ept":0.005,"lat":44.435441667,"lon":-71.671608333,"track":89.1000,"speed":2.624,"mode":2} +$INDPT,2.4,0.0*41 +$INGLL,4426.1265,N,07140.2944,W,194300,A*2A +{"class":"TPV","tag":"GLL","time":1158435780.000,"ept":0.005,"lat":44.435441667,"lon":-71.671573333,"speed":2.787,"mode":2} +$INVTG,89.3,T,105.1,M,5.2,N,9.5,K*62 +$INMTW,18.6,C*1B +$INDPT,2.4,0.0*41 +$INRMC,194301,A,4426.1269,N,07140.2922,W,5.2,89.7,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435781.000,"ept":0.005,"lat":44.435448333,"lon":-71.671536667,"track":89.7000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194302,4426.1269,N,07140.2901,W,2,09,0.9,261.3,M,,,,*1B +{"class":"TPV","tag":"GGA","time":1158435782.000,"ept":0.005,"lat":44.435448333,"lon":-71.671501667,"alt":261.300,"speed":2.787,"mode":3} +$INZDA,194302,16,09,2006,-05,00*77 +$INMTW,18.6,C*1B +$INDPT,2.5,0.0*40 +$INRMC,194303,A,4426.1269,N,07140.2879,W,5.2,90.3,160906,15.8,W*6D +{"class":"TPV","tag":"RMC","time":1158435783.000,"ept":0.005,"lat":44.435448333,"lon":-71.671465000,"track":90.3000,"speed":2.675,"mode":2} +$INDPT,2.5,0.0*40 +$INGLL,4426.1265,N,07140.2863,W,194304,A*2A +{"class":"TPV","tag":"GLL","time":1158435784.000,"ept":0.005,"lat":44.435441667,"lon":-71.671438333,"speed":2.249,"mode":2} +$INVTG,91.4,T,107.2,M,5.2,N,9.7,K*6F +$INMTW,18.5,C*18 +$INDPT,2.4,0.0*41 +$INRMC,194304,A,4426.1265,N,07140.2863,W,5.2,91.4,160906,15.8,W*6B +{"class":"TPV","tag":"RMC","time":1158435784.000,"ept":0.005,"lat":44.435441667,"lon":-71.671438333,"track":91.4000,"speed":2.675,"mode":2} +$INDPT,2.4,0.0*41 +$INGGA,194306,4426.1265,N,07140.2820,W,2,09,0.9,261.0,M,,,,*12 +{"class":"TPV","tag":"GGA","time":1158435786.000,"ept":0.005,"lat":44.435441667,"lon":-71.671366667,"alt":261.000,"speed":2.853,"mode":3} +$INZDA,194306,16,09,2006,-05,00*73 +$INMTW,18.2,C*1F +$INDPT,2.5,0.0*40 +$INRMC,194306,A,4426.1265,N,07140.2820,W,5.2,88.5,160906,15.8,W*67 +{"class":"TPV","tag":"RMC","time":1158435786.000,"ept":0.005,"lat":44.435441667,"lon":-71.671366667,"alt":261.000,"track":88.5000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,1.9,0.0*4F +$INGLL,4426.1269,N,07140.2782,W,194308,A*2A +{"class":"TPV","tag":"GLL","time":1158435788.000,"ept":0.005,"lat":44.435448333,"lon":-71.671303333,"speed":2.548,"mode":2} +$INVTG,87.0,T,102.7,M,5.2,N,9.6,K*6D +$INMTW,18.5,C*18 +$INDPT,1.7,0.0*41 +$INRMC,194308,A,4426.1269,N,07140.2782,W,5.2,87.0,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435788.000,"ept":0.005,"lat":44.435448333,"lon":-71.671303333,"track":87.0000,"speed":2.675,"mode":2} +$INDPT,1.6,0.0*40 +$INGGA,194310,4426.1269,N,07140.2739,W,2,10,0.9,260.8,M,,,,*1F +{"class":"TPV","tag":"GGA","time":1158435790.000,"ept":0.005,"lat":44.435448333,"lon":-71.671231667,"alt":260.800,"speed":2.853,"mode":3} +$INZDA,194310,16,09,2006,-05,00*74 +$INMTW,18.6,C*1B +$INDPT,1.7,0.0*41 +$INRMC,194310,A,4426.1269,N,07140.2739,W,5.2,85.4,160906,15.8,W*67 +{"class":"TPV","tag":"RMC","time":1158435790.000,"ept":0.005,"lat":44.435448333,"lon":-71.671231667,"alt":260.800,"track":85.4000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,1.8,0.0*4E +$INGLL,4426.1273,N,07140.2701,W,194312,A*21 +{"class":"TPV","tag":"GLL","time":1158435792.000,"ept":0.005,"lat":44.435455000,"lon":-71.671168333,"speed":2.548,"mode":2} +$INVTG,83.4,T,99.2,M,5.2,N,9.6,K*5B +$INMTW,18.5,C*18 +$INDPT,2.0,0.0*45 +$INRMC,194312,A,4426.1273,N,07140.2701,W,5.1,83.4,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435792.000,"ept":0.005,"lat":44.435455000,"lon":-71.671168333,"track":83.4000,"speed":2.624,"mode":2} +$INDPT,1.9,0.0*4F +$INGGA,194314,4426.1277,N,07140.2664,W,2,09,0.9,260.7,M,,,,*1A +{"class":"TPV","tag":"GGA","time":1158435794.000,"ept":0.005,"lat":44.435461667,"lon":-71.671106667,"alt":260.700,"speed":2.483,"mode":3} +$INZDA,194314,16,09,2006,-05,00*70 +$INMTW,18.5,C*18 +$INDPT,1.7,0.0*41 +$INRMC,194314,A,4426.1277,N,07140.2664,W,5.2,84.5,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435794.000,"ept":0.005,"lat":44.435461667,"lon":-71.671106667,"alt":260.700,"track":84.5000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,1.6,0.0*40 +$INGLL,4426.1277,N,07140.2620,W,194316,A*23 +{"class":"TPV","tag":"GLL","time":1158435796.000,"ept":0.005,"lat":44.435461667,"lon":-71.671033333,"speed":2.919,"mode":2} +$INVTG,83.3,T,99.1,M,5.2,N,9.6,K*5F +$INMTW,18.6,C*1B +$INDPT,1.6,0.0*40 +$INRMC,194316,A,4426.1277,N,07140.2620,W,5.1,83.3,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435796.000,"ept":0.005,"lat":44.435461667,"lon":-71.671033333,"track":83.3000,"speed":2.624,"mode":2} +$INDPT,1.5,0.0*43 +$INGGA,194318,4426.1281,N,07140.2583,W,2,09,0.9,260.7,M,,,,*15 +{"class":"TPV","tag":"GGA","time":1158435798.000,"ept":0.005,"lat":44.435468333,"lon":-71.670971667,"alt":260.700,"speed":2.483,"mode":3} +$INZDA,194318,16,09,2006,-05,00*7C +$INMTW,18.5,C*18 +$INDPT,1.6,0.0*40 +$INRMC,194318,A,4426.1281,N,07140.2583,W,5.1,84.5,160906,15.8,W*69 +{"class":"TPV","tag":"RMC","time":1158435798.000,"ept":0.005,"lat":44.435468333,"lon":-71.670971667,"alt":260.700,"track":84.5000,"speed":2.624,"climb":0.000,"mode":3} +$INDPT,1.7,0.0*41 +$INGLL,4426.1285,N,07140.2545,W,194320,A*2B +{"class":"TPV","tag":"GLL","time":1158435800.000,"ept":0.005,"lat":44.435475000,"lon":-71.670908333,"speed":2.548,"mode":2} +$INVTG,84.3,T,100.1,M,5.2,N,9.5,K*6A +$INMTW,18.5,C*18 +$INDPT,1.7,0.0*41 +$INRMC,194320,A,4426.1285,N,07140.2545,W,5.1,84.3,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435800.000,"ept":0.005,"lat":44.435475000,"lon":-71.670908333,"track":84.3000,"speed":2.624,"mode":2} +$INDPT,1.7,0.0*41 +$INGGA,194322,4426.1288,N,07140.2502,W,2,10,0.9,260.6,M,,,,*15 +{"class":"TPV","tag":"GGA","time":1158435802.000,"ept":0.005,"lat":44.435480000,"lon":-71.670836667,"alt":260.600,"speed":2.866,"mode":3} +$INZDA,194322,16,09,2006,-05,00*75 +$INMTW,18.5,C*18 +$INDPT,1.8,0.0*4E +$INRMC,194322,A,4426.1288,N,07140.2502,W,5.1,84.7,160906,15.8,W*62 +{"class":"TPV","tag":"RMC","time":1158435802.000,"ept":0.005,"lat":44.435480000,"lon":-71.670836667,"alt":260.600,"track":84.7000,"speed":2.624,"climb":0.000,"mode":3} +$INDPT,2.0,0.0*45 +$INGLL,4426.1288,N,07140.2464,W,194324,A*20 +{"class":"TPV","tag":"GLL","time":1158435804.000,"ept":0.005,"lat":44.435480000,"lon":-71.670773333,"speed":2.521,"mode":2} +$INVTG,84.5,T,100.3,M,5.1,N,9.5,K*6D +$INMTW,18.5,C*18 +$INDPT,2.0,0.0*45 +$INRMC,194324,A,4426.1288,N,07140.2464,W,5.2,84.5,160906,15.8,W*64 +{"class":"TPV","tag":"RMC","time":1158435804.000,"ept":0.005,"lat":44.435480000,"lon":-71.670773333,"track":84.5000,"speed":2.675,"mode":2} +$INDPT,2.2,0.0*47 +$INGGA,194326,4426.1292,N,07140.2421,W,2,09,0.9,260.7,M,,,,*13 +{"class":"TPV","tag":"GGA","time":1158435806.000,"ept":0.005,"lat":44.435486667,"lon":-71.670701667,"alt":260.700,"speed":2.877,"mode":3} +$INZDA,194326,16,09,2006,-05,00*71 +$INMTW,18.4,C*19 +$INDPT,2.2,0.0*47 +$INRMC,194326,A,4426.1292,N,07140.2421,W,5.2,84.7,160906,15.8,W*6E +{"class":"TPV","tag":"RMC","time":1158435806.000,"ept":0.005,"lat":44.435486667,"lon":-71.670701667,"alt":260.700,"track":84.7000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.3,0.0*46 +$INGLL,4426.1296,N,07140.2383,W,194328,A*2D +{"class":"TPV","tag":"GLL","time":1158435808.000,"ept":0.005,"lat":44.435493333,"lon":-71.670638333,"speed":2.548,"mode":2} +$INVTG,84.7,T,100.5,M,5.2,N,9.7,K*68 +$INMTW,18.4,C*19 +$INDPT,2.3,0.0*46 +$INRMC,194328,A,4426.1296,N,07140.2383,W,5.2,84.7,160906,15.8,W*6B +{"class":"TPV","tag":"RMC","time":1158435808.000,"ept":0.005,"lat":44.435493333,"lon":-71.670638333,"track":84.7000,"speed":2.675,"mode":2} +$INDPT,2.5,0.0*40 +$INGGA,194330,4426.1300,N,07140.2346,W,2,09,0.9,260.7,M,,,,*18 +{"class":"TPV","tag":"GGA","time":1158435810.000,"ept":0.005,"lat":44.435500000,"lon":-71.670576667,"alt":260.700,"speed":2.483,"mode":3} +$INZDA,194330,16,09,2006,-05,00*76 +$INMTW,18.5,C*18 +$INDPT,2.6,0.0*43 +$INRMC,194330,A,4426.1300,N,07140.2346,W,5.2,84.3,160906,15.8,W*61 +{"class":"TPV","tag":"RMC","time":1158435810.000,"ept":0.005,"lat":44.435500000,"lon":-71.670576667,"alt":260.700,"track":84.3000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.7,0.0*42 +$INGLL,4426.1300,N,07140.2302,W,194332,A*21 +{"class":"TPV","tag":"GLL","time":1158435812.000,"ept":0.005,"lat":44.435500000,"lon":-71.670503333,"speed":2.919,"mode":2} +$INVTG,85.4,T,101.2,M,5.2,N,9.7,K*6C +$INMTW,18.5,C*18 +$INDPT,2.8,0.0*4D +$INRMC,194332,A,4426.1300,N,07140.2302,W,5.2,85.4,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435812.000,"ept":0.005,"lat":44.435500000,"lon":-71.670503333,"track":85.4000,"speed":2.675,"mode":2} +$INDPT,2.9,0.0*4C +$INGGA,194334,4426.1304,N,07140.2265,W,2,09,0.9,260.7,M,,,,*18 +{"class":"TPV","tag":"GGA","time":1158435814.000,"ept":0.005,"lat":44.435506667,"lon":-71.670441667,"alt":260.700,"speed":2.483,"mode":3} +$INZDA,194334,16,09,2006,-05,00*72 +$INMTW,18.3,C*1E +$INDPT,3.1,0.0*45 +$INRMC,194334,A,4426.1304,N,07140.2265,W,5.2,84.2,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435814.000,"ept":0.005,"lat":44.435506667,"lon":-71.670441667,"alt":260.700,"track":84.2000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,3.3,0.0*47 +$INGLL,4426.1308,N,07140.2222,W,194336,A*2E +{"class":"TPV","tag":"GLL","time":1158435816.000,"ept":0.005,"lat":44.435513333,"lon":-71.670370000,"speed":2.877,"mode":2} +$INVTG,84.3,T,100.1,M,5.2,N,9.7,K*68 +$INMTW,18.4,C*19 +$INDPT,3.3,0.0*47 +$INRMC,194336,A,4426.1308,N,07140.2222,W,5.2,84.3,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435816.000,"ept":0.005,"lat":44.435513333,"lon":-71.670370000,"track":84.3000,"speed":2.675,"mode":2} +$INDPT,3.6,0.0*42 +$INGGA,194338,4426.1308,N,07140.2179,W,2,09,0.9,260.6,M,,,,*17 +{"class":"TPV","tag":"GGA","time":1158435818.000,"ept":0.005,"lat":44.435513333,"lon":-71.670298333,"alt":260.600,"speed":2.853,"mode":3} +$INZDA,194338,16,09,2006,-05,00*7E +$INMTW,18.3,C*1E +$INDPT,3.7,0.0*43 +$INRMC,194338,A,4426.1308,N,07140.2179,W,5.3,85.1,160906,15.8,W*6D +{"class":"TPV","tag":"RMC","time":1158435818.000,"ept":0.005,"lat":44.435513333,"lon":-71.670298333,"alt":260.600,"track":85.1000,"speed":2.727,"climb":0.000,"mode":3} +$INDPT,3.5,0.0*41 +$INGLL,4426.1312,N,07140.2141,W,194340,A*22 +{"class":"TPV","tag":"GLL","time":1158435820.000,"ept":0.005,"lat":44.435520000,"lon":-71.670235000,"speed":2.548,"mode":2} +$INVTG,84.2,T,100.0,M,5.3,N,9.8,K*66 +$INMTW,18.3,C*1E +$INDPT,2.3,0.0*46 +$INRMC,194340,A,4426.1312,N,07140.2141,W,5.2,84.2,160906,15.8,W*61 +{"class":"TPV","tag":"RMC","time":1158435820.000,"ept":0.005,"lat":44.435520000,"lon":-71.670235000,"track":84.2000,"speed":2.675,"mode":2} +$INDPT,2.2,0.0*47 +$INGGA,194342,4426.1315,N,07140.2103,W,2,09,0.9,260.6,M,,,,*1B +{"class":"TPV","tag":"GGA","time":1158435822.000,"ept":0.005,"lat":44.435525000,"lon":-71.670171667,"alt":260.600,"speed":2.536,"mode":3} +$INZDA,194342,16,09,2006,-05,00*73 +$INMTW,18.2,C*1F +$INDPT,2.3,0.0*46 +$INRMC,194342,A,4426.1315,N,07140.2103,W,5.2,84.3,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435822.000,"ept":0.005,"lat":44.435525000,"lon":-71.670171667,"alt":260.600,"track":84.3000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.3,0.0*46 +$INGLL,4426.1315,N,07140.2060,W,194344,A*23 +{"class":"TPV","tag":"GLL","time":1158435824.000,"ept":0.005,"lat":44.435525000,"lon":-71.670100000,"speed":2.853,"mode":2} +$INVTG,84.4,T,100.2,M,5.2,N,9.6,K*6D +$INMTW,18.2,C*1F +$INDPT,2.4,0.0*41 +$INRMC,194344,A,4426.1315,N,07140.2060,W,5.1,84.4,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435824.000,"ept":0.005,"lat":44.435525000,"lon":-71.670100000,"track":84.4000,"speed":2.624,"mode":2} +$INDPT,2.6,0.0*43 +$INGGA,194346,4426.1319,N,07140.2022,W,2,09,0.9,260.7,M,,,,*10 +{"class":"TPV","tag":"GGA","time":1158435826.000,"ept":0.005,"lat":44.435531667,"lon":-71.670036667,"alt":260.700,"speed":2.548,"mode":3} +$INZDA,194346,16,09,2006,-05,00*77 +$INMTW,18.3,C*1E +$INDPT,2.7,0.0*42 +$INRMC,194346,A,4426.1319,N,07140.2022,W,5.2,84.2,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435826.000,"ept":0.005,"lat":44.435531667,"lon":-71.670036667,"alt":260.700,"track":84.2000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.1,0.0*44 +$INGLL,4426.1323,N,07140.1979,W,194348,A*28 +{"class":"TPV","tag":"GLL","time":1158435828.000,"ept":0.005,"lat":44.435538333,"lon":-71.669965000,"speed":2.877,"mode":2} +$INVTG,84.7,T,100.5,M,5.2,N,9.7,K*68 +$INMTW,18.3,C*1E +$INDPT,2.1,0.0*44 +$INRMC,194348,A,4426.1323,N,07140.1979,W,5.3,84.7,160906,15.8,W*6F +{"class":"TPV","tag":"RMC","time":1158435828.000,"ept":0.005,"lat":44.435538333,"lon":-71.669965000,"track":84.7000,"speed":2.727,"mode":2} +$INDPT,2.0,0.0*45 +$INGGA,194350,4426.1327,N,07140.1941,W,2,09,0.9,260.7,M,,,,*15 +{"class":"TPV","tag":"GGA","time":1158435830.000,"ept":0.005,"lat":44.435545000,"lon":-71.669901667,"alt":260.700,"speed":2.548,"mode":3} +$INZDA,194350,16,09,2006,-05,00*70 +$INMTW,18.4,C*19 +$INDPT,2.0,0.0*45 +$INRMC,194350,A,4426.1327,N,07140.1941,W,5.2,84.7,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435830.000,"ept":0.005,"lat":44.435545000,"lon":-71.669901667,"alt":260.700,"track":84.7000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.3,0.0*46 +$INGLL,4426.1327,N,07140.1898,W,194352,A*29 +{"class":"TPV","tag":"GLL","time":1158435832.000,"ept":0.005,"lat":44.435545000,"lon":-71.669830000,"speed":2.853,"mode":2} +$INVTG,85.0,T,100.8,M,5.2,N,9.6,K*62 +$INMTW,18.4,C*19 +$INDPT,2.2,0.0*47 +$INRMC,194352,A,4426.1327,N,07140.1898,W,5.2,85.0,160906,15.8,W*69 +{"class":"TPV","tag":"RMC","time":1158435832.000,"ept":0.005,"lat":44.435545000,"lon":-71.669830000,"track":85.0000,"speed":2.675,"mode":2} +$INDPT,2.1,0.0*44 +$INGGA,194354,4426.1331,N,07140.1861,W,2,09,0.9,260.6,M,,,,*14 +{"class":"TPV","tag":"GGA","time":1158435834.000,"ept":0.005,"lat":44.435551667,"lon":-71.669768333,"alt":260.600,"speed":2.483,"mode":3} +$INZDA,194354,16,09,2006,-05,00*74 +$INMTW,18.3,C*1E +$INDPT,2.1,0.0*44 +$INRMC,194354,A,4426.1331,N,07140.1861,W,5.2,81.5,160906,15.8,W*6F +{"class":"TPV","tag":"RMC","time":1158435834.000,"ept":0.005,"lat":44.435551667,"lon":-71.669768333,"alt":260.600,"track":81.5000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.1,0.0*44 +$INGLL,4426.1335,N,07140.1817,W,194356,A*29 +{"class":"TPV","tag":"GLL","time":1158435836.000,"ept":0.005,"lat":44.435558333,"lon":-71.669695000,"speed":2.943,"mode":2} +$INVTG,81.8,T,97.6,M,5.2,N,9.6,K*5F +$INMTW,18.4,C*19 +$INDPT,2.0,0.0*45 +$INRMC,194356,A,4426.1335,N,07140.1817,W,5.2,81.8,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435836.000,"ept":0.005,"lat":44.435558333,"lon":-71.669695000,"track":81.8000,"speed":2.675,"mode":2} +$INDPT,1.9,0.0*4F +$INGGA,194358,4426.1339,N,07140.1780,W,2,09,0.9,260.7,M,,,,*11 +{"class":"TPV","tag":"GGA","time":1158435838.000,"ept":0.005,"lat":44.435565000,"lon":-71.669633333,"alt":260.700,"speed":2.483,"mode":3} +$INZDA,194358,16,09,2006,-05,00*78 +$INMTW,18.4,C*19 +$INDPT,1.9,0.0*4F +$INRMC,194358,A,4426.1339,N,07140.1780,W,5.2,78.8,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435838.000,"ept":0.005,"lat":44.435565000,"lon":-71.669633333,"alt":260.700,"track":78.8000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.1,0.0*44 +$INGLL,4426.1346,N,07140.1737,W,194400,A*24 +{"class":"TPV","tag":"GLL","time":1158435840.000,"ept":0.005,"lat":44.435576667,"lon":-71.669561667,"speed":2.926,"mode":2} +$INVTG,79.6,T,95.4,M,5.2,N,9.6,K*56 +$INMTW,18.4,C*19 +$INDPT,2.1,0.0*44 +$INRMC,194400,A,4426.1346,N,07140.1737,W,5.2,79.6,160906,15.8,W*61 +{"class":"TPV","tag":"RMC","time":1158435840.000,"ept":0.005,"lat":44.435576667,"lon":-71.669561667,"track":79.6000,"speed":2.675,"mode":2} +$INDPT,2.1,0.0*44 +$INGGA,194402,4426.1350,N,07140.1699,W,2,09,0.9,260.9,M,,,,*11 +{"class":"TPV","tag":"GGA","time":1158435842.000,"ept":0.005,"lat":44.435583333,"lon":-71.669498333,"alt":260.900,"speed":2.548,"mode":3} +$INZDA,194402,16,09,2006,-05,00*70 +$INMTW,18.4,C*19 +$INDPT,2.1,0.0*44 +$INRMC,194402,A,4426.1350,N,07140.1699,W,5.2,75.8,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435842.000,"ept":0.005,"lat":44.435583333,"lon":-71.669498333,"alt":260.900,"track":75.8000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.3,0.0*46 +$INGLL,4426.1358,N,07140.1661,W,194404,A*2D +{"class":"TPV","tag":"GLL","time":1158435844.000,"ept":0.005,"lat":44.435596667,"lon":-71.669435000,"speed":2.628,"mode":2} +$INVTG,78.1,T,93.9,M,5.2,N,9.5,K*58 +$INMTW,18.3,C*1E +$INDPT,2.4,0.0*41 +$INRMC,194404,A,4426.1358,N,07140.1661,W,5.2,78.1,160906,15.8,W*6E +{"class":"TPV","tag":"RMC","time":1158435844.000,"ept":0.005,"lat":44.435596667,"lon":-71.669435000,"track":78.1000,"speed":2.675,"mode":2} +$INDPT,2.3,0.0*46 +$INGGA,194406,4426.1362,N,07140.1618,W,2,09,0.9,260.9,M,,,,*1D +{"class":"TPV","tag":"GGA","time":1158435846.000,"ept":0.005,"lat":44.435603333,"lon":-71.669363333,"alt":260.900,"speed":2.877,"mode":3} +$INZDA,194406,16,09,2006,-05,00*74 +$INMTW,18.3,C*1E +$INDPT,2.3,0.0*46 +$INRMC,194406,A,4426.1362,N,07140.1618,W,5.3,79.1,160906,15.8,W*6B +{"class":"TPV","tag":"RMC","time":1158435846.000,"ept":0.005,"lat":44.435603333,"lon":-71.669363333,"alt":260.900,"track":79.1000,"speed":2.727,"climb":0.000,"mode":3} +$INDPT,2.3,0.0*46 +$INGLL,4426.1370,N,07140.1580,W,194408,A*27 +{"class":"TPV","tag":"GLL","time":1158435848.000,"ept":0.005,"lat":44.435616667,"lon":-71.669300000,"speed":2.628,"mode":2} +$INVTG,78.7,T,94.5,M,5.3,N,9.8,K*59 +$INMTW,18.2,C*1F +$INDPT,2.1,0.0*44 +$INRMC,194408,A,4426.1370,N,07140.1580,W,5.2,78.7,160906,15.8,W*62 +{"class":"TPV","tag":"RMC","time":1158435848.000,"ept":0.005,"lat":44.435616667,"lon":-71.669300000,"track":78.7000,"speed":2.675,"mode":2} +$INDPT,2.0,0.0*45 +$INGGA,194410,4426.1373,N,07140.1537,W,2,09,0.9,261.1,M,,,,*1D +{"class":"TPV","tag":"GGA","time":1158435850.000,"ept":0.005,"lat":44.435621667,"lon":-71.669228333,"alt":261.100,"speed":2.866,"mode":3} +$INZDA,194410,16,09,2006,-05,00*73 +$INMTW,18.2,C*1F +$INDPT,2.0,0.0*45 +$INRMC,194410,A,4426.1373,N,07140.1537,W,5.2,80.2,160906,15.8,W*66 +{"class":"TPV","tag":"RMC","time":1158435850.000,"ept":0.005,"lat":44.435621667,"lon":-71.669228333,"alt":261.100,"track":80.2000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.0,0.0*45 +$INGLL,4426.1377,N,07140.1499,W,194412,A*22 +{"class":"TPV","tag":"GLL","time":1158435852.000,"ept":0.005,"lat":44.435628333,"lon":-71.669165000,"speed":2.548,"mode":2} +$INVTG,79.6,T,95.3,M,5.2,N,9.7,K*50 +$INMTW,18.1,C*1C +$INDPT,2.3,0.0*46 +$INRMC,194412,A,4426.1377,N,07140.1499,W,5.2,79.6,160906,15.8,W*67 +{"class":"TPV","tag":"RMC","time":1158435852.000,"ept":0.005,"lat":44.435628333,"lon":-71.669165000,"track":79.6000,"speed":2.675,"mode":2} +$INDPT,2.2,0.0*47 +$INGGA,194414,4426.1381,N,07140.1462,W,2,09,0.9,261.1,M,,,,*15 +{"class":"TPV","tag":"GGA","time":1158435854.000,"ept":0.005,"lat":44.435635000,"lon":-71.669103333,"alt":261.100,"speed":2.483,"mode":3} +$INZDA,194414,16,09,2006,-05,00*77 +$INMTW,18.2,C*1F +$INDPT,1.8,0.0*4E +$INRMC,194414,A,4426.1381,N,07140.1462,W,5.2,79.9,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435854.000,"ept":0.005,"lat":44.435635000,"lon":-71.669103333,"alt":261.100,"track":79.9000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,1.8,0.0*4E +$INGLL,4426.1389,N,07140.1419,W,194416,A*2F +{"class":"TPV","tag":"GLL","time":1158435856.000,"ept":0.005,"lat":44.435648333,"lon":-71.669031667,"speed":2.948,"mode":2} +$INVTG,80.2,T,96.0,M,5.2,N,9.7,K*52 +$INMTW,18.1,C*1C +$INDPT,1.8,0.0*4E +$INRMC,194416,A,4426.1389,N,07140.1419,W,5.2,80.2,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435856.000,"ept":0.005,"lat":44.435648333,"lon":-71.669031667,"track":80.2000,"speed":2.675,"mode":2} +$INDPT,2.0,0.0*45 +$INGGA,194418,4426.1393,N,07140.1381,W,2,10,0.9,261.1,M,,,,*18 +{"class":"TPV","tag":"GGA","time":1158435858.000,"ept":0.005,"lat":44.435655000,"lon":-71.668968333,"alt":261.100,"speed":2.548,"mode":3} +$INZDA,194418,16,09,2006,-05,00*7B +$INMTW,18.0,C*1D +$INDPT,2.1,0.0*44 +$INRMC,194418,A,4426.1393,N,07140.1381,W,5.2,81.2,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435858.000,"ept":0.005,"lat":44.435655000,"lon":-71.668968333,"alt":261.100,"track":81.2000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.3,0.0*46 +$INGLL,4426.1397,N,07140.1338,W,194420,A*21 +{"class":"TPV","tag":"GLL","time":1158435860.000,"ept":0.005,"lat":44.435661667,"lon":-71.668896667,"speed":2.877,"mode":2} +$INVTG,81.6,T,97.4,M,5.2,N,9.6,K*53 +$INMTW,18.1,C*1C +$INDPT,1.9,0.0*4F +$INRMC,194420,A,4426.1397,N,07140.1338,W,5.2,81.6,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435860.000,"ept":0.005,"lat":44.435661667,"lon":-71.668896667,"track":81.6000,"speed":2.675,"mode":2} +$INDPT,1.9,0.0*4F +$INGGA,194422,4426.1400,N,07140.1300,W,2,10,1.1,261.4,M,,,,*19 +{"class":"TPV","tag":"GGA","time":1158435862.000,"ept":0.005,"lat":44.435666667,"lon":-71.668833333,"alt":261.400,"speed":2.536,"mode":3} +$INZDA,194422,16,09,2006,-05,00*72 +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194422,A,4426.1400,N,07140.1300,W,5.2,80.4,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435862.000,"ept":0.005,"lat":44.435666667,"lon":-71.668833333,"alt":261.400,"track":80.4000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,1.9,0.0*4F +$INGLL,4426.1404,N,07140.1257,W,194424,A*20 +{"class":"TPV","tag":"GLL","time":1158435864.000,"ept":0.005,"lat":44.435673333,"lon":-71.668761667,"speed":2.877,"mode":2} +$INVTG,80.0,T,95.8,M,5.2,N,9.6,K*5A +$INMTW,18.0,C*1D +$INDPT,2.0,0.0*45 +$INRMC,194424,A,4426.1404,N,07140.1257,W,5.2,80.0,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435864.000,"ept":0.005,"lat":44.435673333,"lon":-71.668761667,"track":80.0000,"speed":2.675,"mode":2} +$INDPT,2.1,0.0*44 +$INGGA,194426,4426.1412,N,07140.1219,W,2,10,0.9,261.4,M,,,,*1E +{"class":"TPV","tag":"GGA","time":1158435866.000,"ept":0.005,"lat":44.435686667,"lon":-71.668698333,"alt":261.400,"speed":2.628,"mode":3} +$INZDA,194426,16,09,2006,-05,00*76 +$INMTW,17.9,C*1B +$INDPT,2.1,0.0*44 +$INRMC,194426,A,4426.1412,N,07140.1219,W,5.2,79.4,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435866.000,"ept":0.005,"lat":44.435686667,"lon":-71.668698333,"alt":261.400,"track":79.4000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,1.9,0.0*4F +$INGLL,4426.1416,N,07140.1181,W,194428,A*27 +{"class":"TPV","tag":"GLL","time":1158435868.000,"ept":0.005,"lat":44.435693333,"lon":-71.668635000,"speed":2.548,"mode":2} +$INVTG,78.2,T,93.9,M,5.2,N,9.7,K*59 +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194428,A,4426.1416,N,07140.1181,W,5.2,78.2,160906,15.8,W*67 +{"class":"TPV","tag":"RMC","time":1158435868.000,"ept":0.005,"lat":44.435693333,"lon":-71.668635000,"track":78.2000,"speed":2.675,"mode":2} +$INDPT,1.9,0.0*4F +$INGGA,194430,4426.1424,N,07140.1138,W,2,10,0.9,261.3,M,,,,*1B +{"class":"TPV","tag":"GGA","time":1158435870.000,"ept":0.005,"lat":44.435706667,"lon":-71.668563333,"alt":261.300,"speed":2.948,"mode":3} +$INZDA,194430,16,09,2006,-05,00*71 +$INMTW,17.9,C*1B +$INDPT,2.0,0.0*45 +$INRMC,194430,A,4426.1424,N,07140.1138,W,5.2,78.4,160906,15.8,W*6B +{"class":"TPV","tag":"RMC","time":1158435870.000,"ept":0.005,"lat":44.435706667,"lon":-71.668563333,"alt":261.300,"track":78.4000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.0,0.0*45 +$INGLL,4426.1431,N,07140.1101,W,194432,A*21 +{"class":"TPV","tag":"GLL","time":1158435872.000,"ept":0.005,"lat":44.435718333,"lon":-71.668501667,"speed":2.539,"mode":2} +$INVTG,76.1,T,91.8,M,5.2,N,9.7,K*57 +$INMTW,17.9,C*1B +$INDPT,2.1,0.0*44 +$INRMC,194432,A,4426.1431,N,07140.1101,W,5.2,76.1,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435872.000,"ept":0.005,"lat":44.435718333,"lon":-71.668501667,"track":76.1000,"speed":2.675,"mode":2} +$INDPT,2.1,0.0*44 +$INGGA,194434,4426.1435,N,07140.1063,W,2,10,0.9,261.5,M,,,,*16 +{"class":"TPV","tag":"GGA","time":1158435874.000,"ept":0.005,"lat":44.435725000,"lon":-71.668438333,"alt":261.500,"speed":2.548,"mode":3} +$INZDA,194434,16,09,2006,-05,00*75 +$INMTW,17.9,C*1B +$INDPT,2.2,0.0*47 +$INRMC,194434,A,4426.1435,N,07140.1063,W,5.2,75.9,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435874.000,"ept":0.005,"lat":44.435725000,"lon":-71.668438333,"alt":261.500,"track":75.9000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,2.1,0.0*44 +$INGLL,4426.1443,N,07140.1020,W,194436,A*22 +{"class":"TPV","tag":"GLL","time":1158435876.000,"ept":0.005,"lat":44.435738333,"lon":-71.668366667,"speed":2.948,"mode":2} +$INVTG,75.1,T,90.9,M,5.2,N,9.6,K*55 +$INMTW,18.0,C*1D +$INDPT,2.1,0.0*44 +$INRMC,194436,A,4426.1443,N,07140.1020,W,5.2,75.1,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435876.000,"ept":0.005,"lat":44.435738333,"lon":-71.668366667,"track":75.1000,"speed":2.675,"mode":2} +$INDPT,2.1,0.0*44 +$INGGA,194438,4426.1451,N,07140.0982,W,2,10,0.9,261.7,M,,,,*1D +{"class":"TPV","tag":"GGA","time":1158435878.000,"ept":0.005,"lat":44.435751667,"lon":-71.668303333,"alt":261.700,"speed":2.628,"mode":3} +$INZDA,194438,16,09,2006,-05,00*79 +$INMTW,17.9,C*1B +$INDPT,1.5,0.0*43 +$INRMC,194438,A,4426.1451,N,07140.0982,W,5.1,74.2,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435878.000,"ept":0.005,"lat":44.435751667,"lon":-71.668303333,"alt":261.700,"track":74.2000,"speed":2.624,"climb":0.000,"mode":3} +$INDPT,1.5,0.0*43 +$INGLL,4426.1458,N,07140.0944,W,194440,A*23 +{"class":"TPV","tag":"GLL","time":1158435880.000,"ept":0.005,"lat":44.435763333,"lon":-71.668240000,"speed":2.603,"mode":2} +$INVTG,73.9,T,89.7,M,5.1,N,9.5,K*5D +$INMTW,17.9,C*1B +$INDPT,1.5,0.0*43 +$INRMC,194440,A,4426.1458,N,07140.0944,W,5.2,73.9,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435880.000,"ept":0.005,"lat":44.435763333,"lon":-71.668240000,"track":73.9000,"speed":2.675,"mode":2} +$INDPT,1.5,0.0*43 +$INGGA,194442,4426.1466,N,07140.0907,W,2,09,1.1,261.7,M,,,,*18 +{"class":"TPV","tag":"GGA","time":1158435882.000,"ept":0.005,"lat":44.435776667,"lon":-71.668178333,"alt":261.700,"speed":2.564,"mode":3} +$INZDA,194442,16,09,2006,-05,00*74 +$INMTW,17.9,C*1B +$INDPT,1.5,0.0*43 +$INRMC,194442,A,4426.1466,N,07140.0907,W,5.1,73.5,160906,15.8,W*64 +{"class":"TPV","tag":"RMC","time":1158435882.000,"ept":0.005,"lat":44.435776667,"lon":-71.668178333,"alt":261.700,"track":73.5000,"speed":2.624,"climb":0.000,"mode":3} +$INDPT,1.5,0.0*43 +$INGLL,4426.1474,N,07140.0869,W,194444,A*27 +{"class":"TPV","tag":"GLL","time":1158435884.000,"ept":0.005,"lat":44.435790000,"lon":-71.668115000,"speed":2.628,"mode":2} +$INVTG,73.2,T,89.0,M,5.1,N,9.5,K*51 +$INMTW,17.9,C*1B +$INDPT,1.6,0.0*40 +$INRMC,194444,A,4426.1474,N,07140.0869,W,5.1,73.2,160906,15.8,W*6F +{"class":"TPV","tag":"RMC","time":1158435884.000,"ept":0.005,"lat":44.435790000,"lon":-71.668115000,"track":73.2000,"speed":2.624,"mode":2} +$INDPT,1.7,0.0*41 +$INGGA,194446,4426.1482,N,07140.0831,W,2,10,1.1,261.8,M,,,,*15 +{"class":"TPV","tag":"GGA","time":1158435886.000,"ept":0.005,"lat":44.435803333,"lon":-71.668051667,"alt":261.800,"speed":2.628,"mode":3} +$INZDA,194446,16,09,2006,-05,00*70 +$INMTW,17.8,C*1A +$INDPT,1.6,0.0*40 +$INRMC,194446,A,4426.1482,N,07140.0831,W,5.1,71.7,160906,15.8,W*6E +{"class":"TPV","tag":"RMC","time":1158435886.000,"ept":0.005,"lat":44.435803333,"lon":-71.668051667,"alt":261.800,"track":71.7000,"speed":2.624,"climb":0.000,"mode":3} +$INDPT,1.7,0.0*41 +$INGLL,4426.1493,N,07140.0793,W,194448,A*28 +{"class":"TPV","tag":"GLL","time":1158435888.000,"ept":0.005,"lat":44.435821667,"lon":-71.667988333,"speed":2.719,"mode":2} +$INVTG,72.0,T,87.8,M,5.1,N,9.5,K*54 +$INMTW,17.9,C*1B +$INDPT,1.8,0.0*4E +$INRMC,194448,A,4426.1493,N,07140.0793,W,5.2,72.0,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435888.000,"ept":0.005,"lat":44.435821667,"lon":-71.667988333,"track":72.0000,"speed":2.675,"mode":2} +$INDPT,1.8,0.0*4E +$INGGA,194450,4426.1501,N,07140.0756,W,2,10,1.1,261.9,M,,,,*17 +{"class":"TPV","tag":"GGA","time":1158435890.000,"ept":0.005,"lat":44.435835000,"lon":-71.667926667,"alt":261.900,"speed":2.564,"mode":3} +$INZDA,194450,16,09,2006,-05,00*77 +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194450,A,4426.1501,N,07140.0756,W,5.2,70.4,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435890.000,"ept":0.005,"lat":44.435835000,"lon":-71.667926667,"alt":261.900,"track":70.4000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,1.8,0.0*4E +$INGLL,4426.1512,N,07140.0718,W,194452,A*28 +{"class":"TPV","tag":"GLL","time":1158435892.000,"ept":0.005,"lat":44.435853333,"lon":-71.667863333,"speed":2.719,"mode":2} +$INVTG,70.7,T,86.5,M,5.2,N,9.6,K*5D +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194452,A,4426.1512,N,07140.0718,W,5.2,70.7,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435892.000,"ept":0.005,"lat":44.435853333,"lon":-71.667863333,"track":70.7000,"speed":2.675,"mode":2} +$INDPT,1.8,0.0*4E +$INGGA,194454,4426.1520,N,07140.0680,W,2,11,0.9,261.9,M,,,,*12 +{"class":"TPV","tag":"GGA","time":1158435894.000,"ept":0.005,"lat":44.435866667,"lon":-71.667800000,"alt":261.900,"speed":2.628,"mode":3} +$INZDA,194454,16,09,2006,-05,00*73 +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194454,A,4426.1520,N,07140.0680,W,5.3,69.4,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435894.000,"ept":0.005,"lat":44.435866667,"lon":-71.667800000,"alt":261.900,"track":69.4000,"speed":2.727,"climb":0.000,"mode":3} +$INDPT,2.0,0.0*45 +$INGLL,4426.1532,N,07140.0642,W,194456,A*20 +{"class":"TPV","tag":"GLL","time":1158435896.000,"ept":0.005,"lat":44.435886667,"lon":-71.667736667,"speed":2.755,"mode":2} +$INVTG,68.7,T,84.5,M,5.3,N,9.7,K*56 +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194456,A,4426.1532,N,07140.0642,W,5.2,68.7,160906,15.8,W*64 +{"class":"TPV","tag":"RMC","time":1158435896.000,"ept":0.005,"lat":44.435886667,"lon":-71.667736667,"track":68.7000,"speed":2.675,"mode":2} +$INDPT,1.8,0.0*4E +$INGGA,194458,4426.1543,N,07140.0605,W,2,10,1.1,262.0,M,,,,*14 +{"class":"TPV","tag":"GGA","time":1158435898.000,"ept":0.005,"lat":44.435905000,"lon":-71.667675000,"alt":262.000,"speed":2.658,"mode":3} +$INZDA,194458,16,09,2006,-05,00*7F +$INMTW,17.9,C*1B +$INDPT,1.8,0.0*4E +$INRMC,194458,A,4426.1543,N,07140.0605,W,5.3,68.4,160906,15.8,W*6D +{"class":"TPV","tag":"RMC","time":1158435898.000,"ept":0.005,"lat":44.435905000,"lon":-71.667675000,"alt":262.000,"track":68.4000,"speed":2.727,"climb":0.000,"mode":3} +$INDPT,1.9,0.0*4F +$INGLL,4426.1555,N,07140.0567,W,194500,A*27 +{"class":"TPV","tag":"GLL","time":1158435900.000,"ept":0.005,"lat":44.435925000,"lon":-71.667611667,"speed":2.755,"mode":2} +$INVTG,67.8,T,83.6,M,5.3,N,9.8,K*5D +$INMTW,17.9,C*1B +$INDPT,1.9,0.0*4F +$INRMC,194500,A,4426.1555,N,07140.0567,W,5.2,67.8,160906,15.8,W*63 +{"class":"TPV","tag":"RMC","time":1158435900.000,"ept":0.005,"lat":44.435925000,"lon":-71.667611667,"track":67.8000,"speed":2.675,"mode":2} +$INDPT,1.9,0.0*4F +$INGGA,194502,4426.1563,N,07140.0529,W,2,10,1.1,262.0,M,,,,*15 +{"class":"TPV","tag":"GGA","time":1158435902.000,"ept":0.005,"lat":44.435938333,"lon":-71.667548333,"alt":262.000,"speed":2.628,"mode":3} +$INZDA,194502,16,09,2006,-05,00*71 +$INMTW,17.8,C*1A +$INDPT,1.9,0.0*4F +$INRMC,194502,A,4426.1563,N,07140.0529,W,5.2,68.6,160906,15.8,W*6F +{"class":"TPV","tag":"RMC","time":1158435902.000,"ept":0.005,"lat":44.435938333,"lon":-71.667548333,"alt":262.000,"track":68.6000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,1.9,0.0*4F +$INGLL,4426.1574,N,07140.0492,W,194504,A*2B +{"class":"TPV","tag":"GLL","time":1158435904.000,"ept":0.005,"lat":44.435956667,"lon":-71.667486667,"speed":2.658,"mode":2} +$INVTG,67.6,T,83.4,M,5.2,N,9.7,K*5F +$INMTW,17.8,C*1A +$INDPT,1.9,0.0*4F +$INRMC,194504,A,4426.1574,N,07140.0492,W,5.2,67.6,160906,15.8,W*61 +{"class":"TPV","tag":"RMC","time":1158435904.000,"ept":0.005,"lat":44.435956667,"lon":-71.667486667,"track":67.6000,"speed":2.675,"mode":2} +$INDPT,1.8,0.0*4E +$INGGA,194506,4426.1586,N,07140.0454,W,2,10,1.1,261.9,M,,,,*1B +{"class":"TPV","tag":"GGA","time":1158435906.000,"ept":0.005,"lat":44.435976667,"lon":-71.667423333,"alt":261.900,"speed":2.755,"mode":3} +$INZDA,194506,16,09,2006,-05,00*75 +$INMTW,17.7,C*15 +$INDPT,1.8,0.0*4E +$INRMC,194506,A,4426.1586,N,07140.0454,W,5.3,68.6,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435906.000,"ept":0.005,"lat":44.435976667,"lon":-71.667423333,"alt":261.900,"track":68.6000,"speed":2.727,"climb":0.000,"mode":3} +$INDPT,1.8,0.0*4E +$INGLL,4426.1597,N,07140.0416,W,194508,A*26 +{"class":"TPV","tag":"GLL","time":1158435908.000,"ept":0.005,"lat":44.435995000,"lon":-71.667360000,"speed":2.719,"mode":2} +$INVTG,68.2,T,84.0,M,5.3,N,9.7,K*56 +$INMTW,17.8,C*1A +$INDPT,1.9,0.0*4F +$INRMC,194508,A,4426.1597,N,07140.0416,W,5.2,68.2,160906,15.8,W*67 +{"class":"TPV","tag":"RMC","time":1158435908.000,"ept":0.005,"lat":44.435995000,"lon":-71.667360000,"track":68.2000,"speed":2.675,"mode":2} +$INDPT,1.9,0.0*4F +$INGGA,194510,4426.1609,N,07140.0378,W,2,10,1.1,262.0,M,,,,*1B +{"class":"TPV","tag":"GGA","time":1158435910.000,"ept":0.005,"lat":44.436015000,"lon":-71.667296667,"alt":262.000,"speed":2.755,"mode":3} +$INZDA,194510,16,09,2006,-05,00*72 +$INMTW,17.9,C*1B +$INDPT,1.6,0.0*40 +$INRMC,194510,A,4426.1609,N,07140.0378,W,5.2,68.1,160906,15.8,W*66 +{"class":"TPV","tag":"RMC","time":1158435910.000,"ept":0.005,"lat":44.436015000,"lon":-71.667296667,"alt":262.000,"track":68.1000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,1.6,0.0*40 +$INGLL,4426.1617,N,07140.0341,W,194512,A*23 +{"class":"TPV","tag":"GLL","time":1158435912.000,"ept":0.005,"lat":44.436028333,"lon":-71.667235000,"speed":2.564,"mode":2} +$INVTG,68.0,T,83.8,M,5.2,N,9.7,K*5A +$INMTW,17.8,C*1A +$INDPT,1.7,0.0*41 +$INRMC,194512,A,4426.1617,N,07140.0341,W,5.2,68.0,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435912.000,"ept":0.005,"lat":44.436028333,"lon":-71.667235000,"track":68.0000,"speed":2.675,"mode":2} +$INDPT,1.7,0.0*41 +$INGGA,194514,4426.1628,N,07140.0303,W,2,10,1.1,262.0,M,,,,*10 +{"class":"TPV","tag":"GGA","time":1158435914.000,"ept":0.005,"lat":44.436046667,"lon":-71.667171667,"alt":262.000,"speed":2.719,"mode":3} +$INZDA,194514,16,09,2006,-05,00*76 +$INMTW,17.8,C*1A +$INDPT,1.8,0.0*4E +$INRMC,194514,A,4426.1628,N,07140.0303,W,5.2,67.6,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435914.000,"ept":0.005,"lat":44.436046667,"lon":-71.667171667,"alt":262.000,"track":67.6000,"speed":2.675,"climb":0.000,"mode":3} +$INDPT,1.9,0.0*4F +$INGLL,4426.1636,N,07140.0281,W,194515,A*2A +{"class":"TPV","tag":"GLL","time":1158435915.000,"ept":0.005,"lat":44.436060000,"lon":-71.667135000,"speed":3.274,"mode":2} +$INVTG,67.5,T,83.3,M,5.2,N,9.6,K*5A +$INMTW,17.9,C*1B +$INDPT,1.6,0.0*40 +$INRMC,194516,A,4426.1640,N,07140.0265,W,5.2,68.1,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435916.000,"ept":0.005,"lat":44.436066667,"lon":-71.667108333,"track":68.1000,"speed":2.675,"mode":2} +$INDPT,1.6,0.0*40 +$INGGA,194517,4426.1644,N,07140.0244,W,2,10,1.1,262.0,M,,,,*1B +{"class":"TPV","tag":"GGA","time":1158435917.000,"ept":0.005,"lat":44.436073333,"lon":-71.667073333,"alt":262.000,"speed":2.883,"mode":3} +$INZDA,194517,16,09,2006,-05,00*75 +$INMTW,17.7,C*15 +$INDPT,1.6,0.0*40 +$INRMC,194518,A,4426.1651,N,07140.0227,W,5.2,69.2,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435918.000,"ept":0.005,"lat":44.436085000,"lon":-71.667045000,"track":69.2000,"speed":2.675,"mode":2} +$INDPT,1.6,0.0*40 +$INGLL,4426.1655,N,07140.0206,W,194519,A*2C +{"class":"TPV","tag":"GLL","time":1158435919.000,"ept":0.005,"lat":44.436091667,"lon":-71.667010000,"speed":2.883,"mode":2} +$INVTG,69.0,T,84.8,M,5.2,N,9.7,K*5C +$INMTW,17.9,C*1B +$INDPT,1.7,0.0*41 +$INRMC,194520,A,4426.1663,N,07140.0190,W,5.2,68.6,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435920.000,"ept":0.005,"lat":44.436105000,"lon":-71.666983333,"track":68.6000,"speed":2.675,"mode":2} +$INDPT,1.7,0.0*41 +$INGGA,194521,4426.1667,N,07140.0168,W,2,10,1.1,261.9,M,,,,*18 +{"class":"TPV","tag":"GGA","time":1158435921.000,"ept":0.005,"lat":44.436111667,"lon":-71.666946667,"alt":261.900,"speed":3.012,"mode":3} +$INZDA,194521,16,09,2006,-05,00*70 +$INMTW,17.9,C*1B +$INDPT,1.8,0.0*4E +$INRMC,194522,A,4426.1671,N,07140.0152,W,5.2,69.5,160906,15.8,W*67 +{"class":"TPV","tag":"RMC","time":1158435922.000,"ept":0.005,"lat":44.436118333,"lon":-71.666920000,"track":69.5000,"speed":2.675,"mode":2} +$INDPT,1.6,0.0*40 +$INGLL,4426.1678,N,07140.0136,W,194523,A*2A +{"class":"TPV","tag":"GLL","time":1158435923.000,"ept":0.005,"lat":44.436130000,"lon":-71.666893333,"speed":2.488,"mode":2} +$INVTG,69.4,T,85.2,M,5.2,N,9.6,K*52 +$INMTW,17.9,C*1B +$INDPT,1.5,0.0*43 +$INRMC,194524,A,4426.1682,N,07140.0114,W,5.2,68.7,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435924.000,"ept":0.005,"lat":44.436136667,"lon":-71.666856667,"track":68.7000,"speed":2.675,"mode":2} +$INDPT,1.6,0.0*40 +$INGGA,194525,4426.1686,N,07140.0098,W,2,10,1.1,261.8,M,,,,*1C +{"class":"TPV","tag":"GGA","time":1158435925.000,"ept":0.005,"lat":44.436143333,"lon":-71.666830000,"alt":261.800,"speed":2.249,"mode":3} +$INZDA,194525,16,09,2006,-05,00*74 +$INMTW,17.9,C*1B +$INDPT,1.7,0.0*41 +$INRMC,194526,A,4426.1694,N,07140.0077,W,5.1,69.4,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435926.000,"ept":0.005,"lat":44.436156667,"lon":-71.666795000,"track":69.4000,"speed":2.624,"mode":2} +$INDPT,1.9,0.0*4F +$INGLL,4426.1698,N,07140.0060,W,194527,A*22 +{"class":"TPV","tag":"GLL","time":1158435927.000,"ept":0.005,"lat":44.436163333,"lon":-71.666766667,"speed":2.374,"mode":2} +$INVTG,70.2,T,86.0,M,5.1,N,9.5,K*5D +$INMTW,17.8,C*1A +$INDPT,1.9,0.0*4F +$INRMC,194528,A,4426.1702,N,07140.0039,W,5.2,70.5,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435928.000,"ept":0.005,"lat":44.436170000,"lon":-71.666731667,"track":70.5000,"speed":2.675,"mode":2} +$INDPT,1.4,0.0*42 +$INGGA,194529,4426.1705,N,07140.0023,W,2,11,0.9,261.8,M,,,,*12 +{"class":"TPV","tag":"GGA","time":1158435929.000,"ept":0.005,"lat":44.436175000,"lon":-71.666705000,"alt":261.800,"speed":2.195,"mode":3} +$INZDA,194529,16,09,2006,-05,00*78 +$INMTW,17.8,C*1A +$INDPT,1.3,0.0*45 +$INRMC,194530,A,4426.1713,N,07140.0001,W,5.2,69.8,160906,15.8,W*6B +{"class":"TPV","tag":"RMC","time":1158435930.000,"ept":0.005,"lat":44.436188333,"lon":-71.666668333,"track":69.8000,"speed":2.675,"mode":2} +$INDPT,1.3,0.0*45 +$INGLL,4426.1717,N,07139.9985,W,194531,A*26 +{"class":"TPV","tag":"GLL","time":1158435931.000,"ept":0.005,"lat":44.436195000,"lon":-71.666641667,"speed":2.249,"mode":2} +$INVTG,70.1,T,85.8,M,5.2,N,9.6,K*55 +$INMTW,17.6,C*14 +$INDPT,1.4,0.0*42 +$INRMC,194532,A,4426.1721,N,07139.9963,W,5.1,71.0,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435932.000,"ept":0.005,"lat":44.436201667,"lon":-71.666605000,"track":71.0000,"speed":2.624,"mode":2} +$INDPT,1.4,0.0*42 +$INGGA,194533,4426.1725,N,07139.9947,W,2,11,0.9,261.6,M,,,,*19 +{"class":"TPV","tag":"GGA","time":1158435933.000,"ept":0.005,"lat":44.436208333,"lon":-71.666578333,"alt":261.600,"speed":2.249,"mode":3} +$INZDA,194533,16,09,2006,-05,00*73 +$INMTW,17.6,C*14 +$INDPT,1.4,0.0*42 +$INRMC,194534,A,4426.1729,N,07139.9926,W,5.1,71.6,160906,15.8,W*69 +{"class":"TPV","tag":"RMC","time":1158435934.000,"ept":0.005,"lat":44.436215000,"lon":-71.666543333,"track":71.6000,"speed":2.624,"mode":2} +$INDPT,1.5,0.0*43 +$INGLL,4426.1736,N,07139.9909,W,194535,A*25 +{"class":"TPV","tag":"GLL","time":1158435935.000,"ept":0.005,"lat":44.436226667,"lon":-71.666515000,"speed":2.602,"mode":2} +$INVTG,71.0,T,86.8,M,5.1,N,9.5,K*56 +$INMTW,17.6,C*14 +$INDPT,1.5,0.0*43 +$INRMC,194536,A,4426.1740,N,07139.9888,W,5.1,70.9,160906,15.8,W*6F +{"class":"TPV","tag":"RMC","time":1158435936.000,"ept":0.005,"lat":44.436233333,"lon":-71.666480000,"track":70.9000,"speed":2.624,"mode":2} +$INDPT,1.5,0.0*43 +$INGGA,194537,4426.1744,N,07139.9872,W,2,11,0.9,261.6,M,,,,*1D +{"class":"TPV","tag":"GGA","time":1158435937.000,"ept":0.005,"lat":44.436240000,"lon":-71.666453333,"alt":261.600,"speed":2.249,"mode":3} +$INZDA,194537,16,09,2006,-05,00*77 +$INMTW,17.6,C*14 +$INDPT,1.6,0.0*40 +$INRMC,194538,A,4426.1748,N,07139.9850,W,5.2,73.3,160906,15.8,W*66 +{"class":"TPV","tag":"RMC","time":1158435938.000,"ept":0.005,"lat":44.436246667,"lon":-71.666416667,"track":73.3000,"speed":2.675,"mode":2} +$INDPT,1.8,0.0*4E +$INGLL,4426.1752,N,07139.9834,W,194539,A*24 +{"class":"TPV","tag":"GLL","time":1158435939.000,"ept":0.005,"lat":44.436253333,"lon":-71.666390000,"speed":2.249,"mode":2} +$INVTG,71.8,T,87.6,M,5.2,N,9.7,K*50 +$INMTW,17.5,C*17 +$INDPT,1.9,0.0*4F +$INRMC,194540,A,4426.1756,N,07139.9812,W,5.3,69.1,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435940.000,"ept":0.005,"lat":44.436260000,"lon":-71.666353333,"track":69.1000,"speed":2.727,"mode":2} +$INDPT,1.9,0.0*4F +$INGGA,194541,4426.1763,N,07139.9796,W,2,11,0.9,261.5,M,,,,*1F +{"class":"TPV","tag":"GGA","time":1158435941.000,"ept":0.005,"lat":44.436271667,"lon":-71.666326667,"alt":261.500,"speed":2.488,"mode":3} +$INZDA,194541,16,09,2006,-05,00*76 +$INMTW,17.6,C*14 +$INDPT,1.4,0.0*42 +$INRMC,194542,A,4426.1767,N,07139.9775,W,5.2,67.7,160906,15.8,W*6F +{"class":"TPV","tag":"RMC","time":1158435942.000,"ept":0.005,"lat":44.436278333,"lon":-71.666291667,"track":67.7000,"speed":2.675,"mode":2} +$INDPT,1.5,0.0*43 +$INGLL,4426.1775,N,07139.9759,W,194543,A*28 +{"class":"TPV","tag":"GLL","time":1158435943.000,"ept":0.005,"lat":44.436291667,"lon":-71.666265000,"speed":2.589,"mode":2} +$INVTG,67.9,T,83.7,M,5.2,N,9.6,K*52 +$INMTW,17.5,C*17 +$INDPT,1.6,0.0*40 +$INRMC,194544,A,4426.1779,N,07139.9737,W,5.2,67.3,160906,15.8,W*64 +{"class":"TPV","tag":"RMC","time":1158435944.000,"ept":0.005,"lat":44.436298333,"lon":-71.666228333,"track":67.3000,"speed":2.675,"mode":2} +$INDPT,1.7,0.0*41 +$INGGA,194545,4426.1787,N,07139.9721,W,2,11,0.9,261.3,M,,,,*1B +{"class":"TPV","tag":"GGA","time":1158435945.000,"ept":0.005,"lat":44.436311667,"lon":-71.666201667,"alt":261.300,"speed":2.589,"mode":3} +$INZDA,194545,16,09,2006,-05,00*72 +$INMTW,17.5,C*17 +$INDPT,1.7,0.0*41 +$INRMC,194546,A,4426.1790,N,07139.9705,W,5.1,65.9,160906,15.8,W*6B +{"class":"TPV","tag":"RMC","time":1158435946.000,"ept":0.005,"lat":44.436316667,"lon":-71.666175000,"track":65.9000,"speed":2.624,"mode":2} +$INDPT,1.7,0.0*41 +$INGLL,4426.1798,N,07139.9683,W,194547,A*29 +{"class":"TPV","tag":"GLL","time":1158435947.000,"ept":0.005,"lat":44.436330000,"lon":-71.666138333,"speed":3.274,"mode":2} +$INVTG,65.6,T,81.4,M,5.1,N,9.5,K*5E +$INMTW,17.5,C*17 +$INDPT,1.8,0.0*4E +$INRMC,194548,A,4426.1802,N,07139.9667,W,5.2,64.8,160906,15.8,W*67 +{"class":"TPV","tag":"RMC","time":1158435948.000,"ept":0.005,"lat":44.436336667,"lon":-71.666111667,"track":64.8000,"speed":2.675,"mode":2} +$INDPT,1.9,0.0*4F +$INGGA,194549,4426.1810,N,07139.9651,W,2,11,0.9,261.3,M,,,,*10 +{"class":"TPV","tag":"GGA","time":1158435949.000,"ept":0.005,"lat":44.436350000,"lon":-71.666085000,"alt":261.300,"speed":2.589,"mode":3} +$INZDA,194549,16,09,2006,-05,00*7E +$INMTW,17.5,C*17 +$INDPT,1.7,0.0*41 +$INRMC,194550,A,4426.1817,N,07139.9629,W,5.2,63.6,160906,15.8,W*69 +{"class":"TPV","tag":"RMC","time":1158435950.000,"ept":0.005,"lat":44.436361667,"lon":-71.666048333,"track":63.6000,"speed":2.675,"mode":2} +$INDPT,1.7,0.0*41 +$INGLL,4426.1825,N,07139.9613,W,194551,A*2E +{"class":"TPV","tag":"GLL","time":1158435951.000,"ept":0.005,"lat":44.436375000,"lon":-71.666021667,"speed":2.589,"mode":2} +$INVTG,63.3,T,79.1,M,5.2,N,9.7,K*5E +$INMTW,17.5,C*17 +$INDPT,1.6,0.0*40 +$INRMC,194552,A,4426.1829,N,07139.9597,W,5.2,62.8,160906,15.8,W*6F +{"class":"TPV","tag":"RMC","time":1158435952.000,"ept":0.005,"lat":44.436381667,"lon":-71.665995000,"track":62.8000,"speed":2.675,"mode":2} +$INDPT,1.6,0.0*40 +$INGGA,194553,4426.1837,N,07139.9575,W,2,11,0.9,261.2,M,,,,*1A +{"class":"TPV","tag":"GGA","time":1158435953.000,"ept":0.005,"lat":44.436395000,"lon":-71.665958333,"alt":261.200,"speed":3.274,"mode":3} +$INZDA,194553,16,09,2006,-05,00*75 +$INMTW,17.5,C*17 +$INDPT,1.7,0.0*41 +$INRMC,194554,A,4426.1844,N,07139.9559,W,5.2,61.3,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435954.000,"ept":0.005,"lat":44.436406667,"lon":-71.665931667,"track":61.3000,"speed":2.675,"mode":2} +$INDPT,1.8,0.0*4E +$INGLL,4426.1852,N,07139.9543,W,194555,A*2C +{"class":"TPV","tag":"GLL","time":1158435955.000,"ept":0.005,"lat":44.436420000,"lon":-71.665905000,"speed":2.589,"mode":2} +$INVTG,61.6,T,77.4,M,5.1,N,9.5,K*53 +$INMTW,17.4,C*16 +$INDPT,1.8,0.0*4E +$INRMC,194556,A,4426.1860,N,07139.9527,W,5.1,62.3,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435956.000,"ept":0.005,"lat":44.436433333,"lon":-71.665878333,"track":62.3000,"speed":2.624,"mode":2} +$INDPT,1.9,0.0*4F +$INGGA,194557,4426.1864,N,07139.9505,W,2,11,0.9,261.1,M,,,,*1C +{"class":"TPV","tag":"GGA","time":1158435957.000,"ept":0.005,"lat":44.436440000,"lon":-71.665841667,"alt":261.100,"speed":3.012,"mode":3} +$INZDA,194557,16,09,2006,-05,00*71 +$INMTW,17.5,C*17 +$INDPT,2.0,0.0*45 +$INRMC,194558,A,4426.1872,N,07139.9489,W,5.2,62.5,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435958.000,"ept":0.005,"lat":44.436453333,"lon":-71.665815000,"track":62.5000,"speed":2.675,"mode":2} +$INDPT,2.0,0.0*45 +$INGLL,4426.1879,N,07139.9473,W,194559,A*2B +{"class":"TPV","tag":"GLL","time":1158435959.000,"ept":0.005,"lat":44.436465000,"lon":-71.665788333,"speed":2.488,"mode":2} +$INVTG,61.9,T,77.7,M,5.2,N,9.7,K*5E +$INMTW,17.6,C*14 +$INDPT,1.6,0.0*40 +$INRMC,194600,A,4426.1887,N,07139.9451,W,5.2,61.4,160906,15.8,W*6B +{"class":"TPV","tag":"RMC","time":1158435960.000,"ept":0.005,"lat":44.436478333,"lon":-71.665751667,"track":61.4000,"speed":2.675,"mode":2} +$INDPT,1.6,0.0*40 +$INGGA,194601,4426.1895,N,07139.9435,W,2,11,0.9,261.1,M,,,,*10 +{"class":"TPV","tag":"GGA","time":1158435961.000,"ept":0.005,"lat":44.436491667,"lon":-71.665725000,"alt":261.100,"speed":2.589,"mode":3} +$INZDA,194601,16,09,2006,-05,00*71 +$INMTW,17.5,C*17 +$INDPT,1.7,0.0*41 +$INRMC,194602,A,4426.1899,N,07139.9419,W,5.2,62.4,160906,15.8,W*69 +{"class":"TPV","tag":"RMC","time":1158435962.000,"ept":0.005,"lat":44.436498333,"lon":-71.665698333,"track":62.4000,"speed":2.675,"mode":2} +$INDPT,1.6,0.0*40 +$INGLL,4426.1906,N,07139.9403,W,194603,A*29 +{"class":"TPV","tag":"GLL","time":1158435963.000,"ept":0.005,"lat":44.436510000,"lon":-71.665671667,"speed":2.488,"mode":2} +$INVTG,62.3,T,78.1,M,5.1,N,9.5,K*5F +$INMTW,17.5,C*17 +$INDPT,1.6,0.0*40 +$INRMC,194604,A,4426.1914,N,07139.9387,W,5.1,61.9,160906,15.8,W*66 +{"class":"TPV","tag":"RMC","time":1158435964.000,"ept":0.005,"lat":44.436523333,"lon":-71.665645000,"track":61.9000,"speed":2.624,"mode":2} +$INDPT,1.6,0.0*40 +$INGGA,194605,4426.1922,N,07139.9365,W,2,11,0.9,261.0,M,,,,*1A +{"class":"TPV","tag":"GGA","time":1158435965.000,"ept":0.005,"lat":44.436536667,"lon":-71.665608333,"alt":261.000,"speed":3.274,"mode":3} +$INZDA,194605,16,09,2006,-05,00*75 +$INMTW,17.6,C*14 +$INDPT,1.7,0.0*41 +$INRMC,194606,A,4426.1926,N,07139.9349,W,5.1,62.0,160906,15.8,W*6D +{"class":"TPV","tag":"RMC","time":1158435966.000,"ept":0.005,"lat":44.436543333,"lon":-71.665581667,"track":62.0000,"speed":2.624,"mode":2} +$INDPT,1.7,0.0*41 +$INGLL,4426.1933,N,07139.9333,W,194607,A*2F +{"class":"TPV","tag":"GLL","time":1158435967.000,"ept":0.005,"lat":44.436555000,"lon":-71.665555000,"speed":2.488,"mode":2} +$INVTG,62.6,T,78.4,M,5.1,N,9.5,K*5F +$INMTW,17.6,C*14 +$INDPT,1.7,0.0*41 +$INRMC,194608,A,4426.1941,N,07139.9311,W,5.2,62.6,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435968.000,"ept":0.005,"lat":44.436568333,"lon":-71.665518333,"track":62.6000,"speed":2.675,"mode":2} +$INDPT,1.7,0.0*41 +$INGGA,194609,4426.1949,N,07139.9295,W,2,11,0.9,260.9,M,,,,*1D +{"class":"TPV","tag":"GGA","time":1158435969.000,"ept":0.005,"lat":44.436581667,"lon":-71.665491667,"alt":260.900,"speed":2.589,"mode":3} +$INZDA,194609,16,09,2006,-05,00*79 +$INMTW,17.5,C*17 +$INDPT,1.8,0.0*4E +$INRMC,194610,A,4426.1953,N,07139.9279,W,5.1,62.0,160906,15.8,W*6A +{"class":"TPV","tag":"RMC","time":1158435970.000,"ept":0.005,"lat":44.436588333,"lon":-71.665465000,"track":62.0000,"speed":2.624,"mode":2} +$INDPT,1.8,0.0*4E +$INGLL,4426.1960,N,07139.9263,W,194611,A*2A +{"class":"TPV","tag":"GLL","time":1158435971.000,"ept":0.005,"lat":44.436600000,"lon":-71.665438333,"speed":2.488,"mode":2} +$INVTG,62.3,T,78.1,M,5.1,N,9.5,K*5F +$INMTW,17.4,C*16 +$INDPT,1.9,0.0*4F +$INRMC,194612,A,4426.1968,N,07139.9241,W,5.1,62.3,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435972.000,"ept":0.005,"lat":44.436613333,"lon":-71.665401667,"track":62.3000,"speed":2.624,"mode":2} +$INDPT,1.8,0.0*4E +$INGGA,194613,4426.1976,N,07139.9225,W,2,11,0.9,260.9,M,,,,*11 +{"class":"TPV","tag":"GGA","time":1158435973.000,"ept":0.005,"lat":44.436626667,"lon":-71.665375000,"alt":260.900,"speed":2.589,"mode":3} +$INZDA,194613,16,09,2006,-05,00*72 +$INMTW,17.4,C*16 +$INDPT,1.9,0.0*4F +$INRMC,194614,A,4426.1980,N,07139.9209,W,5.2,63.0,160906,15.8,W*65 +{"class":"TPV","tag":"RMC","time":1158435974.000,"ept":0.005,"lat":44.436633333,"lon":-71.665348333,"track":63.0000,"speed":2.675,"mode":2} +$INDPT,2.0,0.0*45 +$INGLL,4426.1987,N,07139.9187,W,194615,A*2E +{"class":"TPV","tag":"GLL","time":1158435975.000,"ept":0.005,"lat":44.436645000,"lon":-71.665311667,"speed":3.194,"mode":2} +$INVTG,63.2,T,79.0,M,5.2,N,9.6,K*5F +$INMTW,17.4,C*16 +$INDPT,1.6,0.0*40 +$INRMC,194616,A,4426.1995,N,07139.9171,W,5.1,63.3,160906,15.8,W*6F +{"class":"TPV","tag":"RMC","time":1158435976.000,"ept":0.005,"lat":44.436658333,"lon":-71.665285000,"track":63.3000,"speed":2.624,"mode":2} +$INDPT,1.7,0.0*41 +$INGGA,194617,4426.1999,N,07139.9155,W,2,11,0.9,260.8,M,,,,*11 +{"class":"TPV","tag":"GGA","time":1158435977.000,"ept":0.005,"lat":44.436665000,"lon":-71.665258333,"alt":260.800,"speed":2.249,"mode":3} +$INZDA,194617,16,09,2006,-05,00*76 +$INMTW,17.4,C*16 +$INDPT,1.8,0.0*4E +$INRMC,194618,A,4426.2007,N,07139.9139,W,5.2,62.6,160906,15.8,W*6B +{"class":"TPV","tag":"RMC","time":1158435978.000,"ept":0.005,"lat":44.436678333,"lon":-71.665231667,"track":62.6000,"speed":2.675,"mode":2} +$INDPT,1.9,0.0*4F +$INGLL,4426.2014,N,07139.9117,W,194619,A*2B +{"class":"TPV","tag":"GLL","time":1158435979.000,"ept":0.005,"lat":44.436690000,"lon":-71.665195000,"speed":3.194,"mode":2} +$INVTG,63.1,T,78.9,M,5.1,N,9.5,K*54 +$INMTW,17.2,C*10 +$INDPT,1.6,0.0*40 +$INRMC,194620,A,4426.2018,N,07139.9101,W,5.1,62.8,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435980.000,"ept":0.005,"lat":44.436696667,"lon":-71.665168333,"track":62.8000,"speed":2.624,"mode":2} +$INDPT,1.7,0.0*41 +$INGGA,194621,4426.2026,N,07139.9085,W,2,11,0.9,260.8,M,,,,*16 +{"class":"TPV","tag":"GGA","time":1158435981.000,"ept":0.005,"lat":44.436710000,"lon":-71.665141667,"alt":260.800,"speed":2.589,"mode":3} +$INZDA,194621,16,09,2006,-05,00*73 +$INMTW,17.4,C*16 +$INDPT,1.8,0.0*4E +$INRMC,194622,A,4426.2034,N,07139.9063,W,5.2,62.6,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435982.000,"ept":0.005,"lat":44.436723333,"lon":-71.665105000,"track":62.6000,"speed":2.675,"mode":2} +$INDPT,1.9,0.0*4F +$INGLL,4426.2038,N,07139.9047,W,194623,A*28 +{"class":"TPV","tag":"GLL","time":1158435983.000,"ept":0.005,"lat":44.436730000,"lon":-71.665078333,"speed":2.249,"mode":2} +$INVTG,62.5,T,78.2,M,5.2,N,9.6,K*5A +$INMTW,17.4,C*16 +$INDPT,1.7,0.0*41 +$INRMC,194624,A,4426.2045,N,07139.9031,W,5.2,62.5,160906,15.8,W*68 +{"class":"TPV","tag":"RMC","time":1158435984.000,"ept":0.005,"lat":44.436741667,"lon":-71.665051667,"track":62.5000,"speed":2.675,"mode":2} +$INDPT,1.6,0.0*40 +$INGGA,194625,4426.2053,N,07139.9009,W,2,11,0.9,260.8,M,,,,*14 +{"class":"TPV","tag":"GGA","time":1158435985.000,"ept":0.005,"lat":44.436755000,"lon":-71.665015000,"alt":260.800,"speed":3.274,"mode":3} +$INZDA,194625,16,09,2006,-05,00*77 +$INMTW,17.4,C*16 +$INDPT,1.7,0.0*41 +$INRMC,194626,A,4426.2061,N,07139.8993,W,5.1,61.5,160906,15.8,W*6C +{"class":"TPV","tag":"RMC","time":1158435986.000,"ept":0.005,"lat":44.436768333,"lon":-71.664988333,"track":61.5000,"speed":2.624,"mode":2} +$INDPT,1.7,0.0*41 +$INGLL,4426.2068,N,07139.8977,W,194627,A*22 +{"class":"TPV","tag":"GLL","time":1158435987.000,"ept":0.005,"lat":44.436780000,"lon":-71.664961667,"speed":2.488,"mode":2} +$INVTG,61.6,T,77.4,M,5.2,N,9.6,K*53 +$INMTW,17.4,C*16 +$INDPT,1.7,0.0*41 +$INRMC,194628,A,4426.2072,N,07139.8961,W,5.1,62.2,160906,15.8,W*69 +{"class":"TPV","tag":"RMC","time":1158435988.000,"ept":0.005,"lat":44.436786667,"lon":-71.664935000,"track":62.2000,"speed":2.624,"mode":2} +$INDPT,1.7,0.0*41 +$INGGA,194629,4426.2080,N,07139.8945,W,2,11,0.9,260.5,M,,,,*1B +{"class":"TPV","tag":"GGA","time":1158435989.000,"ept":0.005,"lat":44.436800000,"lon":-71.664908333,"alt":260.500,"speed":2.589,"mode":3} +$INZDA,194629,16,09,2006,-05,00*7B +$INMTW,17.3,C*11 +$INDPT,1.9,0.0*4F +$INRMC,194630,A,4426.2088,N,07139.8923,W,5.2,62.2,160906,15.8,W*60 +{"class":"TPV","tag":"RMC","time":1158435990.000,"ept":0.005,"lat":44.436813333,"lon":-71.664871667,"track":62.2000,"speed":2.675,"mode":2} +$INDPT,1.9,0.0*4F diff --git a/test/daemon/iTrek.log b/test/daemon/iTrek.log new file mode 100644 index 0000000..0a41fc6 --- /dev/null +++ b/test/daemon/iTrek.log @@ -0,0 +1,117 @@ +# Name: i.Trek M3 +# Submitted-by: "Lance Fetters" +# Date: 27 Jul 2005 +# Location: Anpachi, Gifu, JP, 35N136E +# Note that this log file is a combination of two separate logs, +# one captured without a fix (first three lines) and one with. +# This GPS emuits a badly malformed GSA when it has no fix, as +# you can see on the first two lines. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPRMC,151605.053,V,,,,,,,260705,,*29 +$GPRMC,151606.055,V,,,,,,,260705,,*2C +$GPGSA,A,1,,,,*32 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045849.000,A,3519.9048,N,13640.2631,E,0.10,92.17,270705,,*31 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045850.000,A,3519.9047,N,13640.2631,E,0.11,99.12,270705,,*39 +$GPGGA,045851.000,3519.9046,N,13640.2631,E,1,04,2.2,80.4,M,,,,0000*39 +$GPRMC,045851.000,A,3519.9046,N,13640.2631,E,0.12,114.35,270705,,*0B +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSV,2,2,08,22,62,272,24,18,55,192,16,30,50,179,18,15,09,229,*74 +$GPRMC,045852.000,A,3519.9046,N,13640.2632,E,0.10,104.21,270705,,*0D +$GPGGA,045853.000,3519.9045,N,13640.2632,E,1,04,2.2,80.4,M,,,,0000*3B +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045853.000,A,3519.9045,N,13640.2632,E,0.11,97.51,270705,,*32 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045854.000,A,3519.9044,N,13640.2632,E,0.12,108.39,270705,,*0E +$GPGGA,045855.000,3519.9043,N,13640.2632,E,1,04,2.2,80.4,M,,,,0000*3B +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045855.000,A,3519.9043,N,13640.2632,E,0.11,99.16,270705,,*3F +$GPGGA,045856.000,3519.9042,N,13640.2632,E,1,04,2.2,80.4,M,,,,0000*39 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045856.000,A,3519.9042,N,13640.2632,E,0.11,115.12,270705,,*0C +$GPGGA,045857.000,3519.9040,N,13640.2632,E,1,04,2.2,80.5,M,,,,0000*3B +$GPGSV,2,1,08,05,67,099,26,09,41,047,46,14,32,311,43,26,08,109,30*78 +$GPGSV,2,2,08,22,62,272,25,18,55,192,24,30,50,179,19,15,09,229,*75 +$GPRMC,045857.000,A,3519.9040,N,13640.2632,E,0.11,116.49,270705,,*02 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045858.000,A,3519.9039,N,13640.2632,E,0.11,115.53,270705,,*0B +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045859.000,A,3519.9038,N,13640.2632,E,0.10,107.70,270705,,*08 +$GPGGA,045900.000,3519.9036,N,13640.2632,E,1,04,2.2,80.8,M,,,,0000*34 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045900.000,A,3519.9036,N,13640.2632,E,0.12,130.75,270705,,*08 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045901.000,A,3519.9035,N,13640.2632,E,0.11,121.44,270705,,*0B +$GPGGA,045902.000,3519.9034,N,13640.2633,E,1,04,2.2,81.0,M,,,,0000*3C +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSV,2,1,08,05,67,099,26,09,41,047,46,14,32,311,42,26,08,109,29*71 +$GPGSV,2,2,08,22,62,272,24,18,55,192,24,30,50,179,25,15,09,229,23*7A +$GPRMC,045902.000,A,3519.9034,N,13640.2633,E,0.13,137.85,270705,,*00 +$GPGGA,045903.000,3519.9032,N,13640.2633,E,1,04,2.2,81.1,M,,,,0000*3A +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045903.000,A,3519.9032,N,13640.2633,E,0.15,142.32,270705,,*0F +$GPGGA,045904.000,3519.9030,N,13640.2633,E,1,04,2.2,80.8,M,,,,0000*37 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045904.000,A,3519.9030,N,13640.2633,E,0.55,168.73,270705,,*03 +$GPGGA,045905.000,3519.9028,N,13640.2633,E,1,04,2.2,80.7,M,,,,0000*30 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045905.000,A,3519.9028,N,13640.2633,E,0.11,51.58,270705,,*39 +$GPGGA,045906.000,3519.9027,N,13640.2633,E,1,04,2.2,80.6,M,,,,0000*3D +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045906.000,A,3519.9027,N,13640.2633,E,0.17,42.56,270705,,*3F +$GPGGA,045907.000,3519.9026,N,13640.2633,E,1,04,2.2,80.6,M,,,,0000*3D +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSV,2,1,08,05,67,099,32,09,41,047,46,14,32,311,42,26,08,109,24*79 +$GPGSV,2,2,08,22,62,272,25,18,55,192,25,30,50,179,26,15,09,229,*78 +$GPRMC,045907.000,A,3519.9026,N,13640.2633,E,0.12,56.07,270705,,*3B +$GPGGA,045908.000,3519.9026,N,13640.2633,E,1,04,2.2,80.8,M,,,,0000*3C +$GPRMC,045908.000,A,3519.9026,N,13640.2633,E,0.38,14.44,270705,,*3D +$GPGGA,045909.000,3519.9026,N,13640.2634,E,1,04,2.2,81.0,M,,,,0000*33 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045909.000,A,3519.9026,N,13640.2634,E,0.35,16.55,270705,,*34 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045910.000,A,3519.9026,N,13640.2634,E,0.18,28.96,270705,,*31 +$GPGGA,045911.000,3519.9026,N,13640.2634,E,1,04,2.2,81.3,M,,,,0000*39 +$GPRMC,045911.000,A,3519.9026,N,13640.2634,E,0.42,13.19,270705,,*30 +$GPGGA,045912.000,3519.9026,N,13640.2634,E,1,04,2.2,81.3,M,,,,0000*3A +$GPGSV,2,1,08,05,67,099,33,09,41,047,46,14,32,311,42,26,08,109,23*7F +$GPGSV,2,2,08,22,62,272,25,18,55,192,18,30,50,179,21,15,09,229,*71 +$GPRMC,045912.000,A,3519.9026,N,13640.2634,E,0.36,13.64,270705,,*3A +$GPGGA,045913.000,3519.9025,N,13640.2634,E,1,04,2.2,81.2,M,,,,0000*39 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045913.000,A,3519.9025,N,13640.2634,E,0.30,15.65,270705,,*39 +$GPGGA,045914.000,3519.9024,N,13640.2635,E,1,04,2.2,80.8,M,,,,0000*35 +$GPRMC,045914.000,A,3519.9024,N,13640.2635,E,0.30,160.36,270705,,*0B +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045915.000,A,3519.9021,N,13640.2635,E,0.34,165.82,270705,,*01 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045916.000,A,3519.9019,N,13640.2636,E,0.31,160.03,270705,,*03 +$GPGGA,045917.000,3519.9017,N,13640.2636,E,1,04,2.2,79.0,M,,,,0000*3B +$GPGSV,2,1,08,05,67,099,34,09,41,047,46,14,32,311,42,26,08,109,19*71 +$GPGSV,2,2,08,22,62,272,20,18,55,192,19,30,50,179,13,15,09,229,24*72 +$GPRMC,045917.000,A,3519.9017,N,13640.2636,E,0.32,160.37,270705,,*08 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045918.000,A,3519.9017,N,13640.2636,E,0.21,29.38,270705,,*36 +$GPGGA,045919.000,3519.9017,N,13640.2637,E,1,04,2.2,78.9,M,,,,0000*3C +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045919.000,A,3519.9017,N,13640.2637,E,0.37,18.86,270705,,*36 +$GPGGA,045920.000,3519.9017,N,13640.2637,E,1,04,2.2,78.8,M,,,,0000*37 +$GPRMC,045920.000,A,3519.9017,N,13640.2637,E,0.29,165.15,270705,,*02 +$GPGGA,045921.000,3519.9015,N,13640.2637,E,1,04,2.2,78.5,M,,,,0000*39 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045921.000,A,3519.9015,N,13640.2637,E,1.17,164.92,270705,,*03 +$GPGGA,045922.000,3519.9007,N,13640.2636,E,1,04,2.2,78.6,M,,,,0000*3B +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSV,2,1,08,05,67,099,21,09,41,047,36,14,32,311,26,26,08,109,21*7B +$GPGSV,2,2,08,22,62,272,20,18,55,192,18,30,50,179,,15,09,229,*77 +$GPRMC,045922.000,A,3519.9007,N,13640.2636,E,3.35,194.25,270705,,*03 +$GPGSA,A,2,,,,,,,,,,,,,50.0,50.0,50.0*06 +$GPRMC,045923.000,A,3519.8998,N,13640.2633,E,3.35,194.25,270705,,*09 diff --git a/test/daemon/iTrek.log.chk b/test/daemon/iTrek.log.chk new file mode 100644 index 0000000..bdd5f41 --- /dev/null +++ b/test/daemon/iTrek.log.chk @@ -0,0 +1,153 @@ +$GPRMC,151605.053,V,,,,,,,260705,,*29 +$GPRMC,151606.055,V,,,,,,,260705,,*2C +$GPGSA,A,1,,,,*32 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +{"class":"TPV","tag":"GSA","epv":43.700,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +{"class":"TPV","tag":"GSA","epv":43.700,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +{"class":"TPV","tag":"GSA","epv":43.700,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +{"class":"TPV","tag":"GSA","epv":43.700,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +{"class":"TPV","tag":"GSA","epv":43.700,"mode":3} +$GPRMC,045849.000,A,3519.9048,N,13640.2631,E,0.10,92.17,270705,,*31 +{"class":"TPV","tag":"RMC","time":1122440329.000,"ept":0.005,"lat":35.331746667,"lon":136.671051667,"track":92.1700,"speed":0.051,"mode":2} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +{"class":"TPV","tag":"GSA","time":1122440329.000,"ept":0.005,"lat":35.331746667,"lon":136.671051667,"epv":43.700,"track":92.1700,"speed":0.051,"mode":3} +$GPRMC,045850.000,A,3519.9047,N,13640.2631,E,0.11,99.12,270705,,*39 +{"class":"TPV","tag":"RMC","time":1122440330.000,"ept":0.005,"lat":35.331745000,"lon":136.671051667,"track":99.1200,"speed":0.057,"mode":2} +$GPGGA,045851.000,3519.9046,N,13640.2631,E,1,04,2.2,80.4,M,,,,0000*39 +$GPRMC,045851.000,A,3519.9046,N,13640.2631,E,0.12,114.35,270705,,*0B +{"class":"TPV","tag":"RMC","time":1122440331.000,"ept":0.005,"lat":35.331743333,"lon":136.671051667,"alt":80.400,"epv":43.700,"track":114.3500,"speed":0.062,"climb":0.000,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSV,2,2,08,22,62,272,24,18,55,192,16,30,50,179,18,15,09,229,*74 +{"class":"SKY","tag":"GSV","xdop":11.57,"ydop":10.11,"vdop":1.90,"tdop":17.18,"hdop":2.20,"gdop":26.66,"pdop":2.90,"satellites":[{"PRN":22,"el":62,"az":272,"ss":24,"used":false},{"PRN":18,"el":55,"az":192,"ss":16,"used":false},{"PRN":30,"el":50,"az":179,"ss":18,"used":false},{"PRN":15,"el":9,"az":229,"ss":0,"used":false}]} +$GPRMC,045852.000,A,3519.9046,N,13640.2632,E,0.10,104.21,270705,,*0D +{"class":"TPV","tag":"RMC","time":1122440332.000,"ept":0.005,"lat":35.331743333,"lon":136.671053333,"epx":173.568,"epy":151.635,"track":104.2100,"speed":0.051,"eps":347.14,"mode":2} +$GPGGA,045853.000,3519.9045,N,13640.2632,E,1,04,2.2,80.4,M,,,,0000*3B +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045853.000,A,3519.9045,N,13640.2632,E,0.11,97.51,270705,,*32 +{"class":"TPV","tag":"RMC","time":1122440333.000,"ept":0.005,"lat":35.331741667,"lon":136.671053333,"alt":80.400,"epx":173.568,"epy":151.635,"epv":43.700,"track":97.5100,"speed":0.057,"climb":0.000,"eps":347.14,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045854.000,A,3519.9044,N,13640.2632,E,0.12,108.39,270705,,*0E +{"class":"TPV","tag":"RMC","time":1122440334.000,"ept":0.005,"lat":35.331740000,"lon":136.671053333,"epx":173.568,"epy":151.635,"track":108.3900,"speed":0.062,"eps":347.14,"mode":2} +$GPGGA,045855.000,3519.9043,N,13640.2632,E,1,04,2.2,80.4,M,,,,0000*3B +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045855.000,A,3519.9043,N,13640.2632,E,0.11,99.16,270705,,*3F +{"class":"TPV","tag":"RMC","time":1122440335.000,"ept":0.005,"lat":35.331738333,"lon":136.671053333,"alt":80.400,"epx":173.568,"epy":151.635,"epv":43.700,"track":99.1600,"speed":0.057,"climb":0.000,"eps":347.14,"mode":3} +$GPGGA,045856.000,3519.9042,N,13640.2632,E,1,04,2.2,80.4,M,,,,0000*39 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045856.000,A,3519.9042,N,13640.2632,E,0.11,115.12,270705,,*0C +{"class":"TPV","tag":"RMC","time":1122440336.000,"ept":0.005,"lat":35.331736667,"lon":136.671053333,"alt":80.400,"epx":173.568,"epy":151.635,"epv":43.700,"track":115.1200,"speed":0.057,"climb":0.000,"eps":347.14,"mode":3} +$GPGGA,045857.000,3519.9040,N,13640.2632,E,1,04,2.2,80.5,M,,,,0000*3B +$GPGSV,2,1,08,05,67,099,26,09,41,047,46,14,32,311,43,26,08,109,30*78 +$GPGSV,2,2,08,22,62,272,25,18,55,192,24,30,50,179,19,15,09,229,*75 +{"class":"SKY","tag":"GSV","xdop":1.20,"ydop":1.90,"vdop":1.89,"tdop":1.30,"hdop":2.25,"gdop":3.21,"pdop":2.94,"satellites":[{"PRN":5,"el":67,"az":99,"ss":26,"used":true},{"PRN":9,"el":41,"az":47,"ss":46,"used":true},{"PRN":14,"el":32,"az":311,"ss":43,"used":true},{"PRN":26,"el":8,"az":109,"ss":30,"used":true},{"PRN":22,"el":62,"az":272,"ss":25,"used":false},{"PRN":18,"el":55,"az":192,"ss":24,"used":false},{"PRN":30,"el":50,"az":179,"ss":19,"used":false},{"PRN":15,"el":9,"az":229,"ss":0,"used":false}]} +$GPRMC,045857.000,A,3519.9040,N,13640.2632,E,0.11,116.49,270705,,*02 +{"class":"TPV","tag":"RMC","time":1122440337.000,"ept":0.005,"lat":35.331733333,"lon":136.671053333,"alt":80.500,"epx":173.568,"epy":151.635,"epv":43.700,"track":116.4900,"speed":0.057,"climb":0.100,"eps":347.14,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045858.000,A,3519.9039,N,13640.2632,E,0.11,115.53,270705,,*0B +{"class":"TPV","tag":"RMC","time":1122440338.000,"ept":0.005,"lat":35.331731667,"lon":136.671053333,"epx":17.960,"epy":28.495,"track":115.5300,"speed":0.057,"eps":202.06,"mode":2} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045859.000,A,3519.9038,N,13640.2632,E,0.10,107.70,270705,,*08 +{"class":"TPV","tag":"RMC","time":1122440339.000,"ept":0.005,"lat":35.331730000,"lon":136.671053333,"epx":17.960,"epy":28.495,"track":107.7000,"speed":0.051,"eps":56.99,"mode":2} +$GPGGA,045900.000,3519.9036,N,13640.2632,E,1,04,2.2,80.8,M,,,,0000*34 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045900.000,A,3519.9036,N,13640.2632,E,0.12,130.75,270705,,*08 +{"class":"TPV","tag":"RMC","time":1122440340.000,"ept":0.005,"lat":35.331726667,"lon":136.671053333,"alt":80.800,"epx":17.960,"epy":28.495,"epv":43.700,"track":130.7500,"speed":0.062,"climb":0.000,"eps":56.99,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045901.000,A,3519.9035,N,13640.2632,E,0.11,121.44,270705,,*0B +{"class":"TPV","tag":"RMC","time":1122440341.000,"ept":0.005,"lat":35.331725000,"lon":136.671053333,"epx":17.960,"epy":28.495,"track":121.4400,"speed":0.057,"eps":56.99,"mode":2} +$GPGGA,045902.000,3519.9034,N,13640.2633,E,1,04,2.2,81.0,M,,,,0000*3C +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSV,2,1,08,05,67,099,26,09,41,047,46,14,32,311,42,26,08,109,29*71 +$GPGSV,2,2,08,22,62,272,24,18,55,192,24,30,50,179,25,15,09,229,23*7A +{"class":"SKY","tag":"GSV","xdop":1.20,"ydop":1.90,"vdop":1.89,"tdop":1.30,"hdop":2.25,"gdop":3.21,"pdop":2.94,"satellites":[{"PRN":5,"el":67,"az":99,"ss":26,"used":true},{"PRN":9,"el":41,"az":47,"ss":46,"used":true},{"PRN":14,"el":32,"az":311,"ss":42,"used":true},{"PRN":26,"el":8,"az":109,"ss":29,"used":true},{"PRN":22,"el":62,"az":272,"ss":24,"used":false},{"PRN":18,"el":55,"az":192,"ss":24,"used":false},{"PRN":30,"el":50,"az":179,"ss":25,"used":false},{"PRN":15,"el":9,"az":229,"ss":23,"used":false}]} +$GPRMC,045902.000,A,3519.9034,N,13640.2633,E,0.13,137.85,270705,,*00 +{"class":"TPV","tag":"RMC","time":1122440342.000,"ept":0.005,"lat":35.331723333,"lon":136.671055000,"alt":81.000,"epx":17.960,"epy":28.495,"epv":43.700,"track":137.8500,"speed":0.067,"climb":0.000,"eps":56.99,"mode":3} +$GPGGA,045903.000,3519.9032,N,13640.2633,E,1,04,2.2,81.1,M,,,,0000*3A +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045903.000,A,3519.9032,N,13640.2633,E,0.15,142.32,270705,,*0F +{"class":"TPV","tag":"RMC","time":1122440343.000,"ept":0.005,"lat":35.331720000,"lon":136.671055000,"alt":81.100,"epx":17.960,"epy":28.495,"epv":43.571,"track":142.3200,"speed":0.077,"climb":0.100,"eps":56.99,"mode":3} +$GPGGA,045904.000,3519.9030,N,13640.2633,E,1,04,2.2,80.8,M,,,,0000*37 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045904.000,A,3519.9030,N,13640.2633,E,0.55,168.73,270705,,*03 +{"class":"TPV","tag":"RMC","time":1122440344.000,"ept":0.005,"lat":35.331716667,"lon":136.671055000,"alt":80.800,"epx":17.960,"epy":28.495,"epv":43.700,"track":168.7300,"speed":0.283,"climb":-0.300,"eps":56.99,"mode":3} +$GPGGA,045905.000,3519.9028,N,13640.2633,E,1,04,2.2,80.7,M,,,,0000*30 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045905.000,A,3519.9028,N,13640.2633,E,0.11,51.58,270705,,*39 +{"class":"TPV","tag":"RMC","time":1122440345.000,"ept":0.005,"lat":35.331713333,"lon":136.671055000,"alt":80.700,"epx":17.960,"epy":28.495,"epv":43.700,"track":51.5800,"speed":0.057,"climb":-0.100,"eps":56.99,"mode":3} +$GPGGA,045906.000,3519.9027,N,13640.2633,E,1,04,2.2,80.6,M,,,,0000*3D +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045906.000,A,3519.9027,N,13640.2633,E,0.17,42.56,270705,,*3F +{"class":"TPV","tag":"RMC","time":1122440346.000,"ept":0.005,"lat":35.331711667,"lon":136.671055000,"alt":80.600,"epx":17.960,"epy":28.495,"epv":43.700,"track":42.5600,"speed":0.087,"climb":-0.100,"eps":56.99,"mode":3} +$GPGGA,045907.000,3519.9026,N,13640.2633,E,1,04,2.2,80.6,M,,,,0000*3D +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSV,2,1,08,05,67,099,32,09,41,047,46,14,32,311,42,26,08,109,24*79 +$GPGSV,2,2,08,22,62,272,25,18,55,192,25,30,50,179,26,15,09,229,*78 +{"class":"SKY","tag":"GSV","xdop":1.20,"ydop":1.90,"vdop":1.89,"tdop":1.30,"hdop":2.25,"gdop":3.21,"pdop":2.94,"satellites":[{"PRN":5,"el":67,"az":99,"ss":32,"used":true},{"PRN":9,"el":41,"az":47,"ss":46,"used":true},{"PRN":14,"el":32,"az":311,"ss":42,"used":true},{"PRN":26,"el":8,"az":109,"ss":24,"used":true},{"PRN":22,"el":62,"az":272,"ss":25,"used":false},{"PRN":18,"el":55,"az":192,"ss":25,"used":false},{"PRN":30,"el":50,"az":179,"ss":26,"used":false},{"PRN":15,"el":9,"az":229,"ss":0,"used":false}]} +$GPRMC,045907.000,A,3519.9026,N,13640.2633,E,0.12,56.07,270705,,*3B +{"class":"TPV","tag":"RMC","time":1122440347.000,"ept":0.005,"lat":35.331710000,"lon":136.671055000,"alt":80.600,"epx":17.960,"epy":28.495,"epv":43.700,"track":56.0700,"speed":0.062,"climb":0.000,"eps":56.99,"mode":3} +$GPGGA,045908.000,3519.9026,N,13640.2633,E,1,04,2.2,80.8,M,,,,0000*3C +$GPRMC,045908.000,A,3519.9026,N,13640.2633,E,0.38,14.44,270705,,*3D +{"class":"TPV","tag":"RMC","time":1122440348.000,"ept":0.005,"lat":35.331710000,"lon":136.671055000,"alt":80.800,"epx":17.960,"epy":28.495,"epv":43.571,"track":14.4400,"speed":0.195,"climb":0.200,"eps":56.99,"mode":3} +$GPGGA,045909.000,3519.9026,N,13640.2634,E,1,04,2.2,81.0,M,,,,0000*33 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045909.000,A,3519.9026,N,13640.2634,E,0.35,16.55,270705,,*34 +{"class":"TPV","tag":"RMC","time":1122440349.000,"ept":0.005,"lat":35.331710000,"lon":136.671056667,"alt":81.000,"epx":17.960,"epy":28.495,"epv":43.571,"track":16.5500,"speed":0.180,"climb":0.200,"eps":56.99,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045910.000,A,3519.9026,N,13640.2634,E,0.18,28.96,270705,,*31 +{"class":"TPV","tag":"RMC","time":1122440350.000,"ept":0.005,"lat":35.331710000,"lon":136.671056667,"epx":17.960,"epy":28.495,"track":28.9600,"speed":0.093,"eps":56.99,"mode":2} +$GPGGA,045911.000,3519.9026,N,13640.2634,E,1,04,2.2,81.3,M,,,,0000*39 +$GPRMC,045911.000,A,3519.9026,N,13640.2634,E,0.42,13.19,270705,,*30 +{"class":"TPV","tag":"RMC","time":1122440351.000,"ept":0.005,"lat":35.331710000,"lon":136.671056667,"alt":81.300,"epx":17.960,"epy":28.495,"epv":43.700,"track":13.1900,"speed":0.216,"climb":0.000,"eps":56.99,"mode":3} +$GPGGA,045912.000,3519.9026,N,13640.2634,E,1,04,2.2,81.3,M,,,,0000*3A +$GPGSV,2,1,08,05,67,099,33,09,41,047,46,14,32,311,42,26,08,109,23*7F +$GPGSV,2,2,08,22,62,272,25,18,55,192,18,30,50,179,21,15,09,229,*71 +{"class":"SKY","tag":"GSV","xdop":1.20,"ydop":1.90,"vdop":1.89,"tdop":1.30,"hdop":2.25,"gdop":3.21,"pdop":2.94,"satellites":[{"PRN":5,"el":67,"az":99,"ss":33,"used":true},{"PRN":9,"el":41,"az":47,"ss":46,"used":true},{"PRN":14,"el":32,"az":311,"ss":42,"used":true},{"PRN":26,"el":8,"az":109,"ss":23,"used":true},{"PRN":22,"el":62,"az":272,"ss":25,"used":false},{"PRN":18,"el":55,"az":192,"ss":18,"used":false},{"PRN":30,"el":50,"az":179,"ss":21,"used":false},{"PRN":15,"el":9,"az":229,"ss":0,"used":false}]} +$GPRMC,045912.000,A,3519.9026,N,13640.2634,E,0.36,13.64,270705,,*3A +{"class":"TPV","tag":"RMC","time":1122440352.000,"ept":0.005,"lat":35.331710000,"lon":136.671056667,"alt":81.300,"epx":17.960,"epy":28.495,"epv":43.700,"track":13.6400,"speed":0.185,"climb":0.000,"eps":56.99,"mode":3} +$GPGGA,045913.000,3519.9025,N,13640.2634,E,1,04,2.2,81.2,M,,,,0000*39 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045913.000,A,3519.9025,N,13640.2634,E,0.30,15.65,270705,,*39 +{"class":"TPV","tag":"RMC","time":1122440353.000,"ept":0.005,"lat":35.331708333,"lon":136.671056667,"alt":81.200,"epx":17.960,"epy":28.495,"epv":43.571,"track":15.6500,"speed":0.154,"climb":-0.100,"eps":56.99,"mode":3} +$GPGGA,045914.000,3519.9024,N,13640.2635,E,1,04,2.2,80.8,M,,,,0000*35 +$GPRMC,045914.000,A,3519.9024,N,13640.2635,E,0.30,160.36,270705,,*0B +{"class":"TPV","tag":"RMC","time":1122440354.000,"ept":0.005,"lat":35.331706667,"lon":136.671058333,"alt":80.800,"epx":17.960,"epy":28.495,"epv":43.700,"track":160.3600,"speed":0.154,"climb":-0.400,"eps":56.99,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045915.000,A,3519.9021,N,13640.2635,E,0.34,165.82,270705,,*01 +{"class":"TPV","tag":"RMC","time":1122440355.000,"ept":0.005,"lat":35.331701667,"lon":136.671058333,"epx":17.960,"epy":28.495,"track":165.8200,"speed":0.175,"eps":56.99,"mode":2} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045916.000,A,3519.9019,N,13640.2636,E,0.31,160.03,270705,,*03 +{"class":"TPV","tag":"RMC","time":1122440356.000,"ept":0.005,"lat":35.331698333,"lon":136.671060000,"epx":17.960,"epy":28.495,"track":160.0300,"speed":0.159,"eps":56.99,"mode":2} +$GPGGA,045917.000,3519.9017,N,13640.2636,E,1,04,2.2,79.0,M,,,,0000*3B +$GPGSV,2,1,08,05,67,099,34,09,41,047,46,14,32,311,42,26,08,109,19*71 +$GPGSV,2,2,08,22,62,272,20,18,55,192,19,30,50,179,13,15,09,229,24*72 +{"class":"SKY","tag":"GSV","xdop":1.20,"ydop":1.90,"vdop":1.89,"tdop":1.30,"hdop":2.25,"gdop":3.21,"pdop":2.94,"satellites":[{"PRN":5,"el":67,"az":99,"ss":34,"used":true},{"PRN":9,"el":41,"az":47,"ss":46,"used":true},{"PRN":14,"el":32,"az":311,"ss":42,"used":true},{"PRN":26,"el":8,"az":109,"ss":19,"used":true},{"PRN":22,"el":62,"az":272,"ss":20,"used":false},{"PRN":18,"el":55,"az":192,"ss":19,"used":false},{"PRN":30,"el":50,"az":179,"ss":13,"used":false},{"PRN":15,"el":9,"az":229,"ss":24,"used":false}]} +$GPRMC,045917.000,A,3519.9017,N,13640.2636,E,0.32,160.37,270705,,*08 +{"class":"TPV","tag":"RMC","time":1122440357.000,"ept":0.005,"lat":35.331695000,"lon":136.671060000,"alt":79.000,"epx":17.960,"epy":28.495,"epv":43.700,"track":160.3700,"speed":0.165,"climb":0.000,"eps":56.99,"mode":3} +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045918.000,A,3519.9017,N,13640.2636,E,0.21,29.38,270705,,*36 +{"class":"TPV","tag":"RMC","time":1122440358.000,"ept":0.005,"lat":35.331695000,"lon":136.671060000,"epx":17.960,"epy":28.495,"track":29.3800,"speed":0.108,"eps":56.99,"mode":2} +$GPGGA,045919.000,3519.9017,N,13640.2637,E,1,04,2.2,78.9,M,,,,0000*3C +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045919.000,A,3519.9017,N,13640.2637,E,0.37,18.86,270705,,*36 +{"class":"TPV","tag":"RMC","time":1122440359.000,"ept":0.005,"lat":35.331695000,"lon":136.671061667,"alt":78.900,"epx":17.960,"epy":28.495,"epv":43.700,"track":18.8600,"speed":0.190,"climb":0.000,"eps":56.99,"mode":3} +$GPGGA,045920.000,3519.9017,N,13640.2637,E,1,04,2.2,78.8,M,,,,0000*37 +$GPRMC,045920.000,A,3519.9017,N,13640.2637,E,0.29,165.15,270705,,*02 +{"class":"TPV","tag":"RMC","time":1122440360.000,"ept":0.005,"lat":35.331695000,"lon":136.671061667,"alt":78.800,"epx":17.960,"epy":28.495,"epv":43.700,"track":165.1500,"speed":0.149,"climb":-0.100,"eps":56.99,"mode":3} +$GPGGA,045921.000,3519.9015,N,13640.2637,E,1,04,2.2,78.5,M,,,,0000*39 +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPRMC,045921.000,A,3519.9015,N,13640.2637,E,1.17,164.92,270705,,*03 +{"class":"TPV","tag":"RMC","time":1122440361.000,"ept":0.005,"lat":35.331691667,"lon":136.671061667,"alt":78.500,"epx":17.960,"epy":28.495,"epv":43.700,"track":164.9200,"speed":0.602,"climb":-0.300,"eps":56.99,"mode":3} +$GPGGA,045922.000,3519.9007,N,13640.2636,E,1,04,2.2,78.6,M,,,,0000*3B +$GPGSA,A,3,09,05,14,26,,,,,,,,,2.9,2.2,1.9*3C +$GPGSV,2,1,08,05,67,099,21,09,41,047,36,14,32,311,26,26,08,109,21*7B +$GPGSV,2,2,08,22,62,272,20,18,55,192,18,30,50,179,,15,09,229,*77 +{"class":"SKY","tag":"GSV","xdop":1.20,"ydop":1.90,"vdop":1.89,"tdop":1.30,"hdop":2.25,"gdop":3.21,"pdop":2.94,"satellites":[{"PRN":5,"el":67,"az":99,"ss":21,"used":true},{"PRN":9,"el":41,"az":47,"ss":36,"used":true},{"PRN":14,"el":32,"az":311,"ss":26,"used":true},{"PRN":26,"el":8,"az":109,"ss":21,"used":true},{"PRN":22,"el":62,"az":272,"ss":20,"used":false},{"PRN":18,"el":55,"az":192,"ss":18,"used":false},{"PRN":30,"el":50,"az":179,"ss":0,"used":false},{"PRN":15,"el":9,"az":229,"ss":0,"used":false}]} +$GPRMC,045922.000,A,3519.9007,N,13640.2636,E,3.35,194.25,270705,,*03 +{"class":"TPV","tag":"RMC","time":1122440362.000,"ept":0.005,"lat":35.331678333,"lon":136.671060000,"alt":78.600,"epx":17.960,"epy":28.495,"epv":43.700,"track":194.2500,"speed":1.723,"climb":0.100,"eps":56.99,"mode":3} +$GPGSA,A,2,,,,,,,,,,,,,50.0,50.0,50.0*06 +$GPRMC,045923.000,A,3519.8998,N,13640.2633,E,3.35,194.25,270705,,*09 +{"class":"TPV","tag":"RMC","time":1122440363.000,"ept":0.005,"lat":35.331663333,"lon":136.671055000,"epx":17.960,"epy":28.495,"track":194.2500,"speed":1.723,"eps":56.99,"mode":2} diff --git a/test/daemon/italk-binary.log b/test/daemon/italk-binary.log new file mode 100644 index 0000000000000000000000000000000000000000..4813b1a88c6da6f4db73ecf31583f736425a4b28 GIT binary patch literal 31844 zcmchg2UrwI^YCkCV3#E>ARvee63v*w04QcLAZ9%Sh>D`1Vh&(9BW4tH78OA;XE9+u z&x|>rr=lk!226Za-8&mN_0Ic0?>9b=yIb9ps;7QkUDZ9fxwPofKcc2f!ybcU2lW{4 z64|ClR6m#SK9MnlBVt{=V+KXXMu$g7m2(*yF=%jP^Z=JCrClNixP(Ox=rL%7OaJJe z5vFb~LA-iR?S2FBm@YjA^mOr#?Bx;@J$P_rSX4x5mtK*B`VZ?dD8gk>#L!4~w5W)o z5m6QB5F^5)B3xo4=~^lcMnUM1u>O&;u@ODXhmEL-XBZSY*ri#-h}b?6F15q^4T-=n zf&F_#MpX!l7!(y5J-9;82!GtIeveo@LS-Kxzw$o5<$e566dWDiBNi{crpu54{RTu2 z8(`{&(l&kYfW0E|r1%*W9W!E3WbZzB$Kj=M?@B%{VIy4VT#Z_V)^|ZI^o3~93mY7PSB>@9k%C&b>e!@3BT^8_dPbs7Bg2N!$z29TN5{JKiXPC`xI0?qvyekh%0I(G^9Jai5vYOMh3Um;v?w;#)IOn-)OYk6AI1|j3 zKoUnO!y$FgLq%4Ht8iUPU2Wn)b?QC6DXNwWScfDgMi~yhM&=3Y%l8LWzWdp1Z>kgj zM?IMbv+cy42RW24nqScBN+CnNNSclovWzI3)ba)G6Nuqg$clg ziV_@NB7is44C{;g0$f?^DXlSEgLOz^ch|qRt7n`5X7%5c2RksOD!6%o5wx8PaP}pZ zd&il8DQQapNn!HkxoWz2ysTJ%zFGSSEcJ>rg6UkB5|*1{`RYH*y3$deO41}-s0an` zo#Kc8S*oog{Ced21{0`-ZI0(*cI#omH)Hp|K6r+2qlc+E?C4zjRC& z_%zHhen*!g?Hpm`p+)snP*ko0;S1@j0!p!StqscQ#II@Eg9;cA)<$mBDw~hi?VAf42{F@eaSg4L2>K z&@a6#^c36SGo(hL60(H3QZeYR@`dvF+X#w)KYr@&s449lC_>w|re{!3rQ<|sbOQAx zDfZzr@z};lMHQT0etJir^6$qs^_jc?H{N9P5yTc=Dv?PNDs8{h>8{ZSaEeWI&VKLg?*m ze3nT>H<<6X$17ejCV;Wx?7aO_v!%tn01k}{V5}%r^e~vF7{POYtA^JZE1I7^ zAkN5pgvTKXu_CyF03|&|I0aV2CNWkF8FoNOuu7mhC^_qc+F-1J_xh|z5%Qo7vSLFU zx!i=6JCkZ~dnsLqu4@2BG{SPm64EBIj6O)PnX<++tB znbT2-C8lUO9q@_V9yP9+8cKVm_QuQBZdno?Pv(vD0pd-=H^CcC-~zTi=S}=vVu{Qf zzmLQll}!-x<|x)dy(3FnZ+GnyzN0?MgT=otKuKB?(h)KoHr{wtQH~{T(ngJNr*S) zdY@1{8F38;etq*B=gn@kja%z3+X9e;`7hqqqDB7!aP0Mc^OuY_=4nHq_WdhZha`+Q zp6wy3u>+ihs>yXc0`Vztu&T9Kb!8q}=I~R2j5lGUF2glHV;J>u`)$sftXZML&=2SE zI3$TXi`rl;d5*1Qhx+AP0>s11M1We0lgHEM+X=x+a#~!t%O}FIJ}WaF*CJn=6xgA6c?$?Xo`lEXh#P@tm=DA>O2x zQLeX!f)Ay)>)YjdiC7}@CT=$ICgGPO=-*K1&wYi+1#~`{H~x)UAaBN|dS)JPVsgBH>(GQ3>Wy4M(Z=O;C+p4al51BV@bBH(Q zhfI+-bexauI72^Bovg1+d&m;f&ktE5@?Kc>N90dush4V;@`_?3V~Gd@19xayBDX}& z2hNg9Kk1hcKL%?268Sq_HQzW(j+6O+cPq@28^RzxmXsHdi~@R(~ayEHM7xu*6=&5<2ns{SpbEM(&rC`yH=~Sdw@~sK8p6p36m-9N_Z~0ggk> z=TjL=8b2Q?Y%tqk_A!Yh#FEyJjUc0*fcBQ1|B$g{Spz?5mvWcVvkXa?@3Quq)g#Ah z;2^C}=PWsOwq!a;7a8k8RxV06-FAN%G!%!ZGt` zXl6Udm9ylkou%ad_yE=+35|s^{Q$zycUS|L$5&uuq5O3s^QC}EWZqo8;Q;n9wM!7= zjVk>a6kmG>q0#d*=Z%~42CO`741X4+Eabd-5b{jw`gsSQizGoKQDclZ*RdsayvY%s z!VBchfO>NIJyuS>Hf_e}y97=Ha0$h7uQ*fiv}Km7gv9j#c?FUJ_5_>0=<%1>*$ceR ztS=}S^45G+;Kg|xLv4rV?mw}+tpz+FuVIadEt^#Rh_IqWGfOvo8iOH63QfhMy2n{T zF-NfiR(MdH0;)Y{8*bp8JETcJS_+3YLFfue^3;V)0eE&jQ}$1W7Ne z%2(y6xvFFJ)vy$wRJy9Y)~Ahq4@~sBu&$t>l8?nI@kRgUCCqo9-%-SWXH&@0Tvbz8 z;&b->U*%s2Yx2|JazScA{uTMEO0cVP)Vr$3cvX!q=LIZ)QN`XhDGN@P67`vS&N_suY^5dStGEUK(AE+Gi!zdui%x|U34~^Wh9iVeXM%oHIv?^2l?S2;EW7g2xvpnw4`Z2O(>c@_nWUDfl5A*JT{aBYx z?3#^W8Mkxl$Btw9oO#!Z(`k4==E%mODedb7tD!^t{(XsN^0vW@j^_+Etgp+j+9TN- z>eTII(2wm>>i1*0J*gi%n0y!eF}iO)25-HXjwttI%@U~}TVG#7zxgk$qhP-5v5izm z?#FsQQei))e%uNBv0SWU%j&p4raDTEAOCdr6C9_f=WOpJ_y1Iy#Z)NwbrG(1*w@83 z>xX^aWoieu6<R>m-=ven{Kb$*nc>f7sWZq1*WGR=BVGLl~{s*L4)n;Mh08)K5DG z$4&rrchsGZ%lf(sB~eeTuPZK9z~{`y^uP9XZrBEV3~r1qZ8!#(@EPKMGoAQHeVvV_ zuRGQhuZ#M+u%O90cD;D z&>0%Pdd~Vf)!56z3bPevzS~K{{APDwb-Nwa;Kk=8Nc8eSTj>&UNvyfNvXK%+UXZ3AOqa#rxVEQJ3{~=4o+~@rF!v zDIc}raX;$o`gc^oZ+VNl-f*XLow0})8^xE$bCHC`@)J-e(USodfc>Fg-ALDO@%^r^=Gm%%mvOd38qGHgbH`Hh zueb0vAugq1`GdQ+7<@RFcr0$ila*} z8|Xvk(wwElr9+cHwpGCwWLF+LSEG2UV}WF)vBl$hV-8uvje%nf#{ASy00|bX6_8z| z=O4056D^bdbNRD`)K@i8nWac&>@tGQCa1LQl3O(8;iv^a3I90-yfz}O|kObP7<>J zoMC6xCtFkp$9HD)<}mv|^{lVpwz`;!5=g>)U7@1M#Io06R(|<>CA0tcjn7JnTb;2E zNtpe=zAE?x$AId|%%E&$|I7Xigm>8`&>l!a_TR~=1VkSYFh<#SZzX2`CExlm{~VZv z?7!s1KCt9-QP>EI-GR*h_axhke{I@~F(BFgR~PvWYCKawe|+l`nmVY~rT z8R%C~49#t|ek^WAg_dZ$DZv)#Q$%4M9@kIYO6QYp_nH~m?qs6~v|Xz6gdOKyHq}vT zSTgm{N3`9WQ$jlE+wKM$lB31(cwO66vfb11LuH0I~{-fV<7{}N{G-GV}J6$#3_!xT#ncH`_!hXj`VUC{d4i|?Q85`Ix0Zn&D z;dESPy9@83o|xY;*p&Q^zSjTM@6g5mo$zTe^gHNua=gw;>v#D4E%qd$-5cyYYx4e{CI)zM@T#gm^Kxjxk(VDnLhQ)g^)PVv=fu$n%6GnZ6aZ!Tg0(Y$aWua1~}v zLU8;(UK`sdZ4pmK7s*zw4lL`@5o7y9X5ii|9>;Y_JQ<7S@d4wUsAY&Javbf_Lsw)) z>HHnY3P&nr;|B9&I-cCmJB}t+^o#3(tgyoxJhne(C-FpPMf^$=WW})F`;ZlM93GFm z`-+aJ)UeCDmvIvtIDa_Epr0rG>R1u;f>;s0XbiG~ITBQe8m9jhm_wrRN3$lm$cikJ zF~|yglykqM=oG4BL1Qm`_$QQ|i>#>9=zbG@ABX1&UbZO6wb#eT>N8!an-lqbC30k4a(qOUb) z1-0>sMgW^;VGbQ!@`s^6j?abLRp}c3%S|E)`5!Sx*47Ir)PSvU0p>EEw9H#9=52g| zIY5#SPx?3b-DFDe4X9*1E7^qkA0JKfq1WEOuntLxC%qcq6Q)le2;)tjoZ$Y)_AP^i zlW$((vrH1172QiZ;c<_q)@8oMupL2C#`ZXjk+lxdu;Tt~*l%J2vrN7EWHH~uv`dgE zB>aiTsT06i(Q=vy>%2s$4*@F|Ggd6I_SfVINmAk%YJ;(25Vn$z6)s{tV}*iZ_pE#* zE0<&Yq0k+=tU=4Gf#obFLfRyjL=??dWe=;O-ij=lIU7qEOSrCyCB3oy!n8@qOgSc^ zV7_%qM4c9DxRYu(5D}-{u1Rz}**Dp>n|O1x!(QagDHdNK-z0A%_f5((`(ALGc=Ig1 z8}eo!)-h&G>a~{+Df6aGHR8>c5_^$1$FPnGt8?-V)sg*l1`H!BTMG8b5Uu= zcKTmt$;lPOl3tHTBTMKwrtCOE0@acIjsxRs#;f62{EWu>Ea7>=)k>y4d^AWuKVr%E z@`NtZK-E;`ZACg`3HE$D|Io5TZizqthb;N)r^XCsVzM4f#)yB3l?_-z9-i)wbS&vb z`DVrvHydI}F~|QaOQ?kk`yCRt>yP}7^4K>S&N+xO!RulyX>F%tNsGGzoOBgnGPF4r z&RDY6EQ-Yr@{>qHt-o4X!WZVgsX3VQ zruv8~!kx6Mwnjh_#+$<(Ow@O7z>+VQTdNpv%4W}$S{%HFJ_SkGcxT%cA)xFac=|eH z#0%!XRCF+h^!L}X4oQeND@;1ViF7CU9S)YO&v>&Y^QN$2cb{U|8$O_U2_+p?A#X-5 zG=YOK)8{(l%^`=I@O;(oWDs99%oBD@Al{sIc0=CK)xKfliaX4;aKtDb z`4j2(t&lgd&D6*n3F~}eby^&xYm#|0_Oudtvns6*^2QwHJWrVZp6bZFc@#~&*%C7u zdDBeyZV;Ea;3$nxtC`qh@II*nI8d(ygiJiJ(D+3fYYGB#IY?|o~6PYD#+Ki;p zG-HXSJ+Z{3`2U6_mKv7Oef&LkDzikw>*QmYL*95@#FE6Cj=DTy)5`#-whOQi2EB-3 zEJ-gASsdb15=n?9vv*)0k9k6GDAw@>W66gdmqf}FUX3CN^IbN0SP$9b3yqAyU)TLMAZ)gK?bkD>Mt^V(-gLehEnS+o2ha7e-gWoTji@okn+DjD zI^Oga%fU0`&83@ic`z%tpr*iWl5`mSrvcRUz;c$+n}`~xtOp-NQ%0}%xoH-vuSH4< zQxnQgsyn~vHlIUIA;uYwCj*VeaVcd=TcxCwsZ&$le=6Ib=k<6-umkR29ryRg{rBSj zGjRU_xc>*-{}Ar)gZuYAE$=^*?awoCeE)xQ{$D!E`_IGu<1vw_yZ-N;zst>!KZEKZ#j{7s-(i2C#t?rVoO1XO1bujX_2aO_$x6AnRNWAsM^62ccsDGKarfj^l zepgsaHKc`ZAFR*Y4Q6yaXPSG7qt}$Q&#Q6n<lg!(zzYuRn9T|+grH$8F_=&zNu@=R0Zw)Sw zoNISCd;k0Q4?4CUoiQj_Kx^{ z8UA0G$xh;a#^g#^jhOsVXpc;8re!k10d#jHGr4Ws8kbN{jL8;G#AJo*e`T@@whJFC zQs%)ht|TFm|DMm%#g%kSR%@6%MUB@*OinIUT$j(XN)q8i0}mc=mq017sI)~qr3tb zlTV#dN+UA-+yFi}aVD1xi3DK}j&`6&?HlfNu66Sj;{K#cc&?hBd~T|lBtVtPH0L&9 z;85Hb;Qpa6!1GxoaU`#qal1LTwl1Ib0D3YmH(9}~2J=~@b>dP<_iUBY<4$8*Lfg*f2Ze+Y7^%d0KO$WJtPDC1=Dg3G&XU_`cW8*CcwM(xCX#gFYB}m!?>VK`P8} z$=iqw`li6RIdN&`YT{Bzl@R1o96JM*?oXosEpXNw#kmHa44#N{bB{l5rho4|pS7EE z%q-4Dde*T^=TENG_>=N%Z~3?USxOqFnyI|6*umIk3Y~gLDtSJ<+@f_bpS2g~!~YDs z{4vgT1mj#I(4W-*PItyP?oVoOS{5687G{@=ctUKC{$y3GrG#-}0Tf4ewb8PR9xgwV zWQVslcGhl|;dHD(5!$qw-yikF{5DfpT|TRoN&xfQtzPsyFX%H@+Na!y&oD`xFUs~!8YBBwdS|O@)tXl21Floa%hcHS zGOkauZxxnX1z+?grSp6i_bCPxd9}(K=Y4HY*MEMeSkdw17jq{}H4rsd-x738-|#!Wlh1OKMyO^hA1Zb-+eKP5u+ZAB z+*%dT@A$8_J6g|n>AP;@wwv=)eutNMk=ZWyJEn*^f;a3j>#Vh1@;h{QB-?J=wvK_Q zC+2rNMLkK1NBG>xH2XJeS#Nr)GV>pR0t%x5WKWmXyHFG!t2C7QDXOd|85 z-aBWw0VAyfJzC)toPD(#G&}i8!r2hx>aa1~eW&3Nmt~5+QeN>Zj2FukRiuO!B8EYl zuDr_fS&4~Ca9%1vW4PCQj2k@(DJpMGK8qyXDEi0zg;J&TW7I{2BG3ZIncb-s**J!@ zMLfwVi)&Se&Ml$F81#0EO0l>R*Cp{J7t6aPQH+f9L}tZ+doIX|hdHh(CKz#%`}w$o zbUeAAzuhbZS&`Tx4p~9DDjx57eU9g|I4c?#BUXrIZXhd)V4e3YCe(T|e&wt{BCM$V z1X)ocH|iH=vQ&f{=~u^!%u&ROkkk8+70sxCZOu;7hs=s&p?S!PHnumB74EzO{-3ad zzFOefsh=P2@O+XQy7vztQf@nKJBd+`ck-`uOQyiV?}~E2s0gf%z9{9fgKs> z?kJp&hW&ioww>Rio){}udk`y@m-}C{qR0&5YMN5qTVq7p1 z8g-lILACFBcGcvwNWx-5qlQ`+EmaGWg~UtT|5#&PPV93e$I1vuLOdz&b?3^m+lA;@QML{fKN18|&M z1CBjNo5YeE6>%=zmc=T{jjy8^D`N@QHL>I-mTyiST9b6l#~yrKk(70_l^U8ot!psH z_nJh6bz*>GOFHvV=_{ zra~BkdLfqBvhm5%x;|6XFy(#eV11v9=d;{xP(RG?ApPiA^7k>r_wrfp(pc3zG7iQE#if4~yE@2sJfSrV`3chGm;#{G_98oGUVE6kFr;vbA9Rd5enyCnu2 zxgtw?YguB0a@`&2Skitm>WOSN=4iPJsC_<9_JXGbA-KM*0wmYwYeI@NdMnWSvfLz+ zP+Y;NGDfqI?T2AuCZ8wk*Z;C~4*&Uikc8|yz4yU(EwA}}fhk|!zm=nL#I*Zw?)6DMBbv>;?Bbz-%>l2v0U1#3GgKVy9TZs%#QEYc3x@xUDgS>4b&86}B~BF-OnV62uGO0*`UU zQhD6Z2-ze+2}j)>$+lL%ehpL96YIA}m#2PvMAe_^w+RRGdUe^yrwjdiY*GC$V~a+b ze*5q?ye`&nr}*gl?TarYIDzZJYQw&PmA}#ct*l-iAFI(07n)`x8)CS`~8n%)h zvl`Mfh)bc~9DpVMa(Ox{mpO7*JOxjPBeY7A?Z2Cq%efxvqiRpXwUkbXP-Bxhf`e8w-B;1o_iE^-=C`*L5 zj2mT%UcH=V(Q)Q9yQG;Jwu-s-yqone*70 z9rez90ngkE&%6Q8?1yKL#WP3YnXBTNPvV&`;F)Jq_Tm3{=6rT$6TLJ4n|qGfBJ1oc z?oW%!xXyn2Y@0s&Uha%uL#NM2o&DM|W7D44>JxU;m7i+AE%jdP#61^wX8hWo#=mSt zN47!KPpOfu`bE*OScRbZX1)*Dec_u-xaAP_Q?a~7&^UUTg~kiBW+R_bUOSNbUSH?* zC%<0aHki@zoHZUz&*HU_`bpmB4XD3Uv(k!FzhhUT{+GDFkovC}i7EQycbbkUj||IH zZH?4V$?1U9f3B^wi8)&`^-J9_Lh4t}*^bn|i*@Xor)EBnjw7$Mx^`^*ZX4+5v7(*) zlvC+q>PXO6z*&qK-R&Ow7JG&s$@{QpsIToA8g8OGcPcUM;fRj(^P`^O{=e!Otl*EU zRkb~X+!8(CeSbvv|F>tTEq>JN8Kz^;Pyy7I!?Znv_?@01sut>r^$dxXsArh#`(Jwo z-3-NVt)jC2mpy~6re`>L8Lx|ahUB?bby+9d-p1gAtElW@$1jsu&#)}36w5k&Od<*O z4D)?V!Rv_t10dtZlhX7oWKB>C%gvUX{pv>&>KStW^0jXLx;6w!(SzoAsnHIGugnul z{Z84hF+mBg(Kd>;D+s2qZi&( z=TN;X@OD8RtV0qBO+FZBK?S2nQx@`z)nnJ(Y|1S0rgRgZWs)e7zNg}G^%M3UPr$M> zpDp0~HC^Dd1xP}@$AivOVYIyk+=N$4F1gdWR@%-GDsG__Th?Xx+mj@Bj6Y2RTqU}9 zVLvyz_t?m>a6!6&=OT&!8PqE4Ax>dy>w1_*xN4Ysn4ku7`6X5^_aLo>Sk{C1dty0b z61563X1C)K8yD zv#scO&Uj@MvAOuilI7M=J>aVWla^~%S#c)$S0N?^w?C+15?}pUigj!JD{CWhOUPY--1?$DP{l3uRbFM)=41MFHAHuLZZN{6 zcEpzagS7&(jr9B@w#jkaAA7xO5cm0O*(SGWPmS06J4UNo6nab3kJxrhFDoT~r>o{0 z_j+H-Kfn1|*y{}tC5f_9IP60`PZwWeZ=<#x^N(!XMk_UlA&Db>by=yaHB_(^S6N*I zhv)o_0wD`mN|UT6S^erq65_*_gVWUqrq_Yv1$#zvK9qBx0cIE7FyllL<~g?cVzTe` zU3f13me2XH^vn%$^nG`%LlWY{lhPlB*i*yc*vEBh&WDXDQPQ2o9{A9cg!r(~*cMi~ z2xv`zjtXFWc)Q+HIHo*?9Un=E5A$LbFcdS_7hr79%ATY&yT^^;Fw0z%g!r&>WE?a~ zwm>Zv^}WgXF#Wt66x~iMx@11IbQ7T-W~KT-la{e=be#Axw$dKu9y}LGmQR-Ln>0rD zJt_e0x996}kZI_%Do|Q7Ys2};+c%E!`@}rVyyQnM>nXfSVK7Q5Ou39A9U2$k6 z+AfVo`I|%Tu;7iP$tZ72?~Aq@bjujC#k!4jOwSZD2`y{TLrb(>hY6S3>-!vs*$;{i z(d@$v;T_uU)D@0syEC*tN73zc9C^0$^Weh?YPcO!%)oX@#{e;dW!ohkYHSzBZW72g z8ZT#*HCZY7xBRIa-_eNG8eEq**4nPzT0Jxw<^P54VmI}Jt+4IZ6D_0;*t!%NRKiSg zF1C=`a+20|X~gPh)Kw9zNHux`;dEq-GzSGOq*>w2FDdOueu;PB&-f+O>V-$F61H;T z5i6bU@3WnCD<^cbVeB-1$;gj*U2Mb}R$G^q+VXI!x|F9sJj5TyDyFzgZ?2eO zHi;y}i?p6zD*y5Ku+vX_s9^rYy$vx!#A6GrLlQR9EN3aY^%)LJo^2@oocR;utrg;l z<(627B*cr3DNgWVs{or}_+>xFi?&w}NSn+yq1BOucyZ-|5~2dox~`Z@VYb z2pX6~=7n)}OB{{13%ba7krBUFgxw0vN;y8`D<|eXG=|yuHpb;(88eXaqSWGz!YZ>> zcpQ?rwm@w#e|Q;`)du+B3UaXP_PWz$-J;((O33R%%+f#$`1^pN02`lV+Wvq|{v z-AG$x#f17!-Sk<(S8d9XWREVyirknD$cl#OnQFG(^vNR0c&=VM&&4vq)PK(%pWnf?C0=TDJ*{oEvy zkpB_W_PBb&VSflSdHR&|A;|x!tZTR1Fg089Z2An_W-0yihUG zDiQ0Dgm_|e$_VOWCfo~}Un$ObGP~a}foH-=!gw-$7#zv8#CM!_{^JVcNqD1H!n1v} zqRZ;=6_(|0z1|2ud5GwLoKNPnVj6A?fN56KuntMC1f#|nPZF>tbv*e~yw7;zL9=F9 z`2tohXRh9ZFLYdkv!=UYIUApl#)&u08)d5&zZ9e$n7Q(&Rd39H;q5`ZX@TW4jLub| zR^#In3&w!ceLO?eaMEw%0R8bvmPE&sGgqy)5tF8!9*3E$ljsZZ6;!vc>-#TRk;J4g z=jI@j=&g?2e`)cQ&L@vO#+4-|ZS(sJnREi{STP@G%WA44;j=`%S?zEKnN(uYOauRg z+K8CMS8UFNV#uV&)$MxgGl^%@WhQM)CnmK{IZtB`JQv@d?W0e&@)OT>>)P#^xC+g# zzd@#)+6d#6zc39WlSqd@WRm8sjxvknPeUfzLdRZRv`ms)>$xVo^)pPWgEQiYLlkk> z|4vuUH$L_lrz5dkp!ZprNsYvkj7ju>kpD7HP#}|LYngd&%UL6u0t zBHNz7tDkiWfXZLam!8f1jip=LLgwu|nB5`?@uB~W)2e_q_rYJx{J{C}K75&2{l#5d ze2W=Mh!39E9}A<`kAPaQoStz$tiMu2N=m+mbx1;X?NT-xCbYGJm(bSnI{Xk|WVbcW7oabpo4u0B;sLTR z(P1~)?Zr{SXty+C;C5U61+|%Mw`C8DXt!=}*Q4Fi>#g{kS(1{ejyztNZu}nY&9?S1 zw6}#?d%Jju>g3Yf)L8b4?)^t&ft8vVWxQr=Ab%R#QV|%^w3pVFWGzQ(#_{KWVjM5q z56v#s|4vuUH*QOD^3QL67Ph6PqPM|VAPy}`ZMi^eOEea!Zq!N9NU_0SEU-;G7I=Vq zk`xcHz2(TpKhIF3ODo*JldN$6PGg3DH#1(L>EFFu%Qo)RSZCvl9y>xBX0J*@dd#oP z#;>{AvstG3NhBc~pWGE^$7A+t4%Dxa#cX^;gpy^i>gJP#Y`kL0?&{#T0We*1JHdT` z+-fhywELNuy&?(o0owLg9j@{K78J}4<2GKUepR7l&PmKDk%Vl#SB=X;=|&?lE^u=x zxAFAq7lrtgQ&@*2WaBIL^@e~ytZ-%Lkw;gVjl;Ro;=ZGYv5vCIHTS8sN{HFGx`BS& zaGdB3{uno`t$iDzEi0G%pUzS`Ji^S>Ra!&9_IG0Ca$Io^zP+g?W~S`uZG|kq)EPBN z(Kilh$}dH$rdz0>s!LqTE}`Yo9TmPlEnlhYhjQ*t2~DNiUjo1jUu+mcegWIR8`~eF zYt+OnKh+BN_YJJ-(lBM0)Did3!u@M}F6Uk}VVaGD7tVIUR}fb2Ebrfw?ax=<@crrh z_VHC+x}@wfj=}wp;Ql6G%elKHG_@S`IRG~GE$a7qk-UE-?oYWM-TBqI<+i;WQFUct zg+=4?j#b@q#QRceOEGkL6#9Yso zFf3&me*T;hBVDk({E}-dn86vz$1cLwd}L&LAA18vZZxCgIpZ@=G0G(&o0nL_h-m|N zP-alxd1`z z+=du=-SZeSl3gtGZQ@g?4$ac1m`bBA#K;a$E+8Y*wT#?%lc29wB(@8!9-{5R&gnRNa(D{RSUE~KPi@~})j$@1y zSYsaN06d*Kjxq9mr&N)~6CaaELW~S?GlGae1bpwfOSj#Ok(D~H0?Olzu1FHb$d^y7 zw$2KKtM6;nne7$dB3rd)-><@g$NredAqk7S_ynrzAAbNopRReCcu*as+Zjoj7l3&a zk}yB0+#ccjlaVmyN$2L--c;x9;=T~Mxh~cr35}B`_XUWX1<()7YWcEjhMNxJZRs|S zaY;hsq0A~wY=t!^XrFy|;jv0t=b*bN(^u*#U&s*y9Jk~fCsxw8znY7k*4l#bTX;72p zc}7RSKL&Zy4W21?Svt(}JS1V`v8#PymytDO!J6Jz89$<$Y?P*- zp_NWDKkTAZumtlwCt-gJp6401AyMS3k4RFbv25R@F|zMh?Xp!(S9S30(r~`nr2vh6 zFXQ?o`+kk(=RS=pM%P64&1@I#;9RvSi>+boj-$KuZFiCt9Z!zk_EV7U`qeN)+ohNT zx68Pv`f-vQE68@&88t-PrN0EjR}|#Dr}N3S+ifh_?(>*6XuGem4u2bc$Tq4Y=Xsnw zve9<8ZM$HQqa_{FGsW}DZ@+}0?bg4T*;M8tl^$k4I2&DJuiyg;y_okO+Q0l zEa*6R?-!(7^VINljA5RKuRhw6GVjfb;JrXl+++tvUa} zc57?mB=jZ<{qOQUk{?HZNoTZ9@QrVUZMT&eBz45dRTZpDwmTZHS#7ySYrEf@e^UPh z>WTR+n_7|Ivbp`w_$}Yg^Uzxm3|BqV4aj*OT5J2g*sX*;68BruEb+RCDdR7N>he4l zKi;t#dAu%^dFSUflldDl$99UnUsz#&h9qoE_U5Ik=^qcF#`}Ig3g&NAdH5b~e6q$m zBw=H+P8)@4o}*z;R(6wT%-_g~S}N4sWrKA{LcF*c#+#rs%Re zoZ$XOXe$ML#XL_3xYur^8)++JQW=52O^+lwGy-S-#$#+HU0l{qJPeJ{-|?Too_5Uh zkhX{?*E`{yn(Xe@Wzkya&z`nHBN3N+2uR&8Uy87>;Fp z1##~ebUbZ8|B_gdqv(pP7=(4WFL2|Nex65ZORN}_PH)qr<7BZsPt9HU6EYv>m?1o~KVa z&lBUUny-en0SN~EJYRiudnwZ%j&Vpo|G)}1u#_1ge;Tr)D7?5iL(2-eC3;{Si2mx< zZ~rn5ME$(X2Z{sff7je1esEU&suO(UTVYnT7Mtp^VxIUb627+8x_@LvCapYStXR~B zSh2M8&#}S@TfT6f$Nq<`_;-1pJ2c0X`5*h*>+(EGbWmR5cws%*%^lC|cge7UEYI^g zi6qSb7}8CBt!q8#Y;@ro=SkxREreD%A25eQ62_B1^HrHc9>Gz?$TyrP2an8+rk2? z1z3k9#FNDN_!p&Gi#YCBd!QxbNzI+2FxP4>)*%V=KYEXW%I-E02=2l~#*-N*uE8&t zXr+_ggUc+>6WYlbx_OE?2XDDW6yr%|w+v~z)pV>wk|mC)F~*b2*pfP)jF57mA@XEz zb-DaDE0^;;BXDkihcy6QpI|u~pOD6hH;21st19G4z6qG;DK`#FS)PZt2l3`8miO!8 zTAm(HK0e{T{)^xaZPl>ztEa*EBuk>>$xM2iPE2x#=g6c?v~T`KmR33X{!58kZIMY! zb5oH?8CZw^g#r4zSvvpa!+Jm_T`q4npRal@&0-;LEcZh1aV4MPNOm+bDWT5CK<3cX z?zmAK5tH~z#)1z6kV%`Tn$^>1615SJJJa0QwY!N)7n1iPll*xw3QK>vM0MmY7JkJoQ9(tLLPwrGyvOJG-5t0xeUX7Wdu9064vOd04&0_w> zs8fGPzIpd?Y(o;_L)zjPRYS#Nc=KtykCOQtNh{sOlnD>fZ6yiu;mMeEVQRz}n4Ukj zC+9;>mGh$6p+{JUBxKj!gT_Jjb{psf)`u=LyWTK7N@{S8RyvVghf|D`+3Y{rBx!PeX zWLu(p*VxiG=Y0LUJdYEUTC+-POR|=0{)hg(mS!w45p7BTJ6$#3c>k`Dl}5RGbH2u8qMlg)KC%n-?{VQj)4$V| z74F|jR(LExe@pZ4d7f|0`I6sCx6Tc(i`n?JZaNz;`cMrUG0$@w!k%#(j~%~UqB&Oi zNhBc~ACGCl)pZ4obIusNo7s3xyHx_MQu<^}60-5=aySjY@s&ZgIQP}r|2nhriwz~Q!cAJq)OpTT_j-@&Cr$CWW3v2awI#&w*rH=HfNP_7#8i%m`&#?XR{Q}zkeR2Qyxd&|m zUwWF?D*vlh=Ocam!w1x_+}L{*j5H6Hs+LSJb$cZ5|2x~?L~nmO|Fte-EE7JwH(g!n zy+!vU%jzVqO)k-6gPovEY$#2}{VUv&_rHSsQ=W&PzwMIC53gTMoZop$p!M$k$7fD0 zw +# Date: 9 Jun 2005, 20:52 UTC +# Location: Bend, OR 44N121W +# +# Roof-mounted stationary GPS. This is about as dumb as NMEA gets. +# This log records a transition from no fix to 2D fix and then no fix. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205150.00,V,,,,,,,,,,,V*4a +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205152.00,V,,,,,,,,,,,V*48 +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205154.00,V,,,,,,,,,,,V*4e +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205156.00,V,,,,,,,,,,,V*4c +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205158.00,V,,,,,,,,,,,V*42 +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205200.00,V,,,,,,,,,,,V*4c +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205202.00,V,,,,,,,,,,,V*4e +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205204.00,V,,,,,,,,,,,V*48 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205206.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*49 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205208.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*47 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205210.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4e +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205212.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4c +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205214.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4a +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205216.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*48 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205218.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*46 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205220.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4d +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205222.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4f +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205224.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*49 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205226.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4b +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205228.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*45 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205230.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4c +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205232.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4e +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205234.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*48 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205236.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4a +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205238.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*44 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205240.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4b +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205242.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*49 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205244.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4f +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205246.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4d +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205248.00,V,,,,,,,,,,,V*40 +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205250.00,V,,,,,,,,,,,V*49 +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205252.00,V,,,,,,,,,,,V*4b +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205254.00,V,,,,,,,,,,,V*4d +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205256.00,V,,,,,,,,,,,V*4f +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205258.00,V,,,,,,,,,,,V*41 +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205300.00,V,,,,,,,,,,,V*4d +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205302.00,V,,,,,,,,,,,V*4f +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205304.00,V,,,,,,,,,,,V*49 diff --git a/test/daemon/magellan-ec10.log.chk b/test/daemon/magellan-ec10.log.chk new file mode 100644 index 0000000..e1dd3ed --- /dev/null +++ b/test/daemon/magellan-ec10.log.chk @@ -0,0 +1,97 @@ +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205150.00,V,,,,,,,,,,,V*4a +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205152.00,V,,,,,,,,,,,V*48 +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205154.00,V,,,,,,,,,,,V*4e +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205156.00,V,,,,,,,,,,,V*4c +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205158.00,V,,,,,,,,,,,V*42 +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205200.00,V,,,,,,,,,,,V*4c +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205202.00,V,,,,,,,,,,,V*4e +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205204.00,V,,,,,,,,,,,V*48 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205206.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*49 +{"class":"TPV","tag":"RMC","time":1118350326.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205208.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*47 +{"class":"TPV","tag":"RMC","time":1118350328.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205210.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4e +{"class":"TPV","tag":"RMC","time":1118350330.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205212.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4c +{"class":"TPV","tag":"RMC","time":1118350332.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205214.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4a +{"class":"TPV","tag":"RMC","time":1118350334.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205216.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*48 +{"class":"TPV","tag":"RMC","time":1118350336.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205218.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*46 +{"class":"TPV","tag":"RMC","time":1118350338.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205220.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4d +{"class":"TPV","tag":"RMC","time":1118350340.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205222.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4f +{"class":"TPV","tag":"RMC","time":1118350342.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205224.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*49 +{"class":"TPV","tag":"RMC","time":1118350344.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205226.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4b +{"class":"TPV","tag":"RMC","time":1118350346.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205228.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*45 +{"class":"TPV","tag":"RMC","time":1118350348.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205230.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4c +{"class":"TPV","tag":"RMC","time":1118350350.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205232.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4e +{"class":"TPV","tag":"RMC","time":1118350352.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205234.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*48 +{"class":"TPV","tag":"RMC","time":1118350354.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205236.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4a +{"class":"TPV","tag":"RMC","time":1118350356.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205238.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*44 +{"class":"TPV","tag":"RMC","time":1118350358.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205240.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4b +{"class":"TPV","tag":"RMC","time":1118350360.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205242.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*49 +{"class":"TPV","tag":"RMC","time":1118350362.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205244.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4f +{"class":"TPV","tag":"RMC","time":1118350364.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205246.00,A,4405.556,N,12118.398,W,000.0,000.0,090605,0.0,E*4d +{"class":"TPV","tag":"RMC","time":1118350366.000,"ept":0.005,"lat":44.092600000,"lon":-121.306633333,"track":0.0000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPRMC,205248.00,V,,,,,,,,,,,V*40 +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205250.00,V,,,,,,,,,,,V*49 +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205252.00,V,,,,,,,,,,,V*4b +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205254.00,V,,,,,,,,,,,V*4d +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205256.00,V,,,,,,,,,,,V*4f +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205258.00,V,,,,,,,,,,,V*41 +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205300.00,V,,,,,,,,,,,V*4d +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205302.00,V,,,,,,,,,,,V*4f +$GPRMB,V,,,,,,,,,,,,V*66 +$GPRMC,205304.00,V,,,,,,,,,,,V*49 diff --git a/test/daemon/magellan315.log b/test/daemon/magellan315.log new file mode 100644 index 0000000..8a5c293 --- /dev/null +++ b/test/daemon/magellan315.log @@ -0,0 +1,28 @@ +# Name: Magellan 315 +# Submitted-by: Ángel Marqués Mateu +# Date: 12 Mar 2005 +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGLL,3908.8199,N,00023.0832,W,120824.758,A*22 +$GPGGA,120824.76,3908.8199,N,00023.0832,W,1,06,2.1,00176,M,,,,*39 +$GPRMC,120824.76,A,3908.8199,N,00023.0832,W,00.0,000.0,130305,01.,W*62 +$GPGSA,A,3,19,15,03,18,22,11,,,,,,,3.5,2.1,2.7*34 +$GPGSV,3,1,12,19,77,349,45,03,68,117,41,22,39,052,52,11,35,274,56*7E +$GPGSV,3,2,12,15,22,062,52,14,21,106,,16,10,171,,18,10,040,47*73 +$GPGSV,3,3,12,01,08,146,,20,04,211,,08,02,294,,28,02,328,*70 +$GPGLL,3908.8200,N,00023.0832,W,120827.523,A*2C +$GPGGA,120827.52,3908.8200,N,00023.0832,W,1,06,2.1,00176,M,,,,*3F +$GPRMC,120827.52,A,3908.8200,N,00023.0832,W,00.0,000.0,130305,01.,W*64 +$GPGSA,A,3,19,15,03,18,22,11,,,,,,,3.5,2.1,2.7*34 +$GPGSV,3,1,12,19,77,349,46,03,68,117,42,22,39,052,50,11,35,274,55*7F +$GPGSV,3,2,12,15,22,062,52,14,21,106,,16,10,171,,18,10,040,49*7D +$GPGSV,3,3,12,01,08,146,,20,04,211,,08,02,294,,28,02,328,*70 +$GPGLL,3908.8201,N,00023.0832,W,120829.500,A*22 +$GPGGA,120829.50,3908.8201,N,00023.0832,W,1,06,2.1,00176,M,,,,*32 +$GPRMC,120829.50,A,3908.8201,N,00023.0832,W,00.0,000.0,130305,01.,W*69 +$GPGSA,A,3,19,15,03,18,22,11,,,,,,,3.5,2.1,2.7*34 +$GPGSV,3,1,12,19,77,349,44,03,68,117,42,22,39,052,52,11,35,274,56*7C +$GPGSV,3,2,12,15,22,062,52,14,21,106,,16,10,171,,18,10,040,47*73 +$GPGSV,3,3,12,01,08,146,,20,04,211,,08,02,294,,28,02,328,*70 diff --git a/test/daemon/magellan315.log.chk b/test/daemon/magellan315.log.chk new file mode 100644 index 0000000..6429845 --- /dev/null +++ b/test/daemon/magellan315.log.chk @@ -0,0 +1,30 @@ +$GPGLL,3908.8199,N,00023.0832,W,120824.758,A*22 +{"class":"TPV","tag":"GLL","lat":39.146998333,"lon":-0.384720000,"mode":2} +$GPGGA,120824.76,3908.8199,N,00023.0832,W,1,06,2.1,00176,M,,,,*39 +{"class":"TPV","tag":"GGA","lat":39.146998333,"lon":-0.384720000,"alt":176.000,"mode":3} +$GPRMC,120824.76,A,3908.8199,N,00023.0832,W,00.0,000.0,130305,01.,W*62 +{"class":"TPV","tag":"RMC","time":1110715704.760,"ept":0.005,"lat":39.146998333,"lon":-0.384720000,"alt":176.000,"track":0.0000,"speed":0.000,"mode":3} +$GPGSA,A,3,19,15,03,18,22,11,,,,,,,3.5,2.1,2.7*34 +{"class":"TPV","tag":"GSA","time":1110715704.760,"ept":0.005,"lat":39.146998333,"lon":-0.384720000,"alt":176.000,"epv":62.100,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,3,1,12,19,77,349,45,03,68,117,41,22,39,052,52,11,35,274,56*7E +$GPGSV,3,2,12,15,22,062,52,14,21,106,,16,10,171,,18,10,040,47*73 +$GPGSV,3,3,12,01,08,146,,20,04,211,,08,02,294,,28,02,328,*70 +{"class":"SKY","tag":"GSV","xdop":0.76,"ydop":1.47,"vdop":1.85,"tdop":1.37,"hdop":1.65,"gdop":2.83,"pdop":2.48,"satellites":[{"PRN":19,"el":77,"az":349,"ss":45,"used":true},{"PRN":3,"el":68,"az":117,"ss":41,"used":true},{"PRN":22,"el":39,"az":52,"ss":52,"used":true},{"PRN":11,"el":35,"az":274,"ss":56,"used":true},{"PRN":15,"el":22,"az":62,"ss":52,"used":true},{"PRN":14,"el":21,"az":106,"ss":0,"used":false},{"PRN":16,"el":10,"az":171,"ss":0,"used":false},{"PRN":18,"el":10,"az":40,"ss":47,"used":true},{"PRN":1,"el":8,"az":146,"ss":0,"used":false},{"PRN":20,"el":4,"az":211,"ss":0,"used":false},{"PRN":8,"el":2,"az":294,"ss":0,"used":false},{"PRN":28,"el":2,"az":328,"ss":0,"used":false}]} +$GPGLL,3908.8200,N,00023.0832,W,120827.523,A*2C +$GPGGA,120827.52,3908.8200,N,00023.0832,W,1,06,2.1,00176,M,,,,*3F +$GPRMC,120827.52,A,3908.8200,N,00023.0832,W,00.0,000.0,130305,01.,W*64 +{"class":"TPV","tag":"RMC","time":1110715707.520,"ept":0.005,"lat":39.147000000,"lon":-0.384720000,"alt":176.000,"epx":11.328,"epy":22.003,"epv":42.504,"track":0.0000,"speed":0.000,"climb":0.000,"eps":15.93,"mode":3} +$GPGSA,A,3,19,15,03,18,22,11,,,,,,,3.5,2.1,2.7*34 +$GPGSV,3,1,12,19,77,349,46,03,68,117,42,22,39,052,50,11,35,274,55*7F +$GPGSV,3,2,12,15,22,062,52,14,21,106,,16,10,171,,18,10,040,49*7D +$GPGSV,3,3,12,01,08,146,,20,04,211,,08,02,294,,28,02,328,*70 +{"class":"SKY","tag":"GSV","xdop":0.76,"ydop":1.47,"vdop":1.85,"tdop":1.37,"hdop":1.65,"gdop":2.83,"pdop":2.48,"satellites":[{"PRN":19,"el":77,"az":349,"ss":46,"used":true},{"PRN":3,"el":68,"az":117,"ss":42,"used":true},{"PRN":22,"el":39,"az":52,"ss":50,"used":true},{"PRN":11,"el":35,"az":274,"ss":55,"used":true},{"PRN":15,"el":22,"az":62,"ss":52,"used":true},{"PRN":14,"el":21,"az":106,"ss":0,"used":false},{"PRN":16,"el":10,"az":171,"ss":0,"used":false},{"PRN":18,"el":10,"az":40,"ss":49,"used":true},{"PRN":1,"el":8,"az":146,"ss":0,"used":false},{"PRN":20,"el":4,"az":211,"ss":0,"used":false},{"PRN":8,"el":2,"az":294,"ss":0,"used":false},{"PRN":28,"el":2,"az":328,"ss":0,"used":false}]} +$GPGLL,3908.8201,N,00023.0832,W,120829.500,A*22 +$GPGGA,120829.50,3908.8201,N,00023.0832,W,1,06,2.1,00176,M,,,,*32 +$GPRMC,120829.50,A,3908.8201,N,00023.0832,W,00.0,000.0,130305,01.,W*69 +{"class":"TPV","tag":"RMC","time":1110715709.500,"ept":0.005,"lat":39.147001667,"lon":-0.384720000,"alt":176.000,"epx":11.328,"epy":22.003,"epv":42.504,"track":0.0000,"speed":0.000,"climb":0.000,"eps":22.23,"mode":3} +$GPGSA,A,3,19,15,03,18,22,11,,,,,,,3.5,2.1,2.7*34 +$GPGSV,3,1,12,19,77,349,44,03,68,117,42,22,39,052,52,11,35,274,56*7C +$GPGSV,3,2,12,15,22,062,52,14,21,106,,16,10,171,,18,10,040,47*73 +$GPGSV,3,3,12,01,08,146,,20,04,211,,08,02,294,,28,02,328,*70 +{"class":"SKY","tag":"GSV","xdop":0.76,"ydop":1.47,"vdop":1.85,"tdop":1.37,"hdop":1.65,"gdop":2.83,"pdop":2.48,"satellites":[{"PRN":19,"el":77,"az":349,"ss":44,"used":true},{"PRN":3,"el":68,"az":117,"ss":42,"used":true},{"PRN":22,"el":39,"az":52,"ss":52,"used":true},{"PRN":11,"el":35,"az":274,"ss":56,"used":true},{"PRN":15,"el":22,"az":62,"ss":52,"used":true},{"PRN":14,"el":21,"az":106,"ss":0,"used":false},{"PRN":16,"el":10,"az":171,"ss":0,"used":false},{"PRN":18,"el":10,"az":40,"ss":47,"used":true},{"PRN":1,"el":8,"az":146,"ss":0,"used":false},{"PRN":20,"el":4,"az":211,"ss":0,"used":false},{"PRN":8,"el":2,"az":294,"ss":0,"used":false},{"PRN":28,"el":2,"az":328,"ss":0,"used":false}]} diff --git a/test/daemon/mkt-3301.log b/test/daemon/mkt-3301.log new file mode 100644 index 0000000..fccf2d4 --- /dev/null +++ b/test/daemon/mkt-3301.log @@ -0,0 +1,76 @@ +# Name: San Jose Navigation FV-M11 +# Chipset: MKT-3301 +# Submitted-by: "Henk Fijnvandraat" +# Date: 23 August 2008 +# Location: Enschede, NL, 52.21N 6.88E +# +# NMEA version V3.01 +# +# Dump made with FTDI TTL-232R-3V3 connected to module serial port +# Log created with Kermit logging from /dev/ttyUSB0 at 4800 baud +# Log shows entire power up to first fix sequence +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# power up +# +$PMTK010,001*2E +$POLYN,TIME,RESTART_OCCURRED +$POLYN,EPH,0,00000000 +$POLYN,ALM,0,00000000 +$GPGGA,235946.005,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*49 +$GPRMC,235946.005,V,8960.000000,N,00000.000000,E,0.000,0.00,050180,,,N*47 +$PMTKCHN,14001,29001,23001,02001,21001,11001,16001,28001,05001,20001,22001,18001,06001,19001,07001,09001,25001,08001,13001,30001,10001,03001,04001,27001,26001,01001,24001,15001,31001,17001,12001,32001*46 +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,235947.004,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*49 +$GPRMC,235947.004,V,8960.000000,N,00000.000000,E,0.000,0.00,050180,,,N*47 +$PMTKCHN,21312,02001,14001,29001,23001,16001,05001,20001,22001,18001,06001,19001,28031,11282,07001,09001,25001,08001,13001,30001,10001,03001,04001,27001,26001,01001,24001,15001,31001,17001,12001,32001*4D +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,235948.004,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*46 +$GPRMC,235948.004,V,8960.000000,N,00000.000000,E,0.000,0.00,050180,,,N*48 +$PMTKCHN,21412,28492,22001,14001,29001,23001,02001,11001,16001,05001,20001,06031,19001,18031,07001,09001,25001,08001,13001,30001,10001,03001,04001,27001,26001,01001,24001,15001,31001,17001,12001,32001*4E +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,235949.004,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*47 +$GPRMC,235949.004,V,8960.000000,N,00000.000000,E,0.000,0.00,050180,,,N*49 +$PMTKCHN,21422,28502,22242,09282,07432,14001,29001,23001,02001,11001,16001,13031,25031,08031,05001,20001,18001,06001,19001,30001,10001,03001,04001,27001,26001,01001,24001,15001,31001,17001,12001,32001*4E +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,235950.004,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*4F +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,2,1,06,21,,,40,28,,,47,25,,,43,07,,,40*71 +$GPGSV,2,2,06,08,,,49,10,,,41*7E +$GPRMC,235950.004,V,8960.000000,N,00000.000000,E,0.000,0.00,050180,,,N*41 +$PMTKCHN,21402,28472,14001,25432,07402,08492,29001,10412,23001,02001,11001,03031,04031,27031,16001,05001,20001,22001,18001,06001,19001,09001,13001,30001,26001,01001,24001,15001,31001,17001,12001,32001*49 +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,081433.591,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*43 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,3,1,12,21,,,42,28,,,52,26,,,48,25,,,45*7E +$GPGSV,3,2,12,07,,,44,08,,,50,27,,,48,10,,,44*79 +$GPGSV,3,3,12,15,,,45,03,,,38,19,,,39,05,,,25*77 +$GPRMC,081433.591,V,8960.000000,N,00000.000000,E,0.000,0.00,120180,,,N*4B +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03382,19392,05252,16342,22031,14001,29001,23001,02001,11001,20001,18001,06001,09001,13001,30001,04001,01001,24001,31001,17001,12001,32001*43 +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,081434.590,5212.978993,N,00653.097906,E,0,3,,102.907,M,47.093,M,,*42 +$GPRMC,081434.590,V,5212.978993,N,00653.097906,E,0.052,0.00,230808,,,N*46 +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03392,19392,18031,06031,22252,14001,29001,23001,02001,11001,16001,05001,20001,09001,13001,30001,04001,01001,24001,31001,17001,12001,32001*45 +$GPVTG,0.00,T,,M,0.052,N,0.097,K,N*3B +$GPGGA,081436.000,5212.982135,N,00653.101394,E,1,3,2.88,102.907,M,47.093,M,,*5F +$GPRMC,081436.000,A,5212.982135,N,00653.101394,E,0.039,0.00,230808,,,A*53 +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03392,19392,13031,06031,09272,14001,29001,23001,02001,11001,16001,05001,20001,22001,18001,30001,04001,01001,24001,31001,17001,12001,32001*47 +$GPVTG,0.00,T,,M,0.039,N,0.072,K,A*32 +$GPGGA,081437.000,5212.981473,N,00653.102458,E,1,3,2.88,102.907,M,47.093,M,,*5E +$GPRMC,081437.000,A,5212.981473,N,00653.102458,E,0.039,0.00,230808,,,A*52 +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03392,19392,13031,29031,14031,23001,02001,11001,16001,05001,20001,22001,18001,06001,09001,30001,04001,01001,24001,31001,17001,12001,32001*42 +$GPVTG,0.00,T,,M,0.039,N,0.073,K,A*33 +$GPGGA,081438.000,5212.982641,N,00653.105897,E,1,3,2.88,102.912,M,47.093,M,,*5D +$GPRMC,081438.000,A,5212.982641,N,00653.105897,E,0.042,0.00,230808,,,A*59 +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03392,19392,13342,29031,14342,23001,02001,11001,16001,05001,20001,22001,18001,06001,09001,30001,04001,01001,24001,31001,17001,12001,32001*42 +$GPVTG,0.00,T,,M,0.042,N,0.079,K,A*35 +$GPGGA,081439.000,5212.981832,N,00653.104686,E,1,3,2.88,102.930,M,47.093,M,,*5A +$GPGSA,A,2,21,28,08,,,,,,,,,,3.05,2.88,1.00*07 +$GPGSV,3,1,11,08,63,065,50,28,42,144,52,21,13,320,42,26,,,48*44 +$GPGSV,3,2,11,25,,,45,07,,,44,27,,,48,10,,,44*71 +$GPGSV,3,3,11,15,,,45,03,,,39,19,,,39*77 +$GPRMC,081439.000,A,5212.981832,N,00653.104686,E,0.205,0.00,230808,,,A*5F +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03392,19392,02031,29342,23031,14001,11001,16001,05001,20001,22001,18001,06001,09001,13001,30001,04001,01001,24001,31001,17001,12001,32001*45 +$GPVTG,0.00,T,,M,0.205,N,0.379,K,A*37 diff --git a/test/daemon/mkt-3301.log.chk b/test/daemon/mkt-3301.log.chk new file mode 100644 index 0000000..5205f7a --- /dev/null +++ b/test/daemon/mkt-3301.log.chk @@ -0,0 +1,67 @@ +$PMTK010,001*2E +$POLYN,TIME,RESTART_OCCURRED +$POLYN,EPH,0,00000000 +$POLYN,ALM,0,00000000 +$GPGGA,235946.005,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*49 +$GPRMC,235946.005,V,8960.000000,N,00000.000000,E,0.000,0.00,050180,,,N*47 +$PMTKCHN,14001,29001,23001,02001,21001,11001,16001,28001,05001,20001,22001,18001,06001,19001,07001,09001,25001,08001,13001,30001,10001,03001,04001,27001,26001,01001,24001,15001,31001,17001,12001,32001*46 +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,235947.004,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*49 +$GPRMC,235947.004,V,8960.000000,N,00000.000000,E,0.000,0.00,050180,,,N*47 +$PMTKCHN,21312,02001,14001,29001,23001,16001,05001,20001,22001,18001,06001,19001,28031,11282,07001,09001,25001,08001,13001,30001,10001,03001,04001,27001,26001,01001,24001,15001,31001,17001,12001,32001*4D +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,235948.004,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*46 +$GPRMC,235948.004,V,8960.000000,N,00000.000000,E,0.000,0.00,050180,,,N*48 +$PMTKCHN,21412,28492,22001,14001,29001,23001,02001,11001,16001,05001,20001,06031,19001,18031,07001,09001,25001,08001,13001,30001,10001,03001,04001,27001,26001,01001,24001,15001,31001,17001,12001,32001*4E +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,235949.004,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*47 +$GPRMC,235949.004,V,8960.000000,N,00000.000000,E,0.000,0.00,050180,,,N*49 +$PMTKCHN,21422,28502,22242,09282,07432,14001,29001,23001,02001,11001,16001,13031,25031,08031,05001,20001,18001,06001,19001,30001,10001,03001,04001,27001,26001,01001,24001,15001,31001,17001,12001,32001*4E +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,235950.004,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*4F +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,2,1,06,21,,,40,28,,,47,25,,,43,07,,,40*71 +$GPGSV,2,2,06,08,,,49,10,,,41*7E +$GPRMC,235950.004,V,8960.000000,N,00000.000000,E,0.000,0.00,050180,,,N*41 +$PMTKCHN,21402,28472,14001,25432,07402,08492,29001,10412,23001,02001,11001,03031,04031,27031,16001,05001,20001,22001,18001,06001,19001,09001,13001,30001,26001,01001,24001,15001,31001,17001,12001,32001*49 +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,081433.591,8960.000000,N,00000.000000,E,0,0,,137.000,M,13.000,M,,*43 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,21,,,42,28,,,52,26,,,48,25,,,45*7E +$GPGSV,3,2,12,07,,,44,08,,,50,27,,,48,10,,,44*79 +$GPGSV,3,3,12,15,,,45,03,,,38,19,,,39,05,,,25*77 +$GPRMC,081433.591,V,8960.000000,N,00000.000000,E,0.000,0.00,120180,,,N*4B +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03382,19392,05252,16342,22031,14001,29001,23001,02001,11001,20001,18001,06001,09001,13001,30001,04001,01001,24001,31001,17001,12001,32001*43 +$GPVTG,0.00,T,,M,0.000,N,0.000,K,N*32 +$GPGGA,081434.590,5212.978993,N,00653.097906,E,0,3,,102.907,M,47.093,M,,*42 +$GPRMC,081434.590,V,5212.978993,N,00653.097906,E,0.052,0.00,230808,,,N*46 +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03392,19392,18031,06031,22252,14001,29001,23001,02001,11001,16001,05001,20001,09001,13001,30001,04001,01001,24001,31001,17001,12001,32001*45 +$GPVTG,0.00,T,,M,0.052,N,0.097,K,N*3B +$GPGGA,081436.000,5212.982135,N,00653.101394,E,1,3,2.88,102.907,M,47.093,M,,*5F +{"class":"TPV","tag":"GGA","lat":52.216368917,"lon":6.885023233,"alt":102.907,"mode":3} +$GPRMC,081436.000,A,5212.982135,N,00653.101394,E,0.039,0.00,230808,,,A*53 +{"class":"TPV","tag":"RMC","time":1219479276.000,"ept":0.005,"lat":52.216368917,"lon":6.885023233,"alt":102.907,"track":0.0000,"speed":0.020,"mode":3} +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03392,19392,13031,06031,09272,14001,29001,23001,02001,11001,16001,05001,20001,22001,18001,30001,04001,01001,24001,31001,17001,12001,32001*47 +$GPVTG,0.00,T,,M,0.039,N,0.072,K,A*32 +$GPGGA,081437.000,5212.981473,N,00653.102458,E,1,3,2.88,102.907,M,47.093,M,,*5E +$GPRMC,081437.000,A,5212.981473,N,00653.102458,E,0.039,0.00,230808,,,A*52 +{"class":"TPV","tag":"RMC","time":1219479277.000,"ept":0.005,"lat":52.216357883,"lon":6.885040967,"alt":102.907,"track":0.0000,"speed":0.020,"climb":0.000,"mode":3} +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03392,19392,13031,29031,14031,23001,02001,11001,16001,05001,20001,22001,18001,06001,09001,30001,04001,01001,24001,31001,17001,12001,32001*42 +$GPVTG,0.00,T,,M,0.039,N,0.073,K,A*33 +$GPGGA,081438.000,5212.982641,N,00653.105897,E,1,3,2.88,102.912,M,47.093,M,,*5D +$GPRMC,081438.000,A,5212.982641,N,00653.105897,E,0.042,0.00,230808,,,A*59 +{"class":"TPV","tag":"RMC","time":1219479278.000,"ept":0.005,"lat":52.216377350,"lon":6.885098283,"alt":102.912,"track":0.0000,"speed":0.022,"climb":0.005,"mode":3} +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03392,19392,13342,29031,14342,23001,02001,11001,16001,05001,20001,22001,18001,06001,09001,30001,04001,01001,24001,31001,17001,12001,32001*42 +$GPVTG,0.00,T,,M,0.042,N,0.079,K,A*35 +$GPGGA,081439.000,5212.981832,N,00653.104686,E,1,3,2.88,102.930,M,47.093,M,,*5A +$GPGSA,A,2,21,28,08,,,,,,,,,,3.05,2.88,1.00*07 +$GPGSV,3,1,11,08,63,065,50,28,42,144,52,21,13,320,42,26,,,48*44 +$GPGSV,3,2,11,25,,,45,07,,,44,27,,,48,10,,,44*71 +$GPGSV,3,3,11,15,,,45,03,,,39,19,,,39*77 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":8,"el":63,"az":65,"ss":50,"used":true},{"PRN":28,"el":42,"az":144,"ss":52,"used":true},{"PRN":21,"el":13,"az":320,"ss":42,"used":true},{"PRN":26,"el":0,"az":0,"ss":48,"used":false},{"PRN":25,"el":0,"az":0,"ss":45,"used":false},{"PRN":7,"el":0,"az":0,"ss":44,"used":false},{"PRN":27,"el":0,"az":0,"ss":48,"used":false},{"PRN":10,"el":0,"az":0,"ss":44,"used":false},{"PRN":15,"el":0,"az":0,"ss":45,"used":false},{"PRN":3,"el":0,"az":0,"ss":39,"used":false},{"PRN":19,"el":0,"az":0,"ss":39,"used":false}]} +$GPRMC,081439.000,A,5212.981832,N,00653.104686,E,0.205,0.00,230808,,,A*5F +{"class":"TPV","tag":"RMC","time":1219479279.000,"ept":0.005,"lat":52.216363867,"lon":6.885078100,"alt":102.930,"epv":23.000,"track":0.0000,"speed":0.105,"climb":0.018,"mode":3} +$PMTKCHN,21422,28522,26482,25452,07442,08502,27482,10442,15452,03392,19392,02031,29342,23031,14001,11001,16001,05001,20001,22001,18001,06001,09001,13001,30001,04001,01001,24001,31001,17001,12001,32001*45 +$GPVTG,0.00,T,,M,0.205,N,0.379,K,A*37 diff --git a/test/daemon/motorola-t805.log b/test/daemon/motorola-t805.log new file mode 100644 index 0000000..8300f49 --- /dev/null +++ b/test/daemon/motorola-t805.log @@ -0,0 +1,65 @@ +# Name: Motorola T805 +# Chipset: SiRF III f +# Pause-noted: Y +# Well-behaved: Y +# Submitted-by: "Olivier Lahaye"=20 +# Date: 18 Dec 2007 +# Location: Nozay, 48.66564N2.24812E +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# Lines up to but not including the first GPGLL are +# `cat /dev/ttyACM0` at startup=20 +# Following lines are +# `cat /dev/ttyACM0` stationary +$GPGGA,212607.891,,,,,0,00,,,M,0.0,M,,0000*56 +$GPRMC,212607.891,V,,,,,,,181207,0,N*5C +$GPGGA,212608.879,,,,,0,00,,,M,0.0,M,,0000*5F +$GPRMC,212608.879,V,,,,,,,181207,0,N*55 +$GPGGA,212609.879,,,,,0,00,,,M,0.0,M,,0000*5E +$GPRMC,212609.879,V,,,,,,,181207,0,N*54 +$GPGGA,212610.879,,,,,0,00,,,M,0.0,M,,0000*56 +$GPRMC,212610.879,V,,,,,,,181207,0,N*5C +$GPGGA,212611.879,,,,,0,00,,,M,0.0,M,,0000*57 +$GPRMC,212611.879,V,,,,,,,181207,0,N*5D +$GPGGA,212612.879,,,,,0,00,,,M,0.0,M,,0000*54 +$GPRMC,212612.879,V,,,,,,,181207,0,N*5E +$GPGGA,212613.879,,,,,0,00,,,M,0.0,M,,0000*55 +$GPRMC,212613.879,V,,,,,,,181207,0,N*5F +$GPGGA,212614.879,4839.9488,N,00214.8863,E,1,04,2.2,133.1,M,47.3,M,,0000*55 +$GPRMC,212614.879,A,4839.9488,N,00214.8863,E,0.56,344.41,181207,0,A*77 +$GPGGA,212615.879,4839.9396,N,00214.8909,E,1,04,2.2,140.3,M,47.3,M,,0000*57 +$GPRMC,212615.879,A,4839.9396,N,00214.8909,E,0.78,237.93,181207,0,A*75 +$GPGGA,212617.000,4839.9404,N,00214.9022,E,1,04,2.2,158.4,M,47.3,M,,0000*50 +$GPRMC,212617.000,A,4839.9404,N,00214.9022,E,1.25,21.04,181207,0,A*4E +$GPGGA,212618.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*5F +$GPRMC,212618.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*69 +$GPGGA,212619.000,,,,,0,00,50.0,,M,0.0,M,,0000*42 +$GPRMC,212619.000,V,,,,,,,181207,0,N*53 +$GPGGA,212620.000,,,,,0,00,50.0,,M,0.0,M,,0000*48 +$GPRMC,212620.000,V,,,,,,,181207,0,N*59 +$GPGGA,212621.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*55 +$GPRMC,212621.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*63 +$GPGGA,212622.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*56 +$GPRMC,212622.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*60 +$GPGGA,212623.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*57 +$GPRMC,212623.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*61 +$GPGGA,212624.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*50 +$GPRMC,212624.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*66 +$GPGGA,212625.000,4839.9411,N,00214.9065,E,1,03,3.1,168.0,M,47.3,M,,0000*54 +$GPRMC,212625.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*67 +$GPGGA,212626.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*52 +$GPRMC,212626.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*64 +$GPGGA,212627.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*53 +$GPRMC,212627.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*65 +$GPGGA,212628.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*5C +$GPRMC,212628.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*6A +$GPGGA,212629.000,4839.9411,N,00214.9065,E,1,03,3.1,168.0,M,47.3,M,,0000*58 +$GPRMC,212629.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*6B +$GPGGA,212630.000,4839.9411,N,00214.9065,E,1,03,3.1,168.0,M,47.3,M,,0000*50 +$GPRMC,212630.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*63 +$GPGGA,212631.000,4839.9411,N,00214.9065,E,1,03,3.1,168.0,M,47.3,M,,0000*51 +$GPRMC,212631.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*62 +$GPGGA,212632.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*57 +$GPRMC,212632.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*61 diff --git a/test/daemon/motorola-t805.log.chk b/test/daemon/motorola-t805.log.chk new file mode 100644 index 0000000..e225e49 --- /dev/null +++ b/test/daemon/motorola-t805.log.chk @@ -0,0 +1,67 @@ +$GPGGA,212607.891,,,,,0,00,,,M,0.0,M,,0000*56 +$GPRMC,212607.891,V,,,,,,,181207,0,N*5C +$GPGGA,212608.879,,,,,0,00,,,M,0.0,M,,0000*5F +$GPRMC,212608.879,V,,,,,,,181207,0,N*55 +$GPGGA,212609.879,,,,,0,00,,,M,0.0,M,,0000*5E +$GPRMC,212609.879,V,,,,,,,181207,0,N*54 +$GPGGA,212610.879,,,,,0,00,,,M,0.0,M,,0000*56 +$GPRMC,212610.879,V,,,,,,,181207,0,N*5C +$GPGGA,212611.879,,,,,0,00,,,M,0.0,M,,0000*57 +$GPRMC,212611.879,V,,,,,,,181207,0,N*5D +$GPGGA,212612.879,,,,,0,00,,,M,0.0,M,,0000*54 +$GPRMC,212612.879,V,,,,,,,181207,0,N*5E +$GPGGA,212613.879,,,,,0,00,,,M,0.0,M,,0000*55 +$GPRMC,212613.879,V,,,,,,,181207,0,N*5F +$GPGGA,212614.879,4839.9488,N,00214.8863,E,1,04,2.2,133.1,M,47.3,M,,0000*55 +{"class":"TPV","tag":"GGA","lat":48.665813333,"lon":2.248105000,"alt":133.100,"mode":3} +$GPRMC,212614.879,A,4839.9488,N,00214.8863,E,0.56,344.41,181207,0,A*77 +{"class":"TPV","tag":"RMC","time":1198013174.879,"ept":0.005,"lat":48.665813333,"lon":2.248105000,"alt":133.100,"track":344.4100,"speed":0.288,"mode":3} +$GPGGA,212615.879,4839.9396,N,00214.8909,E,1,04,2.2,140.3,M,47.3,M,,0000*57 +$GPRMC,212615.879,A,4839.9396,N,00214.8909,E,0.78,237.93,181207,0,A*75 +{"class":"TPV","tag":"RMC","time":1198013175.879,"ept":0.005,"lat":48.665660000,"lon":2.248181667,"alt":140.300,"track":237.9300,"speed":0.401,"climb":7.200,"mode":3} +$GPGGA,212617.000,4839.9404,N,00214.9022,E,1,04,2.2,158.4,M,47.3,M,,0000*50 +$GPRMC,212617.000,A,4839.9404,N,00214.9022,E,1.25,21.04,181207,0,A*4E +{"class":"TPV","tag":"RMC","time":1198013177.000,"ept":0.005,"lat":48.665673333,"lon":2.248370000,"alt":158.400,"track":21.0400,"speed":0.643,"climb":16.146,"mode":3} +$GPGGA,212618.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*5F +$GPRMC,212618.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*69 +{"class":"TPV","tag":"RMC","time":1198013178.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":9.600,"mode":3} +$GPGGA,212619.000,,,,,0,00,50.0,,M,0.0,M,,0000*42 +$GPRMC,212619.000,V,,,,,,,181207,0,N*53 +$GPGGA,212620.000,,,,,0,00,50.0,,M,0.0,M,,0000*48 +$GPRMC,212620.000,V,,,,,,,181207,0,N*59 +$GPGGA,212621.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*55 +$GPRMC,212621.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*63 +{"class":"TPV","tag":"RMC","time":1198013181.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212622.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*56 +$GPRMC,212622.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*60 +{"class":"TPV","tag":"RMC","time":1198013182.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212623.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*57 +$GPRMC,212623.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*61 +{"class":"TPV","tag":"RMC","time":1198013183.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212624.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*50 +$GPRMC,212624.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*66 +{"class":"TPV","tag":"RMC","time":1198013184.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212625.000,4839.9411,N,00214.9065,E,1,03,3.1,168.0,M,47.3,M,,0000*54 +$GPRMC,212625.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*67 +{"class":"TPV","tag":"RMC","time":1198013185.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212626.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*52 +$GPRMC,212626.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*64 +{"class":"TPV","tag":"RMC","time":1198013186.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212627.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*53 +$GPRMC,212627.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*65 +{"class":"TPV","tag":"RMC","time":1198013187.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212628.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*5C +$GPRMC,212628.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*6A +{"class":"TPV","tag":"RMC","time":1198013188.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212629.000,4839.9411,N,00214.9065,E,1,03,3.1,168.0,M,47.3,M,,0000*58 +$GPRMC,212629.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*6B +{"class":"TPV","tag":"RMC","time":1198013189.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212630.000,4839.9411,N,00214.9065,E,1,03,3.1,168.0,M,47.3,M,,0000*50 +$GPRMC,212630.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*63 +{"class":"TPV","tag":"RMC","time":1198013190.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212631.000,4839.9411,N,00214.9065,E,1,03,3.1,168.0,M,47.3,M,,0000*51 +$GPRMC,212631.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*62 +{"class":"TPV","tag":"RMC","time":1198013191.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,212632.000,4839.9411,N,00214.9065,E,1,04,2.2,168.0,M,47.3,M,,0000*57 +$GPRMC,212632.000,A,4839.9411,N,00214.9065,E,0.00,,181207,0,A*61 +{"class":"TPV","tag":"RMC","time":1198013192.000,"ept":0.005,"lat":48.665685000,"lon":2.248441667,"alt":168.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} diff --git a/test/daemon/navcom.log b/test/daemon/navcom.log new file mode 100644 index 0000000000000000000000000000000000000000..b0b93a58dfa4828db6264407a6e0da95d5ce1fbf GIT binary patch literal 15167 zcmbu`30%zS{{ZmM%v94Y<;anSkX@k~CC3t3mez=zA?c!+?_?Uw%(5tFjv_*iE#E%OeX8~`_F5IJoEI-ci!{)e4fwqT?c_^k~pLXe*G;- zA{Gqv@fCzHlf#%0QwM>UJZM^oKo&;--6ayg;X5Nx943>61a}IQ_YinZk%mPIyhG%& zDItPhK~rah;2%82lftHT4h)e_3zI~44i4#!PwPKPhBLT2J9q2k?9$1_4ZroPBxsT> zOv3aK%wVQ6l9`OD1AceJ6r3 zq>}KEAQ?WZAO1}iA{9ppCPhR{!-YkL;Hq&PJCoN?pRt2P0|j9W`@P_>NSQP&a0dP1 z0;xnI6NE~ng5VGtE<3U_u7bNEbiX$k8}MLF8t?2u=-+pQz}ekd= zO_Kyo9VKw??A+DaQ`I>FI8VyBCW2YBW;u6talw(!-Q9#>+zBFhIGvFZ2tYvp)ZYmp z%5YW@2fsp*0YKyV9QOyJR#D1+kZcig+;;s@H_0@Wg9SLn>mMJ*{bi$wH(EIY$EOA5 z_>T=6wB@(kCeY(|{o|u~gQttCJ}RAXd`Gv@Kigg37%gf_VEhjK;};n8`6%LnauklA z9=!ay$tX%l7aI27BvM%`M?$jYA7+Bboy+@tY?Q@;1XKOv7a4UvFZ%RQ z*%gw_f9Q7Q&{3gF=Y4m3kO_12k6+9mQ7rmgs&vQoWV&bbkG}EwVX}D-vOQA&_$9_Z z!$eIwDgAN$w$hWkB(JWxt{z(n&EDuAztm(M5m~lY`rvr+lK?BXW`i8!_VR&eqJMmh z=}!(K>rCY&9Dg`A=B{;D-r>_7&7qN}{_)Gq+=jXxLZ( z_~qs;mWs@Ml~Zv17|R){7mHR*I8gin{I=;Izrw0tBztYk+Nn|%h*%#-Zeyr-`o|o4XdI|xWoYX%)7Iy1@w9`L6&dM%NWU*B_4cFt{ zph@?~?fu@QEw+T-OZ1Ol)v%Gh$jnGN1lRLtck!kKHz+G%tXFx5$q%8~T>azYZCV}>nQT)I#_^n#bGX`m-lgVTW8cHHHo^^^afIwEeH5hUb*7xPHfDKm8o`$D-wrU)g|Bh5qsD zZ3mQyO!g`RA-RP`C|~p#uT^k=6KET&e>}HY_XgS>Qr4U+5pt zYre`!07SWl*rlJV+_V@pcVnnr~xfUsv?yfJtxtOyNT?M()ek<;#kX&NALXq3R(99 ztn06Tym2d0PZ77D(htX9wrFbZ-t5u+y}3N#sq~LGu@^ds%wABR=7)-N3eO$#?Z59& z0$r!-A8%UU=Os!1cxw-172$SNDh&yFPYC%Uin8?PTkhT^*FU~lpAGbpxWQx>`-crl z^8gb>GrxM~QFUhicNDIfB=?BeISL|r*q!Ee zTMCN}MNa=(m?c~G|It2mHuQ48esB;ZwQsb-r`4FFFCLB~+qt7&e=KQUGqY*+%;9xs z4yRYc&^+EW+$9Cj| z<-*kS(9rS6FiFcD7YliJ$u3JD%RwcJYi72po;i;b5XaGa2VdmTHMgT1`kcPi#!z!Kw!B66b=WW1m3RmQNqM{XLrOzMI$Zeo1A`%+}R2ujK~B zakXZCzLw4m508FYYnI|Xdf{=a<))6jf92QsM#&Z*QtVS_fJxlg%rT^}{flGXj!p^V z4j&^s%Ga7El=#-n+_-w?j5=4NEQ8K$YWyiW!z9!-=)~BbZ}>SzO}gH*-kNOT<87b% z2l*!?U}6+WXg?x0-S%~i!S)qo_t=d0OH0_w0M#|Ap1B<-U=_!t*7KcqbY`2zy$825 zJLNj{myFF^(~;b$zH5wTCR@xNNNqUA?Y!YlHnq>6XyO>2W$0c&w*A%4G^vD*={U1( z^~{600js!LGb;zvne9vr6@!h-JAFv7UslY|FpwOWWAib&MN}nTXRrxva>fgM9JxLX zZRZy$g{5S#aPX_`C1+}`MziXfCES2`ZnN4ozm?$3{}Grw@*F=lljZUIhm#%cB&NcWmNhfCs-AgbovZPBB72>=?*k^1 zeeQQ;9m5OBPJ@!v&sGhSEq>UG*BLrlw7>K_+0}k&=+hRF?)FAE$gUqITJoXi!Df9V^b?ISY7>?YdjqK0dc? zU=OmhL}2=+WFDQlHZ~pHi{-MXpFjWSOYhzu-|{rH@*25Mtih{2Arlf5Jy zydy}$CIiJRdFy{UJOC~iT*lFr9~xD&-r#xGljIR2E!G{MXt-K+;8#L?t&AZ=5UP8v?vqT z_zc7SmOfx=YSIWAlld7S>HrrYlYzhNNtA%&_!ROXjRB4ki55fK-f#)_1_LxB3nbjO z@8BZrWx%-=SvZl?d;#RbdIm;Wkwtl&4t+T{VHX2V)@1QouKjX24VxI~$|Flcz_cYN z4VDChGoQqaf{q?gNau8FlDE7a$6_BGfJOMcXt01UxLzI?zqri8^|ODYFTsOHSI>&* z;P21(L=krUve3v=B$qS+hbAauSJ)|r8%1uD)(~_ZMUfEfHv-Rzws&?^_}!X+&5B`ty6C z2wsD-P~HuU2|oa@F^UMke2S4SCD$-U6r4p79Za@KqMXSAk`0kpQN;EpuO-|N93KTK zW+=k(w@oq|Q}TvXK;#k>vGs|F@%o3HB_D`a35v*ZFO@!Vf!(AX*eya4i{KAM%t*47 ze1--*DEr)L=}PgHIV6RMVO$uE5!N&1^UKsClo}Cqy=oEbF-8bft5C#rO^ozDh&P2bBHGo&h(0t%c&_AEi%?v5_Drmd?{W`Cn1ew*G2%6k#t620W@E%Z zwIV!qVnn5ui0_UO>;6A6B3B(FKs!dz&{ii#EYyhj7~;?OKoM0<%0h!qk{#qNsdPaR z9lK;RX}^(^#2hLMQN%zW6fuz8BZUx6MRXbUTJl7UF=7Lx1Bw`Ew^^3{UR6vUK=e`+ zp=c{&;w#7v{M<$tqlmP*CDN?};1c;2#4}OE`N4A(roWIVat{6!poo=6SBjNW$tDs4 z$0wnP^__l`_kB-AV2pEVq!B^as}@1CMyx6ZMTBcaVB*jfQAkDHM-gxIi74(!XJ+5W z7q#!Bm->CY2$}eK)p{R;!BrjW^JsMcQ7hJe_a}Sfe|@rR-p7Lg+MjIQ_Yq$xczA!y zbN1F7&YnpPR$Tjpo?W3!J)S#G%S6wAYD5%;`SXP+fAUZaS!9ZIDA{7}S1_-Pi3==^TBB1TALWIYV+iXw^!#)|hXB8SN$$QzF$ zTzAcoH?-r{h-jk`LDx$~C~E2mbJcPbF%?D7OT<2OMI4~tdx;{FT=is)D=TZRsk)9} zV?_2o2R24zmtu@qH|fBKz~#fUN5hDEu4$W%G)4@hGqJW_*4oO}vgHSpv~2m+W(~9z zterLX`srj1Kb@@Mr=2wt{dBU%*L6g#EqtCPYv{3+rV(*L?9cClBGxV{3l&}_Nu(|K z(yTFQ#A&8tIeAFjKzI>F?CHH-;_6Ipk_?Fa8%6YWdn3u0kgH@rq`y_EN4P#hX=wfGO{{r81VxN%Y(4&KcdY|jfjKO{rMeHgwx8h(CD*d1F-=wI}~yJ$Y~}p4&Tq=;6?Wu z3m0yeq;?y~Ae` zUw|S8XFic`{RJ}c9T!i-7?Hc=cf~&w$whJ%t~sHIx7%XH6J}!N>IG&CQAEL`Ncnsl zwTLEky{rhjUbP5XM@UsmQA8MuzzPEGV;QX*Ba)~HHxwb%C&DbfjtEa$M>*8ZjpZtr(uY6_V=_akS(#ig-w8VnvkKib&Fm5eyhaQc%{8PKvSU zE#jy~1YNIM1g#@}S1myiQ#3Kcu&#(4DkA$N7v8(*$r>Ln*AdZITLd`a?(<|yk5ea5 z#ChE9>ECM{lb%5lVvUH``b7joik1kS7=Z@9D@GK+E}gx`e^w+lA`XFpc8s8xq_(nT zML5ybv%AlEa({js6wymr7V3MBY{NaAZzmMN+{jBXFBivWViIua-RunTX6h)Y>nl5ksiS9M1h*XUTx?XJ&7gX^mBC=Wp zYX7Q3^`5@q3t3!n(ILp1$}9N3^$M-;&B|1n1B)DiTO)Df{)Bf@9CKfgJO zNHs$d=SV8~NPLATV%VR#O#Wu_iFiN(%^F+C4vA|JaR36*v_qAA{jDTt3Fd@IC~!p) z6;rp$cx9?`+mj^(vC)JHcTx0DhW+BA#2y6){tBH#>xL zEgwbf%8nCf%_18ytLzzzBL3PFA#cd`EUAcI8WD88Y7w-K7@%5*B4$=+4fLa|+mFEQ zFW%6ABINo+loxzUME07C&Yl*V$l6gT!W?%qx>-XlqC;wiry0mJA}aKYU|^G$2%S2j z&R#>Oj=)+$)3ZboIx#}Gj;Oz9c?g#MM~rx)5#h1WpWhfoe33p2jnBdu@r(p{poqvx zXPB+4$qUj7d>^5RHrsbfhL0eYa1U&5p@=P#3d!olC?W=I1Sn##G(~3fMup8LV0)If zK7*LbhvWpgLsBYG#G;Z%(zG_Pl?Y*i1VscKou$Z}h+cl-#9l!WZbMgz#j~*=A%+%H zP=vI7gnX3+ts|(22O1G{z1ku&RI5>hwEjBc9u-lDBD(4m!Bc0A#yVLe!II4yMXxV8 zd!E}Elqy9LF4())FJivYVH8oO5m8wyLOW|Q&knlh+NvmE|2?#3A#rzFl$7=LJtF%C}PZAK{%WtmR+jTo#5iX?m1WhBbY?u)&?_Rl`(G!~uuCuC^Blolr#2lc_R?GSz3?J2=qF^3aWeO#BtB3;rVUI9*{=*+Z#oFx)4b zV2%%p5D%WIPTD3N0SBafbRIgexHj|mlFfH8u-e}mn9()Cgi z>JHTeRS1gs8AV`CjCBNl)vYX-(~rRP6I{67MURNj%WFjF)Dh~+GP?=xKD+X!cKQoN z%!ZkDM5xa-&dfc8B1$wO-sus6Ctbn7tBn!g-;dC(Bfb?Q@HDILxkjxB?HHj)L~UjH zCeEL4j3P42p3$?OAw5(Fn z#t%gV(Ef$0RCs2aO!!%41m)oM2Z|Uk9moj3;JHX4u`vUzBU(O`t{w^J$wIIjjUu8e ze^X?3Bg;ukPM_;2;!yY1VxbwsG^h!eRqMzAxn{fPIq zBD5<@23}~1`0hGFH%4ghH85*v?KRS2{{I#uFsyVKP!Vj^#>NP`UhNp+tqMmGgR5f%1_*q0x+3;d z5yw!3QD;3d;(hS9M0on5h`54?CKFM_c{o~+2oaao5e}Ld@j)%ZxT&^?Z|pVjgyetd zM_|^_>RG1K>hXVx5v&OIt}<3c_IiIlpopTXXQ9!L@Z7=~(wn1*k-N?@Pgdf&7gm<{ zQABpoZi%aa{EesK!gDC1m2s7%O(+VQ4e3@WVswKYvPvsF7i-FijzAF;Dt~683-B!S zF5x{#5kvOem!=KF7!d(OXdQ82!3;%@9%LQvRwpYlMmVfpEw-3PRucv62|y8BOs2^> z57b#>0lnI+2)f>Yn)@T@UZX;_7)4A*5%@qqG)A;+YSy>`ujc*;_B4FSF)qC9u1AD< z>lzX2I-(zY_W9JLy0YwoS>x$~=JvrT;_Le()LEms7tI=Wbf%1ccz*<4V|RCtD}B7q z^|9S@xOv%tvwfmgm|U>El+{N{5)PKXboca_YP98S!I?fsHnth|#Q0Pnvk7}UZ(Ml0 z58FFrBhANJSABH48kck;%@(bbw_uo{b@HZDjU?#oSac(e_KqbTqQ8zbnm$*I_Krn2 z_pq*_=rv$n?cC(g|Cd%Hd|`+RY3aIRPe&$S;KG`p^|-nn{w-Gl96TNA<$lI73|(1s8r0L(*b=)R zU9tTUR>Y@T5uREig27!&gwBrTTahL~r>mh`jcA{a9ESN{N19p@^;aXTi1Qi|aY_FC z4=AEb;PcSPEo2obCGl-g#D~1|OwJtaI`E*f7)3l4?UAfD#M6#cNXbDF8%nAq*525= z4ueQ~CstzSPMOV3RW?SBf+;BCc0qr};WO@GKam33=WW#}^|_;tZK$ zcXzzAYXR7P#7Gn56EEHug?|@A-ZT`^esj2d(rdMdR&>3r2)bTv5kaaMC}L!FHG;VZ z_bm-|B26j{L7)ES0%w>W5!u6PM5yaiHqr=c_ORJDcq(l*f6OKYiZBQBdU8+d;=L$h z1f7W$@wrxn_8yjj`L!a_zq=Y)`<*cYMSO3JzykxV9SbYMN+V)csz1LHMU0;EJXCmu zB;y%qaZ41z>vVxx9YN0EX+^;S6w!7Kiuj^hL$GamA4T}Jc_-;No#bGyz+9y&&6&7M zR`5i1o^;?;_C^uqHvO5DGVFYsV4n;{_&>fY%^w3NF<0#iKoOZ)k%~*bupW+u+iy|C zl{xWZyD+R*gWv_tJ#&tP$xmC+YQzw$5g&~Rx?XJ&Le*RpF|j)Lpa^_K1Y4cnv}k zfBSkdc+>1o{Ln_5=Ag50;2T?~jvR-+DB@LRKPK{T?1kr$ zbR~+2zII3IDuI7+$1;K5n`gLRs`%WPD6q?6Oz+=y^H?JmM`K@XJ-qNn5pIK~$ltbB ziKNf{*FPM5;%`CAO;6>T|Ioibl3(W5m4C zx12o}e)*yIO%yR3!s-!Wvv?=Qh_RX&p{x~Aq*F(H(Gu}L)e*We;*?H|$e{P=*4?q_ zuOsw`$k&K)KIqSXiXtxGeICk7!Cv$S!m~vYiw<05@|R#QycgJHqlh-SdnFYuFoq;R zF713C?D<~8m0;&{GE_QZjCi$wkIeU(Du;Z6g2^Z%PS}s(-N!Tfo5ZFHMGS3nM;a)_ z!;7i#U_OdC_HMc&Q-F73?Sp5zD8fBtjrhuRJVA{F?{O%?J8-g`(?TtR&CzU(pzEa~ M)OU10pm$>ZAFrl|`~Uy| literal 0 HcmV?d00001 diff --git a/test/daemon/navcom.log.chk b/test/daemon/navcom.log.chk new file mode 100644 index 0000000..6f7172e --- /dev/null +++ b/test/daemon/navcom.log.chk @@ -0,0 +1,197 @@ +$GPGGA,102009,3020.5010,N,01213.7241,E,2,09,1.00,627.59,M,31.479,M,,*40 +$GPRMC,102009,A,3020.5010,N,01213.7241,E,0.0019,90.000,150107,,*10 +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102009,0.22,M,0.22,M,10.35,M*03 +{"class":"TPV","tag":"0xb1","time":1168856409.000,"ept":3.920,"lat":30.341683155,"lon":12.228735775,"alt":627.588,"epx":0.222,"epy":0.222,"epv":10.350,"track":90.0000,"speed":0.001,"climb":0.006,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,34*7F +$GPGSV,3,3,10,07,43,056,43,22,13,173,34*7C +{"class":"SKY","tag":"0x86","time":1168732908.624,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":34,"used":false}]} +$GPGGA,102010,3020.5010,N,01213.7241,E,2,09,1.00,627.58,M,31.479,M,,*49 +$GPRMC,102010,A,3020.5010,N,01213.7241,E,31847.9464,0.000,150107,,*2F +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102010,0.22,M,0.22,M,10.35,M*0B +{"class":"TPV","tag":"0xb1","time":1168856410.000,"ept":3.920,"lat":30.341683205,"lon":12.228735818,"alt":627.577,"epx":0.222,"epy":0.222,"epv":10.350,"track":0.0000,"speed":16383.999,"climb":0.008,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,34*7F +$GPGSV,3,3,10,07,43,056,43,22,13,173,32*7A +{"class":"SKY","tag":"0x86","time":1168732908.625,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":32,"used":false}]} +$GPGGA,102011,3020.5010,N,01213.7242,E,2,09,1.00,627.56,M,31.479,M,,*45 +$GPRMC,102011,A,3020.5010,N,01213.7242,E,0.0019,90.000,150107,,*1A +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102011,0.22,M,0.22,M,10.35,M*0A +{"class":"TPV","tag":"0xb1","time":1168856411.000,"ept":3.920,"lat":30.341683095,"lon":12.228735894,"alt":627.558,"epx":0.222,"epy":0.222,"epv":10.350,"track":90.0000,"speed":0.001,"climb":16383.996,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,34*7F +$GPGSV,3,3,10,07,43,056,43,22,13,173,44*7B +{"class":"SKY","tag":"0x86","time":1168732908.626,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":44,"used":false}]} +$GPGGA,102012,3020.5010,N,01213.7242,E,2,09,1.00,627.55,M,31.479,M,,*45 +$GPRMC,102012,A,3020.5010,N,01213.7242,E,0.0019,90.000,150107,,*19 +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102012,0.22,M,0.22,M,10.35,M*09 +{"class":"TPV","tag":"0xb1","time":1168856412.000,"ept":3.920,"lat":30.341683146,"lon":12.228735886,"alt":627.552,"epx":0.222,"epy":0.222,"epv":10.350,"track":90.0000,"speed":0.001,"climb":0.001,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,34*7F +$GPGSV,3,3,10,07,43,056,43,22,13,173,44*7B +{"class":"SKY","tag":"0x86","time":1168732908.627,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":44,"used":false}]} +$GPGGA,102013,3020.5010,N,01213.7242,E,2,09,1.00,627.55,M,31.480,M,,*42 +$GPRMC,102013,A,3020.5010,N,01213.7242,E,0.0019,0.000,150107,,*21 +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +{"class":"TPV","tag":"0xb1","time":1168856413.000,"ept":3.920,"lat":30.341683214,"lon":12.228735860,"alt":627.552,"epx":0.222,"epy":0.222,"epv":10.350,"track":0.0000,"speed":0.001,"climb":0.000,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,38,03,10,284,34*7E +$GPGSV,3,3,10,07,43,056,43,22,13,173,44*7B +{"class":"SKY","tag":"0x86","time":1168732908.628,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":38,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":44,"used":false}]} +$GPGGA,102014,3020.5010,N,01213.7242,E,2,09,1.00,627.54,M,31.479,M,,*42 +$GPRMC,102014,A,3020.5010,N,01213.7242,E,0.0019,0.000,150107,,*26 +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102014,0.22,M,0.22,M,10.35,M*0F +{"class":"TPV","tag":"0xb1","time":1168856414.000,"ept":3.920,"lat":30.341683205,"lon":12.228735860,"alt":627.538,"epx":0.222,"epy":0.222,"epv":10.350,"track":0.0000,"speed":0.001,"climb":0.001,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,38,03,10,284,34*7E +$GPGSV,3,3,10,07,43,056,43,22,13,173,35*7D +{"class":"SKY","tag":"0x86","time":1168732908.629,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":38,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":35,"used":false}]} +$GPGGA,102015,3020.5010,N,01213.7242,E,2,09,1.00,627.55,M,31.479,M,,*42 +$GPRMC,102015,A,3020.5010,N,01213.7242,E,31847.9407,0.000,150107,,*2C +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102015,0.22,M,0.22,M,10.35,M*0E +{"class":"TPV","tag":"0xb1","time":1168856415.000,"ept":3.920,"lat":30.341683138,"lon":12.228735911,"alt":627.551,"epx":0.222,"epy":0.222,"epv":10.350,"track":0.0000,"speed":16383.996,"climb":0.002,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,38,03,10,284,34*7E +$GPGSV,3,3,10,07,43,056,43,22,13,173,35*7D +{"class":"SKY","tag":"0x86","time":1168732908.630,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":38,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":35,"used":false}]} +$GPGGA,102016,3020.5010,N,01213.7242,E,2,09,1.00,627.55,M,31.479,M,,*41 +$GPRMC,102016,A,3020.5010,N,01213.7242,E,0.0019,0.000,150107,,*24 +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102016,0.22,M,0.22,M,10.35,M*0D +{"class":"TPV","tag":"0xb1","time":1168856416.000,"ept":3.920,"lat":30.341683138,"lon":12.228735852,"alt":627.550,"epx":0.222,"epy":0.222,"epv":10.350,"track":0.0000,"speed":0.001,"climb":0.005,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,34*7F +$GPGSV,3,3,10,07,43,056,43,22,13,173,01*7A +{"class":"SKY","tag":"0x86","time":1168732908.631,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":1,"used":false}]} +$GPGGA,102017,3020.5010,N,01213.7242,E,2,09,1.00,627.56,M,31.479,M,,*43 +$GPRMC,102017,A,3020.5010,N,01213.7242,E,0.0000,0.000,150107,,*2D +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102017,0.22,M,0.22,M,10.35,M*0C +{"class":"TPV","tag":"0xb1","time":1168856417.000,"ept":3.920,"lat":30.341683189,"lon":12.228735877,"alt":627.561,"epx":0.222,"epy":0.222,"epv":10.350,"track":0.0000,"speed":0.000,"climb":0.000,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,34*7F +$GPGSV,3,3,10,07,43,056,43,22,13,173,33*7B +{"class":"SKY","tag":"0x86","time":1168732908.632,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":33,"used":false}]} +$GPGGA,102018,3020.5010,N,01213.7241,E,2,09,1.00,627.56,M,31.479,M,,*4F +$GPRMC,102018,A,3020.5010,N,01213.7241,E,0.0019,90.000,150107,,*10 +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102018,0.22,M,0.22,M,10.35,M*03 +{"class":"TPV","tag":"0xb1","time":1168856418.000,"ept":3.920,"lat":30.341683180,"lon":12.228735826,"alt":627.560,"epx":0.222,"epy":0.222,"epv":10.350,"track":90.0000,"speed":0.001,"climb":0.006,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,34*7F +$GPGSV,3,3,10,07,43,056,43,22,13,173,35*7D +{"class":"SKY","tag":"0x86","time":1168732908.633,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":35,"used":false}]} +$GPGGA,102019,3020.5010,N,01213.7242,E,2,09,1.00,627.56,M,31.479,M,,*4D +$GPRMC,102019,A,3020.5010,N,01213.7242,E,0.0060,71.565,150107,,*15 +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102019,0.22,M,0.22,M,10.35,M*02 +{"class":"TPV","tag":"0xb1","time":1168856419.000,"ept":3.920,"lat":30.341683112,"lon":12.228735945,"alt":627.564,"epx":0.222,"epy":0.222,"epv":10.350,"track":71.5651,"speed":0.003,"climb":16383.997,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,38,03,10,284,34*7E +$GPGSV,3,3,10,07,43,056,43,22,13,173,35*7D +{"class":"SKY","tag":"0x86","time":1168732908.634,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":38,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":35,"used":false}]} +$GPGGA,102020,3020.5010,N,01213.7242,E,2,09,1.00,627.56,M,31.479,M,,*47 +$GPRMC,102020,A,3020.5010,N,01213.7242,E,0.0019,0.000,150107,,*21 +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102020,0.22,M,0.22,M,10.35,M*08 +{"class":"TPV","tag":"0xb1","time":1168856420.000,"ept":3.920,"lat":30.341683172,"lon":12.228735936,"alt":627.559,"epx":0.222,"epy":0.222,"epv":10.350,"track":0.0000,"speed":0.001,"climb":0.005,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,45,06,36,062,43,25,36,245,43*7E +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,34*7F +$GPGSV,3,3,10,07,43,056,43,22,13,173,35*7D +{"class":"SKY","tag":"0x86","time":1168732908.635,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":45,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":35,"used":false}]} +$GPGGA,102021,3020.5010,N,01213.7242,E,2,09,1.00,627.54,M,31.480,M,,*42 +$GPRMC,102021,A,3020.5010,N,01213.7242,E,31847.9445,0.000,150107,,*2D +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102021,0.22,M,0.22,M,10.35,M*09 +{"class":"TPV","tag":"0xb1","time":1168856421.000,"ept":3.920,"lat":30.341683180,"lon":12.228735886,"alt":627.543,"epx":0.222,"epy":0.222,"epv":10.350,"track":0.0000,"speed":16383.998,"climb":0.002,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,34*7F +$GPGSV,3,3,10,07,43,056,43,22,13,173,35*7D +{"class":"SKY","tag":"0x86","time":1168732908.636,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":35,"used":false}]} +$GPGGA,102022,3020.5010,N,01213.7242,E,2,09,1.00,627.52,M,31.479,M,,*41 +$GPRMC,102022,A,3020.5010,N,01213.7242,E,31847.9464,0.000,150107,,*2D +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102022,0.22,M,0.22,M,10.35,M*0A +{"class":"TPV","tag":"0xb1","time":1168856422.000,"ept":3.920,"lat":30.341683256,"lon":12.228735869,"alt":627.515,"epx":0.222,"epy":0.222,"epv":10.350,"track":0.0000,"speed":16383.999,"climb":16383.999,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,34*7F +$GPGSV,3,3,10,07,43,056,43,22,13,173,35*7D +{"class":"SKY","tag":"0x86","time":1168732908.637,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":35,"used":false}]} +$GPGGA,102023,3020.5010,N,01213.7242,E,2,09,1.00,627.54,M,31.479,M,,*46 +$GPRMC,102023,A,3020.5010,N,01213.7242,E,0.0027,45.000,150107,,*1E +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102023,0.22,M,0.22,M,10.35,M*0B +{"class":"TPV","tag":"0xb1","time":1168856423.000,"ept":3.920,"lat":30.341683197,"lon":12.228735835,"alt":627.542,"epx":0.222,"epy":0.222,"epv":10.350,"track":45.0000,"speed":0.001,"climb":0.001,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,32*79 +$GPGSV,3,3,10,07,43,056,43,22,13,173,35*7D +{"class":"SKY","tag":"0x86","time":1168732908.638,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":32,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":35,"used":false}]} +$GPGGA,102024,3020.5010,N,01213.7242,E,2,09,1.00,627.52,M,31.479,M,,*47 +$GPRMC,102024,A,3020.5010,N,01213.7242,E,45039.7977,45.000,150107,,*19 +$GPGSA,A,3,03,06,07,16,18,21,25,30,31,,,,2.0,1.0,1.8*31 +$GPGBS,102024,0.22,M,0.22,M,10.35,M*0C +{"class":"TPV","tag":"0xb1","time":1168856424.000,"ept":3.920,"lat":30.341683248,"lon":12.228735852,"alt":627.520,"epx":0.222,"epy":0.222,"epv":10.350,"track":45.0000,"speed":23170.474,"climb":0.000,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,39,03,10,284,35*7E +$GPGSV,3,3,10,07,43,056,43,22,13,173,35*7D +{"class":"SKY","tag":"0x86","time":1168732908.639,"xdop":0.55,"ydop":0.74,"vdop":1.80,"tdop":1.30,"hdop":1.00,"gdop":2.40,"pdop":2.00,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":false},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":39,"used":true},{"PRN":3,"el":10,"az":284,"ss":35,"used":true},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":35,"used":false}]} +$GPGGA,102025,3020.5010,N,01213.7242,E,2,08,1.10,627.55,M,31.479,M,,*41 +$GPRMC,102025,A,3020.5010,N,01213.7242,E,0.0057,90.000,150107,,*17 +$GPGSA,A,3,06,07,16,18,21,25,30,31,31,,,,2.3,1.1,2.1*38 +$GPGBS,102025,0.22,M,0.22,M,12.08,M*01 +{"class":"TPV","tag":"0xb1","time":1168856425.000,"ept":5.880,"lat":30.341683205,"lon":12.228735911,"alt":627.549,"epx":0.222,"epy":0.222,"epv":12.075,"track":90.0000,"speed":0.003,"climb":0.001,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,38,03,10,284,33*79 +$GPGSV,3,3,10,07,43,056,43,22,13,173,34*7C +{"class":"SKY","tag":"0x86","time":1168732908.640,"xdop":0.55,"ydop":0.74,"vdop":2.10,"tdop":1.50,"hdop":1.10,"gdop":2.80,"pdop":2.30,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":38,"used":true},{"PRN":3,"el":10,"az":284,"ss":33,"used":false},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":34,"used":false}]} +$GPGGA,102026,3020.5010,N,01213.7242,E,2,08,1.10,627.54,M,31.479,M,,*43 +$GPRMC,102026,A,3020.5010,N,01213.7242,E,0.0042,26.565,150107,,*1B +$GPGSA,A,3,06,07,16,18,21,25,30,31,31,,,,2.3,1.1,2.1*38 +$GPGBS,102026,0.22,M,0.22,M,12.08,M*02 +{"class":"TPV","tag":"0xb1","time":1168856426.000,"ept":5.880,"lat":30.341683256,"lon":12.228735936,"alt":627.539,"epx":0.222,"epy":0.222,"epv":12.075,"track":26.5651,"speed":0.002,"climb":0.003,"eps":0.44,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,38,03,10,284,32*78 +$GPGSV,3,3,10,07,43,056,43,22,13,173,34*7C +{"class":"SKY","tag":"0x86","time":1168732908.641,"xdop":0.55,"ydop":0.74,"vdop":2.10,"tdop":1.50,"hdop":1.10,"gdop":2.80,"pdop":2.30,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":38,"used":true},{"PRN":3,"el":10,"az":284,"ss":32,"used":false},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":34,"used":false}]} +$GPGGA,102027,3020.5010,N,01213.7242,E,2,08,1.10,627.53,M,31.479,M,,*45 +$GPRMC,102027,A,3020.5010,N,01213.7242,E,31847.9464,90.000,150107,,*11 +$GPGSA,A,3,06,07,16,18,21,25,30,31,31,,,,2.3,1.1,2.1*38 +$GPGBS,102027,0.24,M,0.24,M,12.08,M*03 +{"class":"TPV","tag":"0xb1","time":1168856427.000,"ept":5.880,"lat":30.341683265,"lon":12.228735920,"alt":627.531,"epx":0.236,"epy":0.236,"epv":12.075,"track":90.0000,"speed":16383.999,"climb":16383.998,"eps":0.46,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,45,06,36,062,43,25,36,245,43*7E +$GPGSV,3,2,10,30,26,132,37,16,40,321,42,18,31,140,38,03,10,284,32*77 +$GPGSV,3,3,10,07,43,056,43,22,13,173,34*7C +{"class":"SKY","tag":"0x86","time":1168732908.642,"xdop":0.55,"ydop":0.74,"vdop":2.10,"tdop":1.50,"hdop":1.10,"gdop":2.80,"pdop":2.30,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":45,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":37,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":38,"used":true},{"PRN":3,"el":10,"az":284,"ss":32,"used":false},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":34,"used":false}]} +$GPGGA,102028,3020.5010,N,01213.7242,E,2,08,1.10,627.54,M,31.479,M,,*4D +$GPRMC,102028,A,3020.5010,N,01213.7242,E,31847.9464,90.000,150107,,*1E +$GPGSA,A,3,06,07,16,18,21,25,30,31,31,,,,2.3,1.1,2.1*38 +$GPGBS,102028,0.24,M,0.24,M,12.08,M*0C +{"class":"TPV","tag":"0xb1","time":1168856428.000,"ept":5.880,"lat":30.341683239,"lon":12.228735920,"alt":627.541,"epx":0.236,"epy":0.236,"epv":12.075,"track":90.0000,"speed":16383.999,"climb":0.002,"eps":0.47,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,38,03,10,284,33*79 +$GPGSV,3,3,10,07,43,056,43,22,13,173,34*7C +{"class":"SKY","tag":"0x86","time":1168732908.643,"xdop":0.55,"ydop":0.74,"vdop":2.10,"tdop":1.50,"hdop":1.10,"gdop":2.80,"pdop":2.30,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":38,"used":true},{"PRN":3,"el":10,"az":284,"ss":33,"used":false},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":34,"used":false}]} +$GPGGA,102029,3020.5010,N,01213.7242,E,2,08,1.10,627.56,M,31.479,M,,*4E +$GPRMC,102029,A,3020.5010,N,01213.7242,E,31847.9445,0.000,150107,,*25 +$GPGSA,A,3,06,07,16,18,21,25,30,31,31,,,,2.3,1.1,2.1*38 +$GPGBS,102029,0.24,M,0.24,M,12.08,M*0D +{"class":"TPV","tag":"0xb1","time":1168856429.000,"ept":5.880,"lat":30.341683214,"lon":12.228735936,"alt":627.555,"epx":0.236,"epy":0.236,"epv":12.075,"track":0.0000,"speed":16383.998,"climb":0.007,"eps":0.47,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,38,03,10,284,34*7E +$GPGSV,3,3,10,07,43,056,43,22,13,173,34*7C +{"class":"SKY","tag":"0x86","time":1168732908.644,"xdop":0.55,"ydop":0.74,"vdop":2.10,"tdop":1.50,"hdop":1.10,"gdop":2.80,"pdop":2.30,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":38,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":false},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":34,"used":false}]} +$GPGGA,102030,3020.5010,N,01213.7242,E,2,08,1.10,627.54,M,31.479,M,,*44 +$GPRMC,102030,A,3020.5010,N,01213.7242,E,31847.9464,90.000,150107,,*17 +$GPGSA,A,3,06,07,16,18,21,25,30,31,31,,,,2.3,1.1,2.1*38 +$GPGBS,102030,0.25,M,0.25,M,12.08,M*05 +{"class":"TPV","tag":"0xb1","time":1168856430.000,"ept":5.880,"lat":30.341683231,"lon":12.228735877,"alt":627.537,"epx":0.249,"epy":0.249,"epv":12.075,"track":90.0000,"speed":16383.999,"climb":0.000,"eps":0.49,"mode":3} +$GPGSV,3,1,10,21,78,040,46,31,39,230,44,06,36,062,43,25,36,245,43*7F +$GPGSV,3,2,10,30,26,132,38,16,40,321,42,18,31,140,38,03,10,284,34*7E +$GPGSV,3,3,10,07,43,056,43,22,13,173,34*7C +{"class":"SKY","tag":"0x86","time":1168732908.645,"xdop":0.55,"ydop":0.74,"vdop":2.10,"tdop":1.50,"hdop":1.10,"gdop":2.80,"pdop":2.30,"satellites":[{"PRN":21,"el":78,"az":40,"ss":46,"used":true},{"PRN":31,"el":39,"az":230,"ss":44,"used":true},{"PRN":6,"el":36,"az":62,"ss":43,"used":true},{"PRN":25,"el":36,"az":245,"ss":43,"used":true},{"PRN":30,"el":26,"az":132,"ss":38,"used":true},{"PRN":16,"el":40,"az":321,"ss":42,"used":true},{"PRN":18,"el":31,"az":140,"ss":38,"used":true},{"PRN":3,"el":10,"az":284,"ss":34,"used":false},{"PRN":7,"el":43,"az":56,"ss":43,"used":true},{"PRN":22,"el":13,"az":173,"ss":34,"used":false}]} diff --git a/test/daemon/nl402u.log b/test/daemon/nl402u.log new file mode 100644 index 0000000..b3f0337 --- /dev/null +++ b/test/daemon/nl402u.log @@ -0,0 +1,264 @@ +# Name: NL-402U USB Empfänger +# Chipset: u-blox5 GPS & GALILEO SuperSense® +# Submitted-by: Klaus Plöger k.ploeger@gastradata.de +# Date: 2008:07:24 +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPTXT,01,01,02,u-blox ag - www.u-blox.com*50 +$GPTXT,01,01,02,HW UBX-G5xxx 00040005 *1B +$GPTXT,01,01,02,EXT CORE 5.00 (28483) Jun 6 2008 14:42:32*5F +$GPTXT,01,01,02,ROM BASE 4.00*12 +$GPTXT,01,01,02,MOD LEA-5H-0*2E +$GPTXT,01,01,02,ANTSUPERV=AC SD PDoS SR*20 +$GPTXT,01,01,02,ANTSTATUS=OK*3B +$GPRMC,104706.000,A,5405.6081,N,01049.4791,E,0.24,18.02,240709,,,A*53 +$GPVTG,18.02,T,,M,0.24,N,0.4,K,A*34 +$GPGGA,104706.000,5405.6081,N,01049.4791,E,1,08,1.1,40.8,M,43.6,M,,0000*61 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.7,1.1,1.3*3C +$GPGSV,3,1,12,08,30,075,25,09,20,262,32,10,16,194,27,15,74,263,46*77 +$GPGSV,3,2,12,17,14,127,19,18,22,315,27,19,05,014,27,21,00,284,*7F +$GPGSV,3,3,12,22,00,337,19,26,03,304,,27,41,264,26,28,58,081,30*7C +$GPGLL,5405.6081,N,01049.4791,E,104706.000,A,A*51 +$GPRMC,104707.000,A,5405.6083,N,01049.4822,E,0.50,19.27,240709,,,A*52 +$GPVTG,19.27,T,,M,0.50,N,0.9,K,A*3C +$GPGGA,104707.000,5405.6083,N,01049.4822,E,1,08,1.0,40.6,M,43.6,M,,0000*6A +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,22,09,20,262,31,10,16,194,27,15,74,263,46*73 +$GPGSV,3,2,12,17,14,127,17,18,22,315,27,19,05,014,26,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,17,26,03,304,,27,41,264,27,28,58,081,30*73 +$GPGLL,5405.6083,N,01049.4822,E,104707.000,A,A*55 +$GPRMC,104708.000,A,5405.6082,N,01049.4856,E,0.32,19.19,240709,,,A*56 +$GPVTG,19.19,T,,M,0.32,N,0.6,K,A*3A +$GPGGA,104708.000,5405.6082,N,01049.4856,E,1,08,0.9,40.0,M,43.6,M,,0000*69 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,32,10,16,194,26,15,74,263,45*73 +$GPGSV,3,2,12,17,14,127,15,18,22,315,26,19,05,014,26,21,00,284,*73 +$GPGSV,3,3,12,22,00,337,15,26,03,304,,27,41,264,28,28,58,081,30*7E +$GPGLL,5405.6082,N,01049.4856,E,104708.000,A,A*58 +$GPRMC,104709.000,A,5405.6083,N,01049.4868,E,0.37,21.29,240709,,,A*56 +$GPVTG,21.29,T,,M,0.37,N,0.7,K,A*36 +$GPGGA,104709.000,5405.6083,N,01049.4868,E,1,08,0.9,40.6,M,43.6,M,,0000*62 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,24,09,20,262,31,10,16,194,25,15,74,263,44*75 +$GPGSV,3,2,12,17,14,127,14,18,22,315,25,19,05,014,26,21,00,284,*71 +$GPGSV,3,3,12,22,00,337,16,26,03,304,,27,41,264,26,28,58,081,29*7B +$GPGLL,5405.6083,N,01049.4868,E,104709.000,A,A*55 +$GPRMC,104710.000,A,5405.6081,N,01049.4876,E,0.94,27.15,240709,,,A*53 +$GPVTG,27.15,T,,M,0.94,N,1.8,K,A*38 +$GPGGA,104710.000,5405.6081,N,01049.4876,E,1,08,0.9,40.4,M,43.6,M,,0000*65 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,24,09,20,262,30,10,16,194,25,15,74,263,44*74 +$GPGSV,3,2,12,17,14,127,14,18,22,315,24,19,05,014,26,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,16,26,03,304,,27,41,264,25,28,58,081,30*70 +$GPGLL,5405.6081,N,01049.4876,E,104710.000,A,A*50 +$GPRMC,104711.000,A,5405.6083,N,01049.4879,E,0.63,28.37,240709,,,A*58 +$GPVTG,28.37,T,,M,0.63,N,1.2,K,A*35 +$GPGGA,104711.000,5405.6083,N,01049.4879,E,1,08,1.0,39.8,M,43.6,M,,0000*63 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,24,09,20,262,30,10,16,194,24,15,74,263,44*75 +$GPGSV,3,2,12,17,14,127,,18,22,315,22,19,05,014,26,21,00,284,*73 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,264,28,28,58,081,30*7A +$GPGLL,5405.6083,N,01049.4879,E,104711.000,A,A*5C +$GPRMC,104712.000,A,5405.6086,N,01049.4879,E,1.23,24.74,240709,,,A*50 +$GPVTG,24.74,T,,M,1.23,N,2.3,K,A*39 +$GPGGA,104712.000,5405.6086,N,01049.4879,E,1,08,1.0,39.2,M,43.6,M,,0000*6F +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,23,09,20,262,29,10,16,194,22,15,74,263,42*7A +$GPGSV,3,2,12,17,14,127,,18,22,315,18,19,05,014,26,21,00,284,*7A +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,264,29,28,58,081,29*73 +$GPGLL,5405.6086,N,01049.4879,E,104712.000,A,A*5A +$GPRMC,104713.000,A,5405.6087,N,01049.4885,E,0.19,24.74,240709,,,A*5B +$GPVTG,24.74,T,,M,0.19,N,0.4,K,A*34 +$GPGGA,104713.000,5405.6087,N,01049.4885,E,1,08,1.0,39.0,M,43.6,M,,0000*6E +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,25,09,20,262,29,10,16,194,23,15,74,263,43*7C +$GPGSV,3,2,12,17,14,127,,18,22,315,19,19,05,014,27,21,00,284,*7A +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,264,31,28,58,081,29*7A +$GPGLL,5405.6087,N,01049.4885,E,104713.000,A,A*59 +$GPRMC,104714.000,A,5405.6087,N,01049.4885,E,0.25,14.12,240709,,,A*50 +$GPVTG,14.12,T,,M,0.25,N,0.5,K,A*39 +$GPGGA,104714.000,5405.6087,N,01049.4885,E,1,08,1.0,38.8,M,43.6,M,,0000*60 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,25,09,20,262,31,10,16,194,23,15,74,263,44*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,20,19,05,014,27,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,19,27,41,264,31,28,58,081,29*72 +$GPGLL,5405.6087,N,01049.4885,E,104714.000,A,A*5E +$GPRMC,104715.000,A,5405.6087,N,01049.4890,E,1.07,20.69,240709,,,A*5F +$GPVTG,20.69,T,,M,1.07,N,2.0,K,A*34 +$GPGGA,104715.000,5405.6087,N,01049.4890,E,1,08,1.0,38.3,M,43.6,M,,0000*6E +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,23,09,20,262,31,10,16,194,24,15,74,263,44*73 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,28,21,00,284,*7E +$GPGSV,3,3,12,22,00,337,,26,03,304,19,27,41,264,30,28,58,081,29*73 +$GPGLL,5405.6087,N,01049.4890,E,104715.000,A,A*5B +$GPRMC,104716.000,A,5405.6088,N,01049.4891,E,0.41,23.09,240709,,,A*54 +$GPVTG,23.09,T,,M,0.41,N,0.8,K,A*38 +$GPGGA,104716.000,5405.6088,N,01049.4891,E,1,08,1.0,38.0,M,43.6,M,,0000*60 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,22,09,20,262,30,10,16,194,23,15,74,263,44*74 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,27,21,00,284,*71 +$GPGSV,3,3,12,22,00,337,,26,03,304,18,27,41,264,30,28,58,081,29*72 +$GPGLL,5405.6088,N,01049.4891,E,104716.000,A,A*56 +$GPRMC,104717.000,A,5405.6087,N,01049.4896,E,0.53,27.07,240709,,,A*54 +$GPVTG,27.07,T,,M,0.53,N,1.0,K,A*38 +$GPGGA,104717.000,5405.6087,N,01049.4896,E,1,08,1.0,37.6,M,43.6,M,,0000*60 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,22,09,20,262,31,10,16,194,24,15,74,263,44*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,20,19,05,014,27,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,18,27,41,264,30,28,58,081,28*73 +$GPGLL,5405.6087,N,01049.4896,E,104717.000,A,A*5F +$GPRMC,104718.000,A,5405.6084,N,01049.4902,E,0.55,32.66,240709,,,A*51 +$GPVTG,32.66,T,,M,0.55,N,1.0,K,A*3D +$GPGGA,104718.000,5405.6084,N,01049.4902,E,1,08,0.9,37.1,M,43.6,M,,0000*6F +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,21,09,20,262,31,10,16,194,25,15,74,263,44*70 +$GPGSV,3,2,12,17,14,127,,18,22,315,20,19,05,014,27,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,16,27,41,264,29,28,58,081,27*7A +$GPGLL,5405.6084,N,01049.4902,E,104718.000,A,A*5F +$GPRMC,104719.000,A,5405.6085,N,01049.4903,E,1.08,28.79,240709,,,A*5C +$GPVTG,28.79,T,,M,1.08,N,2.0,K,A*32 +$GPGGA,104719.000,5405.6085,N,01049.4903,E,1,08,0.9,36.8,M,43.6,M,,0000*66 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,31,10,16,194,25,15,74,263,44*73 +$GPGSV,3,2,12,17,14,127,,18,22,315,19,19,05,014,26,21,00,284,*7B +$GPGSV,3,3,12,22,00,337,,26,03,304,14,27,41,264,29,28,58,081,26*79 +$GPGLL,5405.6085,N,01049.4903,E,104719.000,A,A*5E +$GPRMC,104720.000,A,5405.6083,N,01049.4905,E,0.31,19.40,240709,,,A*55 +$GPVTG,19.40,T,,M,0.31,N,0.6,K,A*35 +$GPGGA,104720.000,5405.6083,N,01049.4905,E,1,08,0.9,36.5,M,43.6,M,,0000*61 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,31,10,16,194,25,15,74,263,44*73 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,26,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,12,27,41,264,28,28,58,081,27*7F +$GPGLL,5405.6083,N,01049.4905,E,104720.000,A,A*54 +$GPRMC,104721.000,A,5405.6081,N,01049.4905,E,0.82,9.27,240709,,,A*6E +$GPVTG,9.27,T,,M,0.82,N,1.5,K,A*0F +$GPGGA,104721.000,5405.6081,N,01049.4905,E,1,08,0.9,36.4,M,43.6,M,,0000*63 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,33,10,16,194,25,15,74,263,46*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,26,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,12,27,41,264,28,28,58,081,27*7F +$GPGLL,5405.6081,N,01049.4905,E,104721.000,A,A*57 +$GPRMC,104722.000,A,5405.6080,N,01049.4910,E,1.06,14.12,240709,,,A*5F +$GPVTG,14.12,T,,M,1.06,N,2.0,K,A*3E +$GPGGA,104722.000,5405.6080,N,01049.4910,E,1,08,0.9,36.4,M,43.6,M,,0000*65 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,21,09,20,262,33,10,16,194,24,15,74,263,45*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,22,19,05,014,26,21,00,284,*73 +$GPGSV,3,3,12,22,00,337,,26,03,304,11,27,41,264,28,28,58,081,26*7D +$GPGLL,5405.6080,N,01049.4910,E,104722.000,A,A*51 +$GPRMC,104723.000,A,5405.6079,N,01049.4913,E,0.23,18.77,240709,,,A*52 +$GPVTG,18.77,T,,M,0.23,N,0.4,K,A*31 +$GPGGA,104723.000,5405.6079,N,01049.4913,E,1,08,0.9,36.2,M,43.6,M,,0000*67 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,32,10,16,194,25,15,74,263,43*77 +$GPGSV,3,2,12,17,14,127,,18,22,315,23,19,05,014,26,21,00,284,*72 +$GPGSV,3,3,12,22,00,337,,26,03,304,09,27,41,264,28,28,58,081,26*74 +$GPGLL,5405.6079,N,01049.4913,E,104723.000,A,A*55 +$GPRMC,104724.000,A,5405.6076,N,01049.4916,E,0.43,25.48,240709,,,A*5B +$GPVTG,25.48,T,,M,0.43,N,0.8,K,A*39 +$GPGGA,104724.000,5405.6076,N,01049.4916,E,1,08,0.9,35.9,M,43.6,M,,0000*62 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,32,10,16,194,26,15,74,263,44*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,24,19,05,014,26,21,00,284,*75 +$GPGSV,3,3,12,22,00,337,,26,03,304,11,27,41,264,27,28,58,081,26*72 +$GPGLL,5405.6076,N,01049.4916,E,104724.000,A,A*58 +$GPRMC,104725.000,A,5405.6076,N,01049.4917,E,0.31,24.01,240709,,,A*52 +$GPVTG,24.01,T,,M,0.31,N,0.6,K,A*3E +$GPGGA,104725.000,5405.6076,N,01049.4917,E,1,08,0.9,35.6,M,43.6,M,,0000*6D +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,24,09,20,262,31,10,16,194,25,15,74,263,44*75 +$GPGSV,3,2,12,17,14,127,,18,22,315,22,19,05,014,27,21,00,284,*72 +$GPGSV,3,3,12,22,00,337,,26,03,304,09,27,41,264,25,28,58,081,25*7A +$GPGLL,5405.6076,N,01049.4917,E,104725.000,A,A*58 +$GPRMC,104726.000,A,5405.6076,N,01049.4918,E,0.42,31.83,240709,,,A*54 +$GPVTG,31.83,T,,M,0.42,N,0.8,K,A*3A +$GPGGA,104726.000,5405.6076,N,01049.4918,E,1,08,0.9,35.3,M,43.6,M,,0000*64 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,32,10,16,194,24,15,74,263,44*71 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,27,21,00,284,*71 +$GPGSV,3,3,12,22,00,337,,26,03,304,08,27,41,264,23,28,58,081,24*7C +$GPGLL,5405.6076,N,01049.4918,E,104726.000,A,A*54 +$GPRMC,104727.000,A,5405.6077,N,01049.4916,E,0.80,28.30,240709,,,A*54 +$GPVTG,28.30,T,,M,0.80,N,1.5,K,A*38 +$GPGGA,104727.000,5405.6077,N,01049.4916,E,1,08,0.9,35.1,M,43.6,M,,0000*68 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,21,09,20,262,32,10,16,194,24,15,74,263,44*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,26,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,08,27,41,264,24,28,58,081,24*7B +$GPGLL,5405.6077,N,01049.4916,E,104727.000,A,A*5A +$GPRMC,104728.000,A,5405.6078,N,01049.4918,E,0.56,28.66,240709,,,A*52 +$GPVTG,28.66,T,,M,0.56,N,1.0,K,A*35 +$GPGGA,104728.000,5405.6078,N,01049.4918,E,1,08,0.9,34.9,M,43.6,M,,0000*6F +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,32,10,16,194,25,15,74,263,44*70 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,27,21,00,284,*71 +$GPGSV,3,3,12,22,00,337,,26,03,304,09,27,41,265,24,28,58,081,22*7D +$GPGLL,5405.6078,N,01049.4918,E,104728.000,A,A*54 +$GPRMC,104729.000,A,5405.6076,N,01049.4921,E,0.51,34.94,240709,,,A*50 +$GPVTG,34.94,T,,M,0.51,N,0.9,K,A*3A +$GPGGA,104729.000,5405.6076,N,01049.4921,E,1,08,0.9,34.7,M,43.6,M,,0000*64 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,32,10,16,194,24,15,74,263,44*71 +$GPGSV,3,2,12,17,14,127,,18,22,315,22,19,05,014,27,21,00,284,*72 +$GPGSV,3,3,12,22,00,337,,26,03,304,08,27,41,265,25,28,58,081,22*7D +$GPGLL,5405.6076,N,01049.4921,E,104729.000,A,A*51 +$GPRMC,104730.000,A,5405.6073,N,01049.4922,E,1.07,44.97,240709,,,A*58 +$GPVTG,44.97,T,,M,1.07,N,2.0,K,A*37 +$GPGGA,104730.000,5405.6073,N,01049.4922,E,1,08,0.9,34.5,M,43.6,M,,0000*68 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,33,10,16,194,23,15,74,263,44*76 +$GPGSV,3,2,12,17,14,127,18,18,22,315,22,19,05,014,27,21,00,284,*7B +$GPGSV,3,3,12,22,00,337,,26,03,304,08,27,41,265,25,28,58,081,21*7E +$GPGLL,5405.6073,N,01049.4922,E,104730.000,A,A*5F +$GPRMC,104731.000,A,5405.6070,N,01049.4926,E,0.67,50.17,240709,,,A*54 +$GPVTG,50.17,T,,M,0.67,N,1.3,K,A*3D +$GPGGA,104731.000,5405.6070,N,01049.4926,E,1,08,0.9,34.4,M,43.6,M,,0000*6F +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,21,09,20,262,33,10,16,194,23,15,74,263,44*74 +$GPGSV,3,2,12,17,14,127,17,18,22,315,22,19,05,014,27,21,00,284,*74 +$GPGSV,3,3,12,22,00,337,,26,03,304,08,27,41,265,26,28,58,081,22*7E +$GPGLL,5405.6070,N,01049.4926,E,104731.000,A,A*59 +$GPRMC,104732.000,A,5405.6071,N,01049.4925,E,0.71,43.34,240709,,,A*51 +$GPVTG,43.34,T,,M,0.71,N,1.3,K,A*39 +$GPGGA,104732.000,5405.6071,N,01049.4925,E,1,08,0.9,34.3,M,43.6,M,,0000*69 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,21,09,20,262,34,10,16,194,23,15,74,263,44*73 +$GPGSV,3,2,12,17,14,127,15,18,22,315,21,19,05,014,27,21,00,284,*75 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,265,25,28,58,081,23*74 +$GPGLL,5405.6071,N,01049.4925,E,104732.000,A,A*58 +$GPRMC,104733.000,A,5405.6069,N,01049.4928,E,1.13,49.89,240709,,,A*5D +$GPVTG,49.89,T,,M,1.13,N,2.1,K,A*31 +$GPGGA,104733.000,5405.6069,N,01049.4928,E,1,08,0.9,34.1,M,43.6,M,,0000*6E +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,33,10,16,194,22,15,74,263,44*76 +$GPGSV,3,2,12,17,14,127,16,18,22,315,22,19,05,014,27,21,00,284,*75 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,265,24,28,58,081,24*72 +$GPGLL,5405.6069,N,01049.4928,E,104733.000,A,A*5D +$GPRMC,104734.000,A,5405.6070,N,01049.4930,E,1.06,48.90,240709,,,A*56 +$GPVTG,48.90,T,,M,1.06,N,2.0,K,A*3D +$GPGGA,104734.000,5405.6070,N,01049.4930,E,1,08,0.9,34.0,M,43.6,M,,0000*69 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,34,10,16,194,23,15,74,263,44*71 +$GPGSV,3,2,12,17,14,127,17,18,22,315,22,19,05,014,27,21,00,284,*74 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,265,24,28,58,081,24*72 +$GPGLL,5405.6070,N,01049.4930,E,104734.000,A,A*5B +$GPRMC,104735.000,A,5405.6071,N,01049.4935,E,0.96,50.63,240709,,,A*5E +$GPVTG,50.63,T,,M,0.96,N,1.8,K,A*3B +$GPGGA,104735.000,5405.6071,N,01049.4935,E,1,08,0.9,33.8,M,43.6,M,,0000*63 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,33,10,16,194,23,15,74,263,44*76 +$GPGSV,3,2,12,17,14,127,16,18,22,315,22,19,05,014,27,21,00,284,*75 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,265,24,28,58,081,24*72 +$GPGLL,5405.6071,N,01049.4935,E,104735.000,A,A*5E +$GPRMC,104736.000,A,5405.6072,N,01049.4936,E,0.52,50.27,240709,,,A*55 +$GPVTG,50.27,T,,M,0.52,N,1.0,K,A*3B +$GPGGA,104736.000,5405.6072,N,01049.4936,E,1,08,0.9,33.7,M,43.6,M,,0000*6F +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,33,10,16,194,24,15,74,263,44*71 +$GPGSV,3,2,12,17,14,127,16,18,22,315,21,19,05,014,27,21,00,284,*76 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,265,24,28,58,081,24*72 +$GPGLL,5405.6072,N,01049.4936,E,104736.000,A,A*5D + diff --git a/test/daemon/nl402u.log.chk b/test/daemon/nl402u.log.chk new file mode 100644 index 0000000..3c0f46c --- /dev/null +++ b/test/daemon/nl402u.log.chk @@ -0,0 +1,320 @@ +$GPTXT,01,01,02,u-blox ag - www.u-blox.com*50 +$GPTXT,01,01,02,HW UBX-G5xxx 00040005 *1B +$GPTXT,01,01,02,EXT CORE 5.00 (28483) Jun 6 2008 14:42:32*5F +$GPTXT,01,01,02,ROM BASE 4.00*12 +$GPTXT,01,01,02,MOD LEA-5H-0*2E +$GPTXT,01,01,02,ANTSUPERV=AC SD PDoS SR*20 +$GPTXT,01,01,02,ANTSTATUS=OK*3B +$GPRMC,104706.000,A,5405.6081,N,01049.4791,E,0.24,18.02,240709,,,A*53 +{"class":"TPV","tag":"RMC","time":1248432426.000,"ept":0.005,"lat":54.093468333,"lon":10.824651667,"track":18.0200,"speed":0.123,"mode":2} +$GPVTG,18.02,T,,M,0.24,N,0.4,K,A*34 +$GPGGA,104706.000,5405.6081,N,01049.4791,E,1,08,1.1,40.8,M,43.6,M,,0000*61 +{"class":"TPV","tag":"GGA","time":1248432426.000,"ept":0.005,"lat":54.093468333,"lon":10.824651667,"alt":40.800,"track":18.0200,"speed":0.123,"mode":3} +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.7,1.1,1.3*3C +{"class":"TPV","tag":"GSA","time":1248432426.000,"ept":0.005,"lat":54.093468333,"lon":10.824651667,"alt":40.800,"epv":29.900,"track":18.0200,"speed":0.123,"climb":0.000,"mode":3} +$GPGSV,3,1,12,08,30,075,25,09,20,262,32,10,16,194,27,15,74,263,46*77 +$GPGSV,3,2,12,17,14,127,19,18,22,315,27,19,05,014,27,21,00,284,*7F +$GPGSV,3,3,12,22,00,337,19,26,03,304,,27,41,264,26,28,58,081,30*7C +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":25,"used":true},{"PRN":9,"el":20,"az":262,"ss":32,"used":true},{"PRN":10,"el":16,"az":194,"ss":27,"used":true},{"PRN":15,"el":74,"az":263,"ss":46,"used":true},{"PRN":17,"el":14,"az":127,"ss":19,"used":false},{"PRN":18,"el":22,"az":315,"ss":27,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":19,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":264,"ss":26,"used":true},{"PRN":28,"el":58,"az":81,"ss":30,"used":true}]} +$GPGLL,5405.6081,N,01049.4791,E,104706.000,A,A*51 +{"class":"TPV","tag":"GLL","time":1248432426.000,"ept":0.005,"lat":54.093468333,"lon":10.824651667,"alt":40.800,"epx":8.042,"epy":9.278,"epv":29.900,"track":18.0200,"speed":0.123,"climb":0.000,"mode":3} +$GPRMC,104707.000,A,5405.6083,N,01049.4822,E,0.50,19.27,240709,,,A*52 +$GPVTG,19.27,T,,M,0.50,N,0.9,K,A*3C +$GPGGA,104707.000,5405.6083,N,01049.4822,E,1,08,1.0,40.6,M,43.6,M,,0000*6A +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,22,09,20,262,31,10,16,194,27,15,74,263,46*73 +$GPGSV,3,2,12,17,14,127,17,18,22,315,27,19,05,014,26,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,17,26,03,304,,27,41,264,27,28,58,081,30*73 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":22,"used":true},{"PRN":9,"el":20,"az":262,"ss":31,"used":true},{"PRN":10,"el":16,"az":194,"ss":27,"used":true},{"PRN":15,"el":74,"az":263,"ss":46,"used":true},{"PRN":17,"el":14,"az":127,"ss":17,"used":false},{"PRN":18,"el":22,"az":315,"ss":27,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":17,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":264,"ss":27,"used":true},{"PRN":28,"el":58,"az":81,"ss":30,"used":true}]} +$GPGLL,5405.6083,N,01049.4822,E,104707.000,A,A*55 +{"class":"TPV","tag":"GLL","time":1248432427.000,"ept":0.005,"lat":54.093471667,"lon":10.824703333,"alt":40.600,"epx":8.042,"epy":9.278,"epv":29.976,"track":19.2700,"speed":0.257,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104708.000,A,5405.6082,N,01049.4856,E,0.32,19.19,240709,,,A*56 +$GPVTG,19.19,T,,M,0.32,N,0.6,K,A*3A +$GPGGA,104708.000,5405.6082,N,01049.4856,E,1,08,0.9,40.0,M,43.6,M,,0000*69 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,32,10,16,194,26,15,74,263,45*73 +$GPGSV,3,2,12,17,14,127,15,18,22,315,26,19,05,014,26,21,00,284,*73 +$GPGSV,3,3,12,22,00,337,15,26,03,304,,27,41,264,28,28,58,081,30*7E +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":23,"used":true},{"PRN":9,"el":20,"az":262,"ss":32,"used":true},{"PRN":10,"el":16,"az":194,"ss":26,"used":true},{"PRN":15,"el":74,"az":263,"ss":45,"used":true},{"PRN":17,"el":14,"az":127,"ss":15,"used":false},{"PRN":18,"el":22,"az":315,"ss":26,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":15,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":264,"ss":28,"used":true},{"PRN":28,"el":58,"az":81,"ss":30,"used":true}]} +$GPGLL,5405.6082,N,01049.4856,E,104708.000,A,A*58 +{"class":"TPV","tag":"GLL","time":1248432428.000,"ept":0.005,"lat":54.093470000,"lon":10.824760000,"alt":40.000,"epx":8.042,"epy":9.278,"epv":29.976,"track":19.1900,"speed":0.165,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104709.000,A,5405.6083,N,01049.4868,E,0.37,21.29,240709,,,A*56 +$GPVTG,21.29,T,,M,0.37,N,0.7,K,A*36 +$GPGGA,104709.000,5405.6083,N,01049.4868,E,1,08,0.9,40.6,M,43.6,M,,0000*62 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,24,09,20,262,31,10,16,194,25,15,74,263,44*75 +$GPGSV,3,2,12,17,14,127,14,18,22,315,25,19,05,014,26,21,00,284,*71 +$GPGSV,3,3,12,22,00,337,16,26,03,304,,27,41,264,26,28,58,081,29*7B +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":24,"used":true},{"PRN":9,"el":20,"az":262,"ss":31,"used":true},{"PRN":10,"el":16,"az":194,"ss":25,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":14,"used":false},{"PRN":18,"el":22,"az":315,"ss":25,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":16,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":264,"ss":26,"used":true},{"PRN":28,"el":58,"az":81,"ss":29,"used":true}]} +$GPGLL,5405.6083,N,01049.4868,E,104709.000,A,A*55 +{"class":"TPV","tag":"GLL","time":1248432429.000,"ept":0.005,"lat":54.093471667,"lon":10.824780000,"alt":40.600,"epx":8.042,"epy":9.278,"epv":29.976,"track":21.2900,"speed":0.190,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104710.000,A,5405.6081,N,01049.4876,E,0.94,27.15,240709,,,A*53 +$GPVTG,27.15,T,,M,0.94,N,1.8,K,A*38 +$GPGGA,104710.000,5405.6081,N,01049.4876,E,1,08,0.9,40.4,M,43.6,M,,0000*65 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,24,09,20,262,30,10,16,194,25,15,74,263,44*74 +$GPGSV,3,2,12,17,14,127,14,18,22,315,24,19,05,014,26,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,16,26,03,304,,27,41,264,25,28,58,081,30*70 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":24,"used":true},{"PRN":9,"el":20,"az":262,"ss":30,"used":true},{"PRN":10,"el":16,"az":194,"ss":25,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":14,"used":false},{"PRN":18,"el":22,"az":315,"ss":24,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":16,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":264,"ss":25,"used":true},{"PRN":28,"el":58,"az":81,"ss":30,"used":true}]} +$GPGLL,5405.6081,N,01049.4876,E,104710.000,A,A*50 +{"class":"TPV","tag":"GLL","time":1248432430.000,"ept":0.005,"lat":54.093468333,"lon":10.824793333,"alt":40.400,"epx":8.042,"epy":9.278,"epv":29.976,"track":27.1500,"speed":0.484,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104711.000,A,5405.6083,N,01049.4879,E,0.63,28.37,240709,,,A*58 +$GPVTG,28.37,T,,M,0.63,N,1.2,K,A*35 +$GPGGA,104711.000,5405.6083,N,01049.4879,E,1,08,1.0,39.8,M,43.6,M,,0000*63 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,24,09,20,262,30,10,16,194,24,15,74,263,44*75 +$GPGSV,3,2,12,17,14,127,,18,22,315,22,19,05,014,26,21,00,284,*73 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,264,28,28,58,081,30*7A +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":24,"used":true},{"PRN":9,"el":20,"az":262,"ss":30,"used":true},{"PRN":10,"el":16,"az":194,"ss":24,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":22,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":264,"ss":28,"used":true},{"PRN":28,"el":58,"az":81,"ss":30,"used":true}]} +$GPGLL,5405.6083,N,01049.4879,E,104711.000,A,A*5C +{"class":"TPV","tag":"GLL","time":1248432431.000,"ept":0.005,"lat":54.093471667,"lon":10.824798333,"alt":39.800,"epx":8.042,"epy":9.278,"epv":29.976,"track":28.3700,"speed":0.324,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104712.000,A,5405.6086,N,01049.4879,E,1.23,24.74,240709,,,A*50 +$GPVTG,24.74,T,,M,1.23,N,2.3,K,A*39 +$GPGGA,104712.000,5405.6086,N,01049.4879,E,1,08,1.0,39.2,M,43.6,M,,0000*6F +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,23,09,20,262,29,10,16,194,22,15,74,263,42*7A +$GPGSV,3,2,12,17,14,127,,18,22,315,18,19,05,014,26,21,00,284,*7A +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,264,29,28,58,081,29*73 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":23,"used":true},{"PRN":9,"el":20,"az":262,"ss":29,"used":true},{"PRN":10,"el":16,"az":194,"ss":22,"used":true},{"PRN":15,"el":74,"az":263,"ss":42,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":18,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":264,"ss":29,"used":true},{"PRN":28,"el":58,"az":81,"ss":29,"used":true}]} +$GPGLL,5405.6086,N,01049.4879,E,104712.000,A,A*5A +{"class":"TPV","tag":"GLL","time":1248432432.000,"ept":0.005,"lat":54.093476667,"lon":10.824798333,"alt":39.200,"epx":8.042,"epy":9.278,"epv":29.976,"track":24.7400,"speed":0.633,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104713.000,A,5405.6087,N,01049.4885,E,0.19,24.74,240709,,,A*5B +$GPVTG,24.74,T,,M,0.19,N,0.4,K,A*34 +$GPGGA,104713.000,5405.6087,N,01049.4885,E,1,08,1.0,39.0,M,43.6,M,,0000*6E +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,25,09,20,262,29,10,16,194,23,15,74,263,43*7C +$GPGSV,3,2,12,17,14,127,,18,22,315,19,19,05,014,27,21,00,284,*7A +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,264,31,28,58,081,29*7A +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":25,"used":true},{"PRN":9,"el":20,"az":262,"ss":29,"used":true},{"PRN":10,"el":16,"az":194,"ss":23,"used":true},{"PRN":15,"el":74,"az":263,"ss":43,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":19,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":264,"ss":31,"used":true},{"PRN":28,"el":58,"az":81,"ss":29,"used":true}]} +$GPGLL,5405.6087,N,01049.4885,E,104713.000,A,A*59 +{"class":"TPV","tag":"GLL","time":1248432433.000,"ept":0.005,"lat":54.093478333,"lon":10.824808333,"alt":39.000,"epx":8.042,"epy":9.278,"epv":29.976,"track":24.7400,"speed":0.098,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104714.000,A,5405.6087,N,01049.4885,E,0.25,14.12,240709,,,A*50 +$GPVTG,14.12,T,,M,0.25,N,0.5,K,A*39 +$GPGGA,104714.000,5405.6087,N,01049.4885,E,1,08,1.0,38.8,M,43.6,M,,0000*60 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,25,09,20,262,31,10,16,194,23,15,74,263,44*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,20,19,05,014,27,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,19,27,41,264,31,28,58,081,29*72 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":25,"used":true},{"PRN":9,"el":20,"az":262,"ss":31,"used":true},{"PRN":10,"el":16,"az":194,"ss":23,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":20,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":19,"used":false},{"PRN":27,"el":41,"az":264,"ss":31,"used":true},{"PRN":28,"el":58,"az":81,"ss":29,"used":true}]} +$GPGLL,5405.6087,N,01049.4885,E,104714.000,A,A*5E +{"class":"TPV","tag":"GLL","time":1248432434.000,"ept":0.005,"lat":54.093478333,"lon":10.824808333,"alt":38.800,"epx":8.042,"epy":9.278,"epv":29.976,"track":14.1200,"speed":0.129,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104715.000,A,5405.6087,N,01049.4890,E,1.07,20.69,240709,,,A*5F +$GPVTG,20.69,T,,M,1.07,N,2.0,K,A*34 +$GPGGA,104715.000,5405.6087,N,01049.4890,E,1,08,1.0,38.3,M,43.6,M,,0000*6E +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,23,09,20,262,31,10,16,194,24,15,74,263,44*73 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,28,21,00,284,*7E +$GPGSV,3,3,12,22,00,337,,26,03,304,19,27,41,264,30,28,58,081,29*73 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":23,"used":true},{"PRN":9,"el":20,"az":262,"ss":31,"used":true},{"PRN":10,"el":16,"az":194,"ss":24,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":21,"used":true},{"PRN":19,"el":5,"az":14,"ss":28,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":19,"used":false},{"PRN":27,"el":41,"az":264,"ss":30,"used":true},{"PRN":28,"el":58,"az":81,"ss":29,"used":true}]} +$GPGLL,5405.6087,N,01049.4890,E,104715.000,A,A*5B +{"class":"TPV","tag":"GLL","time":1248432435.000,"ept":0.005,"lat":54.093478333,"lon":10.824816667,"alt":38.300,"epx":8.042,"epy":9.278,"epv":29.976,"track":20.6900,"speed":0.550,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104716.000,A,5405.6088,N,01049.4891,E,0.41,23.09,240709,,,A*54 +$GPVTG,23.09,T,,M,0.41,N,0.8,K,A*38 +$GPGGA,104716.000,5405.6088,N,01049.4891,E,1,08,1.0,38.0,M,43.6,M,,0000*60 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,22,09,20,262,30,10,16,194,23,15,74,263,44*74 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,27,21,00,284,*71 +$GPGSV,3,3,12,22,00,337,,26,03,304,18,27,41,264,30,28,58,081,29*72 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":22,"used":true},{"PRN":9,"el":20,"az":262,"ss":30,"used":true},{"PRN":10,"el":16,"az":194,"ss":23,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":21,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":18,"used":false},{"PRN":27,"el":41,"az":264,"ss":30,"used":true},{"PRN":28,"el":58,"az":81,"ss":29,"used":true}]} +$GPGLL,5405.6088,N,01049.4891,E,104716.000,A,A*56 +{"class":"TPV","tag":"GLL","time":1248432436.000,"ept":0.005,"lat":54.093480000,"lon":10.824818333,"alt":38.000,"epx":8.042,"epy":9.278,"epv":29.976,"track":23.0900,"speed":0.211,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104717.000,A,5405.6087,N,01049.4896,E,0.53,27.07,240709,,,A*54 +$GPVTG,27.07,T,,M,0.53,N,1.0,K,A*38 +$GPGGA,104717.000,5405.6087,N,01049.4896,E,1,08,1.0,37.6,M,43.6,M,,0000*60 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,1.0,1.3*3C +$GPGSV,3,1,12,08,30,075,22,09,20,262,31,10,16,194,24,15,74,263,44*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,20,19,05,014,27,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,18,27,41,264,30,28,58,081,28*73 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":22,"used":true},{"PRN":9,"el":20,"az":262,"ss":31,"used":true},{"PRN":10,"el":16,"az":194,"ss":24,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":20,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":18,"used":false},{"PRN":27,"el":41,"az":264,"ss":30,"used":true},{"PRN":28,"el":58,"az":81,"ss":28,"used":true}]} +$GPGLL,5405.6087,N,01049.4896,E,104717.000,A,A*5F +{"class":"TPV","tag":"GLL","time":1248432437.000,"ept":0.005,"lat":54.093478333,"lon":10.824826667,"alt":37.600,"epx":8.042,"epy":9.278,"epv":29.976,"track":27.0700,"speed":0.273,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104718.000,A,5405.6084,N,01049.4902,E,0.55,32.66,240709,,,A*51 +$GPVTG,32.66,T,,M,0.55,N,1.0,K,A*3D +$GPGGA,104718.000,5405.6084,N,01049.4902,E,1,08,0.9,37.1,M,43.6,M,,0000*6F +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,21,09,20,262,31,10,16,194,25,15,74,263,44*70 +$GPGSV,3,2,12,17,14,127,,18,22,315,20,19,05,014,27,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,16,27,41,264,29,28,58,081,27*7A +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":21,"used":true},{"PRN":9,"el":20,"az":262,"ss":31,"used":true},{"PRN":10,"el":16,"az":194,"ss":25,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":20,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":16,"used":false},{"PRN":27,"el":41,"az":264,"ss":29,"used":true},{"PRN":28,"el":58,"az":81,"ss":27,"used":true}]} +$GPGLL,5405.6084,N,01049.4902,E,104718.000,A,A*5F +{"class":"TPV","tag":"GLL","time":1248432438.000,"ept":0.005,"lat":54.093473333,"lon":10.824836667,"alt":37.100,"epx":8.042,"epy":9.278,"epv":29.976,"track":32.6600,"speed":0.283,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104719.000,A,5405.6085,N,01049.4903,E,1.08,28.79,240709,,,A*5C +$GPVTG,28.79,T,,M,1.08,N,2.0,K,A*32 +$GPGGA,104719.000,5405.6085,N,01049.4903,E,1,08,0.9,36.8,M,43.6,M,,0000*66 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,31,10,16,194,25,15,74,263,44*73 +$GPGSV,3,2,12,17,14,127,,18,22,315,19,19,05,014,26,21,00,284,*7B +$GPGSV,3,3,12,22,00,337,,26,03,304,14,27,41,264,29,28,58,081,26*79 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":22,"used":true},{"PRN":9,"el":20,"az":262,"ss":31,"used":true},{"PRN":10,"el":16,"az":194,"ss":25,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":19,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":14,"used":false},{"PRN":27,"el":41,"az":264,"ss":29,"used":true},{"PRN":28,"el":58,"az":81,"ss":26,"used":true}]} +$GPGLL,5405.6085,N,01049.4903,E,104719.000,A,A*5E +{"class":"TPV","tag":"GLL","time":1248432439.000,"ept":0.005,"lat":54.093475000,"lon":10.824838333,"alt":36.800,"epx":8.042,"epy":9.278,"epv":29.976,"track":28.7900,"speed":0.556,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104720.000,A,5405.6083,N,01049.4905,E,0.31,19.40,240709,,,A*55 +$GPVTG,19.40,T,,M,0.31,N,0.6,K,A*35 +$GPGGA,104720.000,5405.6083,N,01049.4905,E,1,08,0.9,36.5,M,43.6,M,,0000*61 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,31,10,16,194,25,15,74,263,44*73 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,26,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,12,27,41,264,28,28,58,081,27*7F +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":22,"used":true},{"PRN":9,"el":20,"az":262,"ss":31,"used":true},{"PRN":10,"el":16,"az":194,"ss":25,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":21,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":12,"used":false},{"PRN":27,"el":41,"az":264,"ss":28,"used":true},{"PRN":28,"el":58,"az":81,"ss":27,"used":true}]} +$GPGLL,5405.6083,N,01049.4905,E,104720.000,A,A*54 +{"class":"TPV","tag":"GLL","time":1248432440.000,"ept":0.005,"lat":54.093471667,"lon":10.824841667,"alt":36.500,"epx":8.042,"epy":9.278,"epv":29.976,"track":19.4000,"speed":0.159,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104721.000,A,5405.6081,N,01049.4905,E,0.82,9.27,240709,,,A*6E +$GPVTG,9.27,T,,M,0.82,N,1.5,K,A*0F +$GPGGA,104721.000,5405.6081,N,01049.4905,E,1,08,0.9,36.4,M,43.6,M,,0000*63 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,33,10,16,194,25,15,74,263,46*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,26,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,12,27,41,264,28,28,58,081,27*7F +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":23,"used":true},{"PRN":9,"el":20,"az":262,"ss":33,"used":true},{"PRN":10,"el":16,"az":194,"ss":25,"used":true},{"PRN":15,"el":74,"az":263,"ss":46,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":21,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":12,"used":false},{"PRN":27,"el":41,"az":264,"ss":28,"used":true},{"PRN":28,"el":58,"az":81,"ss":27,"used":true}]} +$GPGLL,5405.6081,N,01049.4905,E,104721.000,A,A*57 +{"class":"TPV","tag":"GLL","time":1248432441.000,"ept":0.005,"lat":54.093468333,"lon":10.824841667,"alt":36.400,"epx":8.042,"epy":9.278,"epv":29.976,"track":9.2700,"speed":0.422,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104722.000,A,5405.6080,N,01049.4910,E,1.06,14.12,240709,,,A*5F +$GPVTG,14.12,T,,M,1.06,N,2.0,K,A*3E +$GPGGA,104722.000,5405.6080,N,01049.4910,E,1,08,0.9,36.4,M,43.6,M,,0000*65 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,21,09,20,262,33,10,16,194,24,15,74,263,45*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,22,19,05,014,26,21,00,284,*73 +$GPGSV,3,3,12,22,00,337,,26,03,304,11,27,41,264,28,28,58,081,26*7D +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":21,"used":true},{"PRN":9,"el":20,"az":262,"ss":33,"used":true},{"PRN":10,"el":16,"az":194,"ss":24,"used":true},{"PRN":15,"el":74,"az":263,"ss":45,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":22,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":11,"used":false},{"PRN":27,"el":41,"az":264,"ss":28,"used":true},{"PRN":28,"el":58,"az":81,"ss":26,"used":true}]} +$GPGLL,5405.6080,N,01049.4910,E,104722.000,A,A*51 +{"class":"TPV","tag":"GLL","time":1248432442.000,"ept":0.005,"lat":54.093466667,"lon":10.824850000,"alt":36.400,"epx":8.042,"epy":9.278,"epv":29.976,"track":14.1200,"speed":0.545,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104723.000,A,5405.6079,N,01049.4913,E,0.23,18.77,240709,,,A*52 +$GPVTG,18.77,T,,M,0.23,N,0.4,K,A*31 +$GPGGA,104723.000,5405.6079,N,01049.4913,E,1,08,0.9,36.2,M,43.6,M,,0000*67 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,32,10,16,194,25,15,74,263,43*77 +$GPGSV,3,2,12,17,14,127,,18,22,315,23,19,05,014,26,21,00,284,*72 +$GPGSV,3,3,12,22,00,337,,26,03,304,09,27,41,264,28,28,58,081,26*74 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":22,"used":true},{"PRN":9,"el":20,"az":262,"ss":32,"used":true},{"PRN":10,"el":16,"az":194,"ss":25,"used":true},{"PRN":15,"el":74,"az":263,"ss":43,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":23,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":9,"used":false},{"PRN":27,"el":41,"az":264,"ss":28,"used":true},{"PRN":28,"el":58,"az":81,"ss":26,"used":true}]} +$GPGLL,5405.6079,N,01049.4913,E,104723.000,A,A*55 +{"class":"TPV","tag":"GLL","time":1248432443.000,"ept":0.005,"lat":54.093465000,"lon":10.824855000,"alt":36.200,"epx":8.042,"epy":9.278,"epv":29.976,"track":18.7700,"speed":0.118,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104724.000,A,5405.6076,N,01049.4916,E,0.43,25.48,240709,,,A*5B +$GPVTG,25.48,T,,M,0.43,N,0.8,K,A*39 +$GPGGA,104724.000,5405.6076,N,01049.4916,E,1,08,0.9,35.9,M,43.6,M,,0000*62 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,32,10,16,194,26,15,74,263,44*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,24,19,05,014,26,21,00,284,*75 +$GPGSV,3,3,12,22,00,337,,26,03,304,11,27,41,264,27,28,58,081,26*72 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":23,"used":true},{"PRN":9,"el":20,"az":262,"ss":32,"used":true},{"PRN":10,"el":16,"az":194,"ss":26,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":24,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":11,"used":false},{"PRN":27,"el":41,"az":264,"ss":27,"used":true},{"PRN":28,"el":58,"az":81,"ss":26,"used":true}]} +$GPGLL,5405.6076,N,01049.4916,E,104724.000,A,A*58 +{"class":"TPV","tag":"GLL","time":1248432444.000,"ept":0.005,"lat":54.093460000,"lon":10.824860000,"alt":35.900,"epx":8.042,"epy":9.278,"epv":29.976,"track":25.4800,"speed":0.221,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104725.000,A,5405.6076,N,01049.4917,E,0.31,24.01,240709,,,A*52 +$GPVTG,24.01,T,,M,0.31,N,0.6,K,A*3E +$GPGGA,104725.000,5405.6076,N,01049.4917,E,1,08,0.9,35.6,M,43.6,M,,0000*6D +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,24,09,20,262,31,10,16,194,25,15,74,263,44*75 +$GPGSV,3,2,12,17,14,127,,18,22,315,22,19,05,014,27,21,00,284,*72 +$GPGSV,3,3,12,22,00,337,,26,03,304,09,27,41,264,25,28,58,081,25*7A +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":24,"used":true},{"PRN":9,"el":20,"az":262,"ss":31,"used":true},{"PRN":10,"el":16,"az":194,"ss":25,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":22,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":9,"used":false},{"PRN":27,"el":41,"az":264,"ss":25,"used":true},{"PRN":28,"el":58,"az":81,"ss":25,"used":true}]} +$GPGLL,5405.6076,N,01049.4917,E,104725.000,A,A*58 +{"class":"TPV","tag":"GLL","time":1248432445.000,"ept":0.005,"lat":54.093460000,"lon":10.824861667,"alt":35.600,"epx":8.042,"epy":9.278,"epv":29.976,"track":24.0100,"speed":0.159,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104726.000,A,5405.6076,N,01049.4918,E,0.42,31.83,240709,,,A*54 +$GPVTG,31.83,T,,M,0.42,N,0.8,K,A*3A +$GPGGA,104726.000,5405.6076,N,01049.4918,E,1,08,0.9,35.3,M,43.6,M,,0000*64 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,32,10,16,194,24,15,74,263,44*71 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,27,21,00,284,*71 +$GPGSV,3,3,12,22,00,337,,26,03,304,08,27,41,264,23,28,58,081,24*7C +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":22,"used":true},{"PRN":9,"el":20,"az":262,"ss":32,"used":true},{"PRN":10,"el":16,"az":194,"ss":24,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":21,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":8,"used":false},{"PRN":27,"el":41,"az":264,"ss":23,"used":true},{"PRN":28,"el":58,"az":81,"ss":24,"used":true}]} +$GPGLL,5405.6076,N,01049.4918,E,104726.000,A,A*54 +{"class":"TPV","tag":"GLL","time":1248432446.000,"ept":0.005,"lat":54.093460000,"lon":10.824863333,"alt":35.300,"epx":8.042,"epy":9.278,"epv":29.976,"track":31.8300,"speed":0.216,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104727.000,A,5405.6077,N,01049.4916,E,0.80,28.30,240709,,,A*54 +$GPVTG,28.30,T,,M,0.80,N,1.5,K,A*38 +$GPGGA,104727.000,5405.6077,N,01049.4916,E,1,08,0.9,35.1,M,43.6,M,,0000*68 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,21,09,20,262,32,10,16,194,24,15,74,263,44*72 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,26,21,00,284,*70 +$GPGSV,3,3,12,22,00,337,,26,03,304,08,27,41,264,24,28,58,081,24*7B +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":21,"used":true},{"PRN":9,"el":20,"az":262,"ss":32,"used":true},{"PRN":10,"el":16,"az":194,"ss":24,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":21,"used":true},{"PRN":19,"el":5,"az":14,"ss":26,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":8,"used":false},{"PRN":27,"el":41,"az":264,"ss":24,"used":true},{"PRN":28,"el":58,"az":81,"ss":24,"used":true}]} +$GPGLL,5405.6077,N,01049.4916,E,104727.000,A,A*5A +{"class":"TPV","tag":"GLL","time":1248432447.000,"ept":0.005,"lat":54.093461667,"lon":10.824860000,"alt":35.100,"epx":8.042,"epy":9.278,"epv":29.976,"track":28.3000,"speed":0.412,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104728.000,A,5405.6078,N,01049.4918,E,0.56,28.66,240709,,,A*52 +$GPVTG,28.66,T,,M,0.56,N,1.0,K,A*35 +$GPGGA,104728.000,5405.6078,N,01049.4918,E,1,08,0.9,34.9,M,43.6,M,,0000*6F +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,32,10,16,194,25,15,74,263,44*70 +$GPGSV,3,2,12,17,14,127,,18,22,315,21,19,05,014,27,21,00,284,*71 +$GPGSV,3,3,12,22,00,337,,26,03,304,09,27,41,265,24,28,58,081,22*7D +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":22,"used":true},{"PRN":9,"el":20,"az":262,"ss":32,"used":true},{"PRN":10,"el":16,"az":194,"ss":25,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":21,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":9,"used":false},{"PRN":27,"el":41,"az":265,"ss":24,"used":true},{"PRN":28,"el":58,"az":81,"ss":22,"used":true}]} +$GPGLL,5405.6078,N,01049.4918,E,104728.000,A,A*54 +{"class":"TPV","tag":"GLL","time":1248432448.000,"ept":0.005,"lat":54.093463333,"lon":10.824863333,"alt":34.900,"epx":8.042,"epy":9.278,"epv":29.976,"track":28.6600,"speed":0.288,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104729.000,A,5405.6076,N,01049.4921,E,0.51,34.94,240709,,,A*50 +$GPVTG,34.94,T,,M,0.51,N,0.9,K,A*3A +$GPGGA,104729.000,5405.6076,N,01049.4921,E,1,08,0.9,34.7,M,43.6,M,,0000*64 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,32,10,16,194,24,15,74,263,44*71 +$GPGSV,3,2,12,17,14,127,,18,22,315,22,19,05,014,27,21,00,284,*72 +$GPGSV,3,3,12,22,00,337,,26,03,304,08,27,41,265,25,28,58,081,22*7D +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":22,"used":true},{"PRN":9,"el":20,"az":262,"ss":32,"used":true},{"PRN":10,"el":16,"az":194,"ss":24,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":0,"used":false},{"PRN":18,"el":22,"az":315,"ss":22,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":8,"used":false},{"PRN":27,"el":41,"az":265,"ss":25,"used":true},{"PRN":28,"el":58,"az":81,"ss":22,"used":true}]} +$GPGLL,5405.6076,N,01049.4921,E,104729.000,A,A*51 +{"class":"TPV","tag":"GLL","time":1248432449.000,"ept":0.005,"lat":54.093460000,"lon":10.824868333,"alt":34.700,"epx":8.042,"epy":9.278,"epv":29.976,"track":34.9400,"speed":0.262,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104730.000,A,5405.6073,N,01049.4922,E,1.07,44.97,240709,,,A*58 +$GPVTG,44.97,T,,M,1.07,N,2.0,K,A*37 +$GPGGA,104730.000,5405.6073,N,01049.4922,E,1,08,0.9,34.5,M,43.6,M,,0000*68 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,33,10,16,194,23,15,74,263,44*76 +$GPGSV,3,2,12,17,14,127,18,18,22,315,22,19,05,014,27,21,00,284,*7B +$GPGSV,3,3,12,22,00,337,,26,03,304,08,27,41,265,25,28,58,081,21*7E +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":23,"used":true},{"PRN":9,"el":20,"az":262,"ss":33,"used":true},{"PRN":10,"el":16,"az":194,"ss":23,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":18,"used":false},{"PRN":18,"el":22,"az":315,"ss":22,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":8,"used":false},{"PRN":27,"el":41,"az":265,"ss":25,"used":true},{"PRN":28,"el":58,"az":81,"ss":21,"used":true}]} +$GPGLL,5405.6073,N,01049.4922,E,104730.000,A,A*5F +{"class":"TPV","tag":"GLL","time":1248432450.000,"ept":0.005,"lat":54.093455000,"lon":10.824870000,"alt":34.500,"epx":8.042,"epy":9.278,"epv":29.976,"track":44.9700,"speed":0.550,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104731.000,A,5405.6070,N,01049.4926,E,0.67,50.17,240709,,,A*54 +$GPVTG,50.17,T,,M,0.67,N,1.3,K,A*3D +$GPGGA,104731.000,5405.6070,N,01049.4926,E,1,08,0.9,34.4,M,43.6,M,,0000*6F +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,21,09,20,262,33,10,16,194,23,15,74,263,44*74 +$GPGSV,3,2,12,17,14,127,17,18,22,315,22,19,05,014,27,21,00,284,*74 +$GPGSV,3,3,12,22,00,337,,26,03,304,08,27,41,265,26,28,58,081,22*7E +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":21,"used":true},{"PRN":9,"el":20,"az":262,"ss":33,"used":true},{"PRN":10,"el":16,"az":194,"ss":23,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":17,"used":false},{"PRN":18,"el":22,"az":315,"ss":22,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":8,"used":false},{"PRN":27,"el":41,"az":265,"ss":26,"used":true},{"PRN":28,"el":58,"az":81,"ss":22,"used":true}]} +$GPGLL,5405.6070,N,01049.4926,E,104731.000,A,A*59 +{"class":"TPV","tag":"GLL","time":1248432451.000,"ept":0.005,"lat":54.093450000,"lon":10.824876667,"alt":34.400,"epx":8.042,"epy":9.278,"epv":29.976,"track":50.1700,"speed":0.345,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104732.000,A,5405.6071,N,01049.4925,E,0.71,43.34,240709,,,A*51 +$GPVTG,43.34,T,,M,0.71,N,1.3,K,A*39 +$GPGGA,104732.000,5405.6071,N,01049.4925,E,1,08,0.9,34.3,M,43.6,M,,0000*69 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,21,09,20,262,34,10,16,194,23,15,74,263,44*73 +$GPGSV,3,2,12,17,14,127,15,18,22,315,21,19,05,014,27,21,00,284,*75 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,265,25,28,58,081,23*74 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":21,"used":true},{"PRN":9,"el":20,"az":262,"ss":34,"used":true},{"PRN":10,"el":16,"az":194,"ss":23,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":15,"used":false},{"PRN":18,"el":22,"az":315,"ss":21,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":265,"ss":25,"used":true},{"PRN":28,"el":58,"az":81,"ss":23,"used":true}]} +$GPGLL,5405.6071,N,01049.4925,E,104732.000,A,A*58 +{"class":"TPV","tag":"GLL","time":1248432452.000,"ept":0.005,"lat":54.093451667,"lon":10.824875000,"alt":34.300,"epx":8.042,"epy":9.278,"epv":29.976,"track":43.3400,"speed":0.365,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104733.000,A,5405.6069,N,01049.4928,E,1.13,49.89,240709,,,A*5D +$GPVTG,49.89,T,,M,1.13,N,2.1,K,A*31 +$GPGGA,104733.000,5405.6069,N,01049.4928,E,1,08,0.9,34.1,M,43.6,M,,0000*6E +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,22,09,20,262,33,10,16,194,22,15,74,263,44*76 +$GPGSV,3,2,12,17,14,127,16,18,22,315,22,19,05,014,27,21,00,284,*75 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,265,24,28,58,081,24*72 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":22,"used":true},{"PRN":9,"el":20,"az":262,"ss":33,"used":true},{"PRN":10,"el":16,"az":194,"ss":22,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":16,"used":false},{"PRN":18,"el":22,"az":315,"ss":22,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":265,"ss":24,"used":true},{"PRN":28,"el":58,"az":81,"ss":24,"used":true}]} +$GPGLL,5405.6069,N,01049.4928,E,104733.000,A,A*5D +{"class":"TPV","tag":"GLL","time":1248432453.000,"ept":0.005,"lat":54.093448333,"lon":10.824880000,"alt":34.100,"epx":8.042,"epy":9.278,"epv":29.976,"track":49.8900,"speed":0.581,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104734.000,A,5405.6070,N,01049.4930,E,1.06,48.90,240709,,,A*56 +$GPVTG,48.90,T,,M,1.06,N,2.0,K,A*3D +$GPGGA,104734.000,5405.6070,N,01049.4930,E,1,08,0.9,34.0,M,43.6,M,,0000*69 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,34,10,16,194,23,15,74,263,44*71 +$GPGSV,3,2,12,17,14,127,17,18,22,315,22,19,05,014,27,21,00,284,*74 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,265,24,28,58,081,24*72 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":23,"used":true},{"PRN":9,"el":20,"az":262,"ss":34,"used":true},{"PRN":10,"el":16,"az":194,"ss":23,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":17,"used":false},{"PRN":18,"el":22,"az":315,"ss":22,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":265,"ss":24,"used":true},{"PRN":28,"el":58,"az":81,"ss":24,"used":true}]} +$GPGLL,5405.6070,N,01049.4930,E,104734.000,A,A*5B +{"class":"TPV","tag":"GLL","time":1248432454.000,"ept":0.005,"lat":54.093450000,"lon":10.824883333,"alt":34.000,"epx":8.042,"epy":9.278,"epv":29.976,"track":48.9000,"speed":0.545,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104735.000,A,5405.6071,N,01049.4935,E,0.96,50.63,240709,,,A*5E +$GPVTG,50.63,T,,M,0.96,N,1.8,K,A*3B +$GPGGA,104735.000,5405.6071,N,01049.4935,E,1,08,0.9,33.8,M,43.6,M,,0000*63 +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,33,10,16,194,23,15,74,263,44*76 +$GPGSV,3,2,12,17,14,127,16,18,22,315,22,19,05,014,27,21,00,284,*75 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,265,24,28,58,081,24*72 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":23,"used":true},{"PRN":9,"el":20,"az":262,"ss":33,"used":true},{"PRN":10,"el":16,"az":194,"ss":23,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":16,"used":false},{"PRN":18,"el":22,"az":315,"ss":22,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":265,"ss":24,"used":true},{"PRN":28,"el":58,"az":81,"ss":24,"used":true}]} +$GPGLL,5405.6071,N,01049.4935,E,104735.000,A,A*5E +{"class":"TPV","tag":"GLL","time":1248432455.000,"ept":0.005,"lat":54.093451667,"lon":10.824891667,"alt":33.800,"epx":8.042,"epy":9.278,"epv":29.976,"track":50.6300,"speed":0.494,"climb":0.000,"eps":18.56,"mode":3} +$GPRMC,104736.000,A,5405.6072,N,01049.4936,E,0.52,50.27,240709,,,A*55 +$GPVTG,50.27,T,,M,0.52,N,1.0,K,A*3B +$GPGGA,104736.000,5405.6072,N,01049.4936,E,1,08,0.9,33.7,M,43.6,M,,0000*6F +$GPGSA,A,3,28,18,27,19,08,09,10,15,,,,,1.6,0.9,1.3*34 +$GPGSV,3,1,12,08,30,075,23,09,20,262,33,10,16,194,24,15,74,263,44*71 +$GPGSV,3,2,12,17,14,127,16,18,22,315,21,19,05,014,27,21,00,284,*76 +$GPGSV,3,3,12,22,00,337,,26,03,304,,27,41,265,24,28,58,081,24*72 +{"class":"SKY","tag":"GSV","xdop":0.54,"ydop":0.62,"vdop":1.30,"tdop":0.59,"hdop":0.82,"gdop":1.65,"pdop":1.54,"satellites":[{"PRN":8,"el":30,"az":75,"ss":23,"used":true},{"PRN":9,"el":20,"az":262,"ss":33,"used":true},{"PRN":10,"el":16,"az":194,"ss":24,"used":true},{"PRN":15,"el":74,"az":263,"ss":44,"used":true},{"PRN":17,"el":14,"az":127,"ss":16,"used":false},{"PRN":18,"el":22,"az":315,"ss":21,"used":true},{"PRN":19,"el":5,"az":14,"ss":27,"used":true},{"PRN":21,"el":0,"az":284,"ss":0,"used":false},{"PRN":22,"el":0,"az":337,"ss":0,"used":false},{"PRN":26,"el":3,"az":304,"ss":0,"used":false},{"PRN":27,"el":41,"az":265,"ss":24,"used":true},{"PRN":28,"el":58,"az":81,"ss":24,"used":true}]} +$GPGLL,5405.6072,N,01049.4936,E,104736.000,A,A*5D +{"class":"TPV","tag":"GLL","time":1248432456.000,"ept":0.005,"lat":54.093453333,"lon":10.824893333,"alt":33.700,"epx":8.042,"epy":9.278,"epv":29.976,"track":50.2700,"speed":0.268,"climb":0.000,"eps":18.56,"mode":3} diff --git a/test/daemon/nokia-ld-4w.log b/test/daemon/nokia-ld-4w.log new file mode 100644 index 0000000..1db77cd --- /dev/null +++ b/test/daemon/nokia-ld-4w.log @@ -0,0 +1,189 @@ +# Name: Nokia LD-4W +# Chipset: SiRF-3 +# Description: Bletooth add-on for Nokia mobile phone +# Cycle time: 1s +# Submitted-by: jussi.kivilinna@mbnet.fi +# Date: 5 Dec 2009 +# Location: Oulu, FI, 65N 25E +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGGA,080315.000,6503.0241,N,02528.3627,E,1,07,1.2,9.9,M,21.6,M,,0000*58 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPGSV,3,1,11,29,65,214,25,30,52,154,23,31,45,272,32,02,41,068,*7A +$GPGSV,3,2,11,12,23,132,25,23,18,348,13,10,16,098,15,04,12,040,24*7E +$GPGSV,3,3,11,05,11,110,23,16,07,296,33,13,07,020,26*43 +$GPRMC,080315.000,A,6503.0241,N,02528.3627,E,0.95,25.69,051209,,,A*50 +$GPGGA,080316.000,6503.0241,N,02528.3625,E,1,07,1.2,10.4,M,21.6,M,,0000*6C +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080316.000,A,6503.0241,N,02528.3625,E,0.56,33.07,051209,,,A*51 +$GPGGA,080317.000,6503.0239,N,02528.3621,E,1,07,1.2,10.3,M,21.6,M,,0000*61 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080317.000,A,6503.0239,N,02528.3621,E,0.74,18.23,051209,,,A*54 +$GPGGA,080318.000,6503.0236,N,02528.3617,E,1,07,1.2,10.2,M,21.6,M,,0000*65 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080318.000,A,6503.0236,N,02528.3617,E,0.36,37.53,051209,,,A*5D +$GPGGA,080319.000,6503.0235,N,02528.3611,E,1,07,1.2,10.3,M,21.6,M,,0000*60 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080319.000,A,6503.0235,N,02528.3611,E,0.34,8.27,051209,,,A*64 +$GPGGA,080320.000,6503.0233,N,02528.3606,E,1,07,1.2,10.9,M,21.6,M,,0000*60 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPGSV,3,1,11,29,66,214,24,30,52,154,24,31,45,272,32,02,41,068,*7F +$GPGSV,3,2,11,12,23,132,26,23,18,348,16,10,16,098,,04,12,040,25*7D +$GPGSV,3,3,11,05,12,110,23,16,07,296,33,13,07,020,25*43 +$GPRMC,080320.000,A,6503.0233,N,02528.3606,E,0.11,349.73,051209,,,A*6E +$GPGGA,080321.000,6503.0229,N,02528.3601,E,1,07,1.2,10.2,M,21.6,M,,0000*66 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080321.000,A,6503.0229,N,02528.3601,E,0.17,185.36,051209,,,A*66 +$GPGGA,080322.000,6503.0225,N,02528.3596,E,1,07,1.2,9.1,M,21.6,M,,0000*5F +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080322.000,A,6503.0225,N,02528.3596,E,0.15,191.14,051209,,,A*63 +$GPGGA,080323.000,6503.0221,N,02528.3588,E,1,07,1.2,8.0,M,21.6,M,,0000*55 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080323.000,A,6503.0221,N,02528.3588,E,0.23,195.46,051209,,,A*6F +$GPGGA,080324.000,6503.0219,N,02528.3584,E,1,07,1.2,8.1,M,21.6,M,,0000*54 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080324.000,A,6503.0219,N,02528.3584,E,0.07,83.00,051209,,,A*5D +$GPGGA,080325.000,6503.0216,N,02528.3580,E,1,08,1.0,8.0,M,21.6,M,,0000*52 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPGSV,3,1,11,29,66,214,24,30,52,154,25,31,45,272,32,02,41,068,17*78 +$GPGSV,3,2,11,12,23,132,26,23,18,348,18,10,16,098,,04,12,040,25*73 +$GPGSV,3,3,11,05,12,110,23,16,07,296,32,13,07,020,25*42 +$GPRMC,080325.000,A,6503.0216,N,02528.3580,E,0.12,86.47,051209,,,A*55 +$GPGGA,080326.000,6503.0215,N,02528.3576,E,1,06,1.4,8.6,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPRMC,080326.000,A,6503.0215,N,02528.3576,E,0.06,1.14,051209,,,A*60 +$GPGGA,080327.000,6503.0214,N,02528.3571,E,1,08,1.0,8.9,M,21.6,M,,0000*55 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080327.000,A,6503.0214,N,02528.3571,E,0.32,1.13,051209,,,A*67 +$GPGGA,080328.000,6503.0211,N,02528.3568,E,1,08,1.0,7.5,M,21.6,M,,0000*54 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080328.000,A,6503.0211,N,02528.3568,E,0.19,97.48,051209,,,A*5D +$GPGGA,080329.000,6503.0208,N,02528.3565,E,1,08,1.0,6.8,M,21.6,M,,0000*5C +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080329.000,A,6503.0208,N,02528.3565,E,0.25,72.57,051209,,,A*53 +$GPGGA,080330.000,6503.0205,N,02528.3561,E,1,08,1.0,5.7,M,21.6,M,,0000*51 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPGSV,3,1,11,29,66,214,23,30,52,154,26,31,45,272,32,02,41,068,17*7C +$GPGSV,3,2,11,12,23,132,25,23,18,348,20,10,16,098,,04,12,040,25*7B +$GPGSV,3,3,11,05,12,110,24,16,07,296,32,13,07,020,23*43 +$GPRMC,080330.000,A,6503.0205,N,02528.3561,E,0.14,181.62,051209,,,A*6B +$GPGGA,080331.000,6503.0202,N,02528.3556,E,1,08,1.0,5.3,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080331.000,A,6503.0202,N,02528.3556,E,0.20,209.92,051209,,,A*62 +$GPGGA,080332.000,6503.0200,N,02528.3552,E,1,08,1.0,4.6,M,21.6,M,,0000*56 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080332.000,A,6503.0200,N,02528.3552,E,0.36,228.63,051209,,,A*6D +$GPGGA,080333.000,6503.0196,N,02528.3548,E,1,07,1.2,3.5,M,21.6,M,,0000*59 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080333.000,A,6503.0196,N,02528.3548,E,0.21,93.12,051209,,,A*59 +$GPGGA,080334.000,6503.0194,N,02528.3545,E,1,07,1.2,3.0,M,21.6,M,,0000*54 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080334.000,A,6503.0194,N,02528.3545,E,0.27,131.95,051209,,,A*61 +$GPGGA,080335.000,6503.0195,N,02528.3544,E,1,07,1.2,3.3,M,21.6,M,,0000*56 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPGSV,3,1,11,29,66,214,22,30,52,154,27,31,45,272,32,02,41,068,*7A +$GPGSV,3,2,11,12,23,132,18,23,18,348,21,10,16,098,,04,12,040,25*74 +$GPGSV,3,3,11,05,12,110,24,16,07,296,32,13,07,020,22*42 +$GPRMC,080335.000,A,6503.0195,N,02528.3544,E,0.28,93.31,051209,,,A*58 +$GPGGA,080336.000,6503.0192,N,02528.3542,E,1,07,1.2,2.1,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080336.000,A,6503.0192,N,02528.3542,E,0.31,109.65,051209,,,A*61 +$GPGGA,080337.000,6503.0193,N,02528.3539,E,1,06,1.7,2.0,M,21.6,M,,0000*5E +$GPGSA,A,3,29,30,23,04,31,16,,,,,,,3.3,1.7,2.8*36 +$GPRMC,080337.000,A,6503.0193,N,02528.3539,E,0.26,357.90,051209,,,A*68 +$GPGGA,080338.000,6503.0192,N,02528.3535,E,1,07,1.2,1.3,M,21.6,M,,0000*58 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080338.000,A,6503.0192,N,02528.3535,E,0.23,329.09,051209,,,A*66 +$GPGGA,080339.000,6503.0194,N,02528.3531,E,1,06,1.7,1.4,M,21.6,M,,0000*58 +$GPGSA,A,3,29,30,23,04,31,16,,,,,,,3.3,1.7,2.8*36 +$GPRMC,080339.000,A,6503.0194,N,02528.3531,E,0.29,324.54,051209,,,A*6A +$GPGGA,080340.000,6503.0196,N,02528.3527,E,1,06,1.7,1.7,M,21.6,M,,0000*50 +$GPGSA,A,3,29,30,23,04,31,16,,,,,,,3.3,1.7,2.8*36 +$GPGSV,3,1,11,29,66,214,21,30,52,154,28,31,45,272,31,02,41,068,*75 +$GPGSV,3,2,11,12,23,132,17,23,18,348,21,10,16,098,,04,12,040,25*7B +$GPGSV,3,3,11,05,12,110,23,16,07,296,31,13,07,020,22*46 +$GPRMC,080340.000,A,6503.0196,N,02528.3527,E,0.17,253.19,051209,,,A*64 +$GPGGA,080341.000,6503.0192,N,02528.3525,E,1,07,1.2,0.1,M,21.6,M,,0000*54 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080341.000,A,6503.0192,N,02528.3525,E,0.16,233.14,051209,,,A*69 +$GPGGA,080342.000,6503.0194,N,02528.3526,E,1,08,1.0,-0.9,M,21.6,M,,0000*7A +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080342.000,A,6503.0194,N,02528.3526,E,0.10,352.68,051209,,,A*64 +$GPGGA,080343.000,6503.0192,N,02528.3526,E,1,08,1.0,-2.0,M,21.6,M,,0000*76 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080343.000,A,6503.0192,N,02528.3526,E,0.17,125.18,051209,,,A*61 +$GPGGA,080344.000,6503.0194,N,02528.3524,E,1,08,1.0,-1.7,M,21.6,M,,0000*71 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080344.000,A,6503.0194,N,02528.3524,E,0.26,17.55,051209,,,A*59 +$GPGGA,080345.000,6503.0200,N,02528.3521,E,1,08,1.0,0.2,M,21.6,M,,0000*52 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPGSV,3,1,11,29,66,214,21,30,52,154,29,31,45,272,31,02,41,068,17*72 +$GPGSV,3,2,11,12,23,132,19,23,18,348,12,10,16,098,,04,12,040,25*75 +$GPGSV,3,3,11,05,12,110,22,16,07,296,31,13,07,020,21*44 +$GPRMC,080345.000,A,6503.0200,N,02528.3521,E,0.02,174.00,051209,,,A*61 +$GPGGA,080346.000,6503.0204,N,02528.3519,E,1,08,1.0,1.5,M,21.6,M,,0000*58 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080346.000,A,6503.0204,N,02528.3519,E,0.74,16.87,051209,,,A*56 +$GPGGA,080347.000,6503.0207,N,02528.3518,E,1,08,1.0,2.5,M,21.6,M,,0000*58 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080347.000,A,6503.0207,N,02528.3518,E,0.43,19.41,051209,,,A*54 +$GPGGA,080348.000,6503.0210,N,02528.3517,E,1,06,1.4,3.2,M,21.6,M,,0000*52 +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPRMC,080348.000,A,6503.0210,N,02528.3517,E,0.37,36.42,051209,,,A*5F +$GPGGA,080349.000,6503.0212,N,02528.3517,E,1,06,1.4,3.6,M,21.6,M,,0000*55 +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPRMC,080349.000,A,6503.0212,N,02528.3517,E,0.50,28.72,051209,,,A*51 +$GPGGA,080350.000,6503.0211,N,02528.3517,E,1,06,1.4,3.4,M,21.6,M,,0000*5C +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPGSV,3,1,12,29,66,213,20,30,52,154,29,31,45,271,30,02,41,068,16*74 +$GPGSV,3,2,12,12,23,132,21,23,18,348,,10,16,097,,04,12,040,25*71 +$GPGSV,3,3,12,05,12,110,22,16,07,296,31,13,07,020,20,21,00,196,*7B +$GPRMC,080350.000,A,6503.0211,N,02528.3517,E,0.15,309.98,051209,,,A*6F +$GPGGA,080351.000,6503.0211,N,02528.3515,E,1,07,1.2,3.8,M,21.6,M,,0000*54 +$GPGSA,A,3,29,12,30,04,31,02,16,,,,,,2.1,1.2,1.7*3C +$GPRMC,080351.000,A,6503.0211,N,02528.3515,E,0.03,195.01,051209,,,A*6C +$GPGGA,080352.000,6503.0210,N,02528.3519,E,1,07,1.2,3.1,M,21.6,M,,0000*53 +$GPGSA,A,3,29,12,30,04,31,02,16,,,,,,2.1,1.2,1.7*3C +$GPRMC,080352.000,A,6503.0210,N,02528.3519,E,0.17,300.87,051209,,,A*67 +$GPGGA,080353.000,6503.0211,N,02528.3521,E,1,07,1.2,3.8,M,21.6,M,,0000*51 +$GPGSA,A,3,29,12,30,04,31,02,16,,,,,,2.1,1.2,1.7*3C +$GPRMC,080353.000,A,6503.0211,N,02528.3521,E,0.05,235.43,051209,,,A*60 +$GPGGA,080354.000,6503.0205,N,02528.3519,E,1,08,1.0,2.1,M,21.6,M,,0000*5D +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080354.000,A,6503.0205,N,02528.3519,E,0.18,82.11,051209,,,A*5C +$GPGGA,080355.000,6503.0204,N,02528.3517,E,1,08,1.0,2.5,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPGSV,3,1,12,29,66,213,20,30,52,154,29,31,45,271,30,02,41,068,15*77 +$GPGSV,3,2,12,12,23,132,22,23,18,348,18,10,16,097,,04,12,040,25*7B +$GPGSV,3,3,12,05,12,110,12,16,07,296,30,13,07,020,19,21,00,196,*73 +$GPRMC,080355.000,A,6503.0204,N,02528.3517,E,0.14,17.41,051209,,,A*57 +$GPGGA,080356.000,6503.0205,N,02528.3514,E,1,08,1.0,3.5,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080356.000,A,6503.0205,N,02528.3514,E,0.26,318.83,051209,,,A*65 +$GPGGA,080357.000,6503.0206,N,02528.3510,E,1,08,1.0,4.3,M,21.6,M,,0000*50 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080357.000,A,6503.0206,N,02528.3510,E,0.22,274.62,051209,,,A*63 +$GPGGA,080358.000,6503.0202,N,02528.3508,E,1,08,1.0,2.6,M,21.6,M,,0000*51 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080358.000,A,6503.0202,N,02528.3508,E,0.29,327.42,051209,,,A*6F +$GPGGA,080359.000,6503.0200,N,02528.3505,E,1,08,1.0,2.3,M,21.6,M,,0000*5A +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080359.000,A,6503.0200,N,02528.3505,E,0.15,188.94,051209,,,A*62 +$GPGGA,080400.000,6503.0198,N,02528.3504,E,1,08,1.0,1.5,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPGSV,3,1,12,29,66,213,20,30,52,154,29,31,45,271,30,02,41,068,15*77 +$GPGSV,3,2,12,12,23,132,23,23,18,348,18,10,16,097,,04,12,040,25*7A +$GPGSV,3,3,12,05,12,110,15,16,07,296,30,13,07,020,18,21,00,196,*75 +$GPRMC,080400.000,A,6503.0198,N,02528.3504,E,0.40,159.57,051209,,,A*69 +$GPGGA,080401.000,6503.0194,N,02528.3504,E,1,08,1.0,-0.2,M,21.6,M,,0000*71 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080401.000,A,6503.0194,N,02528.3504,E,0.41,126.31,051209,,,A*6D +$GPGGA,080402.000,6503.0192,N,02528.3504,E,1,06,1.4,-1.4,M,21.6,M,,0000*79 +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPRMC,080402.000,A,6503.0192,N,02528.3504,E,0.14,155.29,051209,,,A*65 +$GPGGA,080403.000,6503.0185,N,02528.3502,E,1,06,1.4,-3.6,M,21.6,M,,0000*78 +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPRMC,080403.000,A,6503.0185,N,02528.3502,E,0.10,233.34,051209,,,A*6F + diff --git a/test/daemon/nokia-ld-4w.log.chk b/test/daemon/nokia-ld-4w.log.chk new file mode 100644 index 0000000..40cb598 --- /dev/null +++ b/test/daemon/nokia-ld-4w.log.chk @@ -0,0 +1,238 @@ +$GPGGA,080315.000,6503.0241,N,02528.3627,E,1,07,1.2,9.9,M,21.6,M,,0000*58 +{"class":"TPV","tag":"GGA","lat":65.050401667,"lon":25.472711667,"alt":9.900,"mode":3} +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +{"class":"TPV","tag":"GSA","lat":65.050401667,"lon":25.472711667,"alt":9.900,"epv":43.700,"mode":3} +$GPGSV,3,1,11,29,65,214,25,30,52,154,23,31,45,272,32,02,41,068,*7A +$GPGSV,3,2,11,12,23,132,25,23,18,348,13,10,16,098,15,04,12,040,24*7E +$GPGSV,3,3,11,05,11,110,23,16,07,296,33,13,07,020,26*43 +{"class":"SKY","tag":"GSV","xdop":0.89,"ydop":0.96,"vdop":2.26,"tdop":1.44,"hdop":1.31,"gdop":2.99,"pdop":2.61,"satellites":[{"PRN":29,"el":65,"az":214,"ss":25,"used":true},{"PRN":30,"el":52,"az":154,"ss":23,"used":true},{"PRN":31,"el":45,"az":272,"ss":32,"used":true},{"PRN":2,"el":41,"az":68,"ss":0,"used":false},{"PRN":12,"el":23,"az":132,"ss":25,"used":true},{"PRN":23,"el":18,"az":348,"ss":13,"used":true},{"PRN":10,"el":16,"az":98,"ss":15,"used":false},{"PRN":4,"el":12,"az":40,"ss":24,"used":true},{"PRN":5,"el":11,"az":110,"ss":23,"used":false},{"PRN":16,"el":7,"az":296,"ss":33,"used":true},{"PRN":13,"el":7,"az":20,"ss":26,"used":false}]} +$GPRMC,080315.000,A,6503.0241,N,02528.3627,E,0.95,25.69,051209,,,A*50 +{"class":"TPV","tag":"RMC","time":1260000195.000,"ept":0.005,"lat":65.050401667,"lon":25.472711667,"alt":9.900,"epx":13.383,"epy":14.464,"epv":43.700,"track":25.6900,"speed":0.489,"mode":3} +$GPGGA,080316.000,6503.0241,N,02528.3625,E,1,07,1.2,10.4,M,21.6,M,,0000*6C +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080316.000,A,6503.0241,N,02528.3625,E,0.56,33.07,051209,,,A*51 +{"class":"TPV","tag":"RMC","time":1260000196.000,"ept":0.005,"lat":65.050401667,"lon":25.472708333,"alt":10.400,"epx":13.383,"epy":14.464,"epv":51.970,"track":33.0700,"speed":0.288,"climb":0.500,"eps":28.93,"mode":3} +$GPGGA,080317.000,6503.0239,N,02528.3621,E,1,07,1.2,10.3,M,21.6,M,,0000*61 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080317.000,A,6503.0239,N,02528.3621,E,0.74,18.23,051209,,,A*54 +{"class":"TPV","tag":"RMC","time":1260000197.000,"ept":0.005,"lat":65.050398333,"lon":25.472701667,"alt":10.300,"epx":13.383,"epy":14.464,"epv":43.700,"track":18.2300,"speed":0.381,"climb":-0.100,"eps":28.93,"mode":3} +$GPGGA,080318.000,6503.0236,N,02528.3617,E,1,07,1.2,10.2,M,21.6,M,,0000*65 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080318.000,A,6503.0236,N,02528.3617,E,0.36,37.53,051209,,,A*5D +{"class":"TPV","tag":"RMC","time":1260000198.000,"ept":0.005,"lat":65.050393333,"lon":25.472695000,"alt":10.200,"epx":13.383,"epy":14.464,"epv":43.700,"track":37.5300,"speed":0.185,"climb":-0.100,"eps":28.93,"mode":3} +$GPGGA,080319.000,6503.0235,N,02528.3611,E,1,07,1.2,10.3,M,21.6,M,,0000*60 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080319.000,A,6503.0235,N,02528.3611,E,0.34,8.27,051209,,,A*64 +{"class":"TPV","tag":"RMC","time":1260000199.000,"ept":0.005,"lat":65.050391667,"lon":25.472685000,"alt":10.300,"epx":13.383,"epy":14.464,"epv":43.700,"track":8.2700,"speed":0.175,"climb":0.100,"eps":28.93,"mode":3} +$GPGGA,080320.000,6503.0233,N,02528.3606,E,1,07,1.2,10.9,M,21.6,M,,0000*60 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPGSV,3,1,11,29,66,214,24,30,52,154,24,31,45,272,32,02,41,068,*7F +$GPGSV,3,2,11,12,23,132,26,23,18,348,16,10,16,098,,04,12,040,25*7D +$GPGSV,3,3,11,05,12,110,23,16,07,296,33,13,07,020,25*43 +{"class":"SKY","tag":"GSV","xdop":0.89,"ydop":0.97,"vdop":2.24,"tdop":1.43,"hdop":1.32,"gdop":2.97,"pdop":2.60,"satellites":[{"PRN":29,"el":66,"az":214,"ss":24,"used":true},{"PRN":30,"el":52,"az":154,"ss":24,"used":true},{"PRN":31,"el":45,"az":272,"ss":32,"used":true},{"PRN":2,"el":41,"az":68,"ss":0,"used":false},{"PRN":12,"el":23,"az":132,"ss":26,"used":true},{"PRN":23,"el":18,"az":348,"ss":16,"used":true},{"PRN":10,"el":16,"az":98,"ss":0,"used":false},{"PRN":4,"el":12,"az":40,"ss":25,"used":true},{"PRN":5,"el":12,"az":110,"ss":23,"used":false},{"PRN":16,"el":7,"az":296,"ss":33,"used":true},{"PRN":13,"el":7,"az":20,"ss":25,"used":false}]} +$GPRMC,080320.000,A,6503.0233,N,02528.3606,E,0.11,349.73,051209,,,A*6E +{"class":"TPV","tag":"RMC","time":1260000200.000,"ept":0.005,"lat":65.050388333,"lon":25.472676667,"alt":10.900,"epx":13.383,"epy":14.464,"epv":43.700,"track":349.7300,"speed":0.057,"climb":0.600,"eps":28.93,"mode":3} +$GPGGA,080321.000,6503.0229,N,02528.3601,E,1,07,1.2,10.2,M,21.6,M,,0000*66 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080321.000,A,6503.0229,N,02528.3601,E,0.17,185.36,051209,,,A*66 +{"class":"TPV","tag":"RMC","time":1260000201.000,"ept":0.005,"lat":65.050381667,"lon":25.472668333,"alt":10.200,"epx":13.407,"epy":14.485,"epv":51.462,"track":185.3600,"speed":0.087,"climb":-0.700,"eps":28.95,"mode":3} +$GPGGA,080322.000,6503.0225,N,02528.3596,E,1,07,1.2,9.1,M,21.6,M,,0000*5F +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080322.000,A,6503.0225,N,02528.3596,E,0.15,191.14,051209,,,A*63 +{"class":"TPV","tag":"RMC","time":1260000202.000,"ept":0.005,"lat":65.050375000,"lon":25.472660000,"alt":9.100,"epx":13.407,"epy":14.485,"epv":43.700,"track":191.1400,"speed":0.077,"climb":-1.100,"eps":28.97,"mode":3} +$GPGGA,080323.000,6503.0221,N,02528.3588,E,1,07,1.2,8.0,M,21.6,M,,0000*55 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080323.000,A,6503.0221,N,02528.3588,E,0.23,195.46,051209,,,A*6F +{"class":"TPV","tag":"RMC","time":1260000203.000,"ept":0.005,"lat":65.050368333,"lon":25.472646667,"alt":8.000,"epx":13.407,"epy":14.485,"epv":43.700,"track":195.4600,"speed":0.118,"climb":-1.100,"eps":28.97,"mode":3} +$GPGGA,080324.000,6503.0219,N,02528.3584,E,1,07,1.2,8.1,M,21.6,M,,0000*54 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080324.000,A,6503.0219,N,02528.3584,E,0.07,83.00,051209,,,A*5D +{"class":"TPV","tag":"RMC","time":1260000204.000,"ept":0.005,"lat":65.050365000,"lon":25.472640000,"alt":8.100,"epx":13.407,"epy":14.485,"epv":43.700,"track":83.0000,"speed":0.036,"climb":0.100,"eps":28.97,"mode":3} +$GPGGA,080325.000,6503.0216,N,02528.3580,E,1,08,1.0,8.0,M,21.6,M,,0000*52 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPGSV,3,1,11,29,66,214,24,30,52,154,25,31,45,272,32,02,41,068,17*78 +$GPGSV,3,2,11,12,23,132,26,23,18,348,18,10,16,098,,04,12,040,25*73 +$GPGSV,3,3,11,05,12,110,23,16,07,296,32,13,07,020,25*42 +{"class":"SKY","tag":"GSV","xdop":0.87,"ydop":0.89,"vdop":2.22,"tdop":1.42,"hdop":1.25,"gdop":2.92,"pdop":2.55,"satellites":[{"PRN":29,"el":66,"az":214,"ss":24,"used":true},{"PRN":30,"el":52,"az":154,"ss":25,"used":true},{"PRN":31,"el":45,"az":272,"ss":32,"used":true},{"PRN":2,"el":41,"az":68,"ss":17,"used":true},{"PRN":12,"el":23,"az":132,"ss":26,"used":true},{"PRN":23,"el":18,"az":348,"ss":18,"used":true},{"PRN":10,"el":16,"az":98,"ss":0,"used":false},{"PRN":4,"el":12,"az":40,"ss":25,"used":true},{"PRN":5,"el":12,"az":110,"ss":23,"used":false},{"PRN":16,"el":7,"az":296,"ss":32,"used":true},{"PRN":13,"el":7,"az":20,"ss":25,"used":false}]} +$GPRMC,080325.000,A,6503.0216,N,02528.3580,E,0.12,86.47,051209,,,A*55 +{"class":"TPV","tag":"RMC","time":1260000205.000,"ept":0.005,"lat":65.050360000,"lon":25.472633333,"alt":8.000,"epx":13.407,"epy":14.485,"epv":43.700,"track":86.4700,"speed":0.062,"climb":-0.100,"eps":28.97,"mode":3} +$GPGGA,080326.000,6503.0215,N,02528.3576,E,1,06,1.4,8.6,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPRMC,080326.000,A,6503.0215,N,02528.3576,E,0.06,1.14,051209,,,A*60 +{"class":"TPV","tag":"RMC","time":1260000206.000,"ept":0.005,"lat":65.050358333,"lon":25.472626667,"alt":8.600,"epx":13.114,"epy":13.403,"epv":51.160,"track":1.1400,"speed":0.031,"climb":0.600,"eps":27.89,"mode":3} +$GPGGA,080327.000,6503.0214,N,02528.3571,E,1,08,1.0,8.9,M,21.6,M,,0000*55 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080327.000,A,6503.0214,N,02528.3571,E,0.32,1.13,051209,,,A*67 +{"class":"TPV","tag":"RMC","time":1260000207.000,"ept":0.005,"lat":65.050356667,"lon":25.472618333,"alt":8.900,"epx":13.114,"epy":13.403,"epv":43.700,"track":1.1300,"speed":0.165,"climb":0.300,"eps":26.81,"mode":3} +$GPGGA,080328.000,6503.0211,N,02528.3568,E,1,08,1.0,7.5,M,21.6,M,,0000*54 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080328.000,A,6503.0211,N,02528.3568,E,0.19,97.48,051209,,,A*5D +{"class":"TPV","tag":"RMC","time":1260000208.000,"ept":0.005,"lat":65.050351667,"lon":25.472613333,"alt":7.500,"epx":13.114,"epy":13.403,"epv":39.100,"track":97.4800,"speed":0.098,"climb":-1.400,"eps":26.81,"mode":3} +$GPGGA,080329.000,6503.0208,N,02528.3565,E,1,08,1.0,6.8,M,21.6,M,,0000*5C +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080329.000,A,6503.0208,N,02528.3565,E,0.25,72.57,051209,,,A*53 +{"class":"TPV","tag":"RMC","time":1260000209.000,"ept":0.005,"lat":65.050346667,"lon":25.472608333,"alt":6.800,"epx":13.114,"epy":13.403,"epv":39.100,"track":72.5700,"speed":0.129,"climb":-0.700,"eps":26.81,"mode":3} +$GPGGA,080330.000,6503.0205,N,02528.3561,E,1,08,1.0,5.7,M,21.6,M,,0000*51 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPGSV,3,1,11,29,66,214,23,30,52,154,26,31,45,272,32,02,41,068,17*7C +$GPGSV,3,2,11,12,23,132,25,23,18,348,20,10,16,098,,04,12,040,25*7B +$GPGSV,3,3,11,05,12,110,24,16,07,296,32,13,07,020,23*43 +{"class":"SKY","tag":"GSV","xdop":0.87,"ydop":0.89,"vdop":2.22,"tdop":1.42,"hdop":1.25,"gdop":2.92,"pdop":2.55,"satellites":[{"PRN":29,"el":66,"az":214,"ss":23,"used":true},{"PRN":30,"el":52,"az":154,"ss":26,"used":true},{"PRN":31,"el":45,"az":272,"ss":32,"used":true},{"PRN":2,"el":41,"az":68,"ss":17,"used":true},{"PRN":12,"el":23,"az":132,"ss":25,"used":true},{"PRN":23,"el":18,"az":348,"ss":20,"used":true},{"PRN":10,"el":16,"az":98,"ss":0,"used":false},{"PRN":4,"el":12,"az":40,"ss":25,"used":true},{"PRN":5,"el":12,"az":110,"ss":24,"used":false},{"PRN":16,"el":7,"az":296,"ss":32,"used":true},{"PRN":13,"el":7,"az":20,"ss":23,"used":false}]} +$GPRMC,080330.000,A,6503.0205,N,02528.3561,E,0.14,181.62,051209,,,A*6B +{"class":"TPV","tag":"RMC","time":1260000210.000,"ept":0.005,"lat":65.050341667,"lon":25.472601667,"alt":5.700,"epx":13.114,"epy":13.403,"epv":39.100,"track":181.6200,"speed":0.072,"climb":-1.100,"eps":26.81,"mode":3} +$GPGGA,080331.000,6503.0202,N,02528.3556,E,1,08,1.0,5.3,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080331.000,A,6503.0202,N,02528.3556,E,0.20,209.92,051209,,,A*62 +{"class":"TPV","tag":"RMC","time":1260000211.000,"ept":0.005,"lat":65.050336667,"lon":25.472593333,"alt":5.300,"epx":13.114,"epy":13.403,"epv":51.160,"track":209.9200,"speed":0.103,"climb":-0.400,"eps":26.81,"mode":3} +$GPGGA,080332.000,6503.0200,N,02528.3552,E,1,08,1.0,4.6,M,21.6,M,,0000*56 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080332.000,A,6503.0200,N,02528.3552,E,0.36,228.63,051209,,,A*6D +{"class":"TPV","tag":"RMC","time":1260000212.000,"ept":0.005,"lat":65.050333333,"lon":25.472586667,"alt":4.600,"epx":13.114,"epy":13.403,"epv":39.100,"track":228.6300,"speed":0.185,"climb":-0.700,"eps":26.81,"mode":3} +$GPGGA,080333.000,6503.0196,N,02528.3548,E,1,07,1.2,3.5,M,21.6,M,,0000*59 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080333.000,A,6503.0196,N,02528.3548,E,0.21,93.12,051209,,,A*59 +{"class":"TPV","tag":"RMC","time":1260000213.000,"ept":0.005,"lat":65.050326667,"lon":25.472580000,"alt":3.500,"epx":13.114,"epy":13.403,"epv":39.100,"track":93.1200,"speed":0.108,"climb":-1.100,"eps":26.81,"mode":3} +$GPGGA,080334.000,6503.0194,N,02528.3545,E,1,07,1.2,3.0,M,21.6,M,,0000*54 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080334.000,A,6503.0194,N,02528.3545,E,0.27,131.95,051209,,,A*61 +{"class":"TPV","tag":"RMC","time":1260000214.000,"ept":0.005,"lat":65.050323333,"lon":25.472575000,"alt":3.000,"epx":13.114,"epy":13.403,"epv":43.700,"track":131.9500,"speed":0.139,"climb":-0.500,"eps":26.81,"mode":3} +$GPGGA,080335.000,6503.0195,N,02528.3544,E,1,07,1.2,3.3,M,21.6,M,,0000*56 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPGSV,3,1,11,29,66,214,22,30,52,154,27,31,45,272,32,02,41,068,*7A +$GPGSV,3,2,11,12,23,132,18,23,18,348,21,10,16,098,,04,12,040,25*74 +$GPGSV,3,3,11,05,12,110,24,16,07,296,32,13,07,020,22*42 +{"class":"SKY","tag":"GSV","xdop":0.89,"ydop":0.97,"vdop":2.24,"tdop":1.43,"hdop":1.32,"gdop":2.97,"pdop":2.60,"satellites":[{"PRN":29,"el":66,"az":214,"ss":22,"used":true},{"PRN":30,"el":52,"az":154,"ss":27,"used":true},{"PRN":31,"el":45,"az":272,"ss":32,"used":true},{"PRN":2,"el":41,"az":68,"ss":0,"used":false},{"PRN":12,"el":23,"az":132,"ss":18,"used":true},{"PRN":23,"el":18,"az":348,"ss":21,"used":true},{"PRN":10,"el":16,"az":98,"ss":0,"used":false},{"PRN":4,"el":12,"az":40,"ss":25,"used":true},{"PRN":5,"el":12,"az":110,"ss":24,"used":false},{"PRN":16,"el":7,"az":296,"ss":32,"used":true},{"PRN":13,"el":7,"az":20,"ss":22,"used":false}]} +$GPRMC,080335.000,A,6503.0195,N,02528.3544,E,0.28,93.31,051209,,,A*58 +{"class":"TPV","tag":"RMC","time":1260000215.000,"ept":0.005,"lat":65.050325000,"lon":25.472573333,"alt":3.300,"epx":13.114,"epy":13.403,"epv":43.700,"track":93.3100,"speed":0.144,"climb":0.300,"eps":26.81,"mode":3} +$GPGGA,080336.000,6503.0192,N,02528.3542,E,1,07,1.2,2.1,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080336.000,A,6503.0192,N,02528.3542,E,0.31,109.65,051209,,,A*61 +{"class":"TPV","tag":"RMC","time":1260000216.000,"ept":0.005,"lat":65.050320000,"lon":25.472570000,"alt":2.100,"epx":13.407,"epy":14.485,"epv":51.462,"track":109.6500,"speed":0.159,"climb":-1.200,"eps":27.89,"mode":3} +$GPGGA,080337.000,6503.0193,N,02528.3539,E,1,06,1.7,2.0,M,21.6,M,,0000*5E +$GPGSA,A,3,29,30,23,04,31,16,,,,,,,3.3,1.7,2.8*36 +$GPRMC,080337.000,A,6503.0193,N,02528.3539,E,0.26,357.90,051209,,,A*68 +{"class":"TPV","tag":"RMC","time":1260000217.000,"ept":0.005,"lat":65.050321667,"lon":25.472565000,"alt":2.000,"epx":13.407,"epy":14.485,"epv":43.700,"track":357.9000,"speed":0.134,"climb":-0.100,"eps":28.97,"mode":3} +$GPGGA,080338.000,6503.0192,N,02528.3535,E,1,07,1.2,1.3,M,21.6,M,,0000*58 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080338.000,A,6503.0192,N,02528.3535,E,0.23,329.09,051209,,,A*66 +{"class":"TPV","tag":"RMC","time":1260000218.000,"ept":0.005,"lat":65.050320000,"lon":25.472558333,"alt":1.300,"epx":13.407,"epy":14.485,"epv":64.400,"track":329.0900,"speed":0.118,"climb":-0.700,"eps":28.97,"mode":3} +$GPGGA,080339.000,6503.0194,N,02528.3531,E,1,06,1.7,1.4,M,21.6,M,,0000*58 +$GPGSA,A,3,29,30,23,04,31,16,,,,,,,3.3,1.7,2.8*36 +$GPRMC,080339.000,A,6503.0194,N,02528.3531,E,0.29,324.54,051209,,,A*6A +{"class":"TPV","tag":"RMC","time":1260000219.000,"ept":0.005,"lat":65.050323333,"lon":25.472551667,"alt":1.400,"epx":13.407,"epy":14.485,"epv":43.700,"track":324.5400,"speed":0.149,"climb":0.100,"eps":28.97,"mode":3} +$GPGGA,080340.000,6503.0196,N,02528.3527,E,1,06,1.7,1.7,M,21.6,M,,0000*50 +$GPGSA,A,3,29,30,23,04,31,16,,,,,,,3.3,1.7,2.8*36 +$GPGSV,3,1,11,29,66,214,21,30,52,154,28,31,45,272,31,02,41,068,*75 +$GPGSV,3,2,11,12,23,132,17,23,18,348,21,10,16,098,,04,12,040,25*7B +$GPGSV,3,3,11,05,12,110,23,16,07,296,31,13,07,020,22*46 +{"class":"SKY","tag":"GSV","xdop":0.93,"ydop":0.98,"vdop":2.43,"tdop":1.59,"hdop":1.35,"gdop":3.20,"pdop":2.78,"satellites":[{"PRN":29,"el":66,"az":214,"ss":21,"used":true},{"PRN":30,"el":52,"az":154,"ss":28,"used":true},{"PRN":31,"el":45,"az":272,"ss":31,"used":true},{"PRN":2,"el":41,"az":68,"ss":0,"used":false},{"PRN":12,"el":23,"az":132,"ss":17,"used":false},{"PRN":23,"el":18,"az":348,"ss":21,"used":true},{"PRN":10,"el":16,"az":98,"ss":0,"used":false},{"PRN":4,"el":12,"az":40,"ss":25,"used":true},{"PRN":5,"el":12,"az":110,"ss":23,"used":false},{"PRN":16,"el":7,"az":296,"ss":31,"used":true},{"PRN":13,"el":7,"az":20,"ss":22,"used":false}]} +$GPRMC,080340.000,A,6503.0196,N,02528.3527,E,0.17,253.19,051209,,,A*64 +{"class":"TPV","tag":"RMC","time":1260000220.000,"ept":0.005,"lat":65.050326667,"lon":25.472545000,"alt":1.700,"epx":13.407,"epy":14.485,"epv":64.400,"track":253.1900,"speed":0.087,"climb":0.300,"eps":28.97,"mode":3} +$GPGGA,080341.000,6503.0192,N,02528.3525,E,1,07,1.2,0.1,M,21.6,M,,0000*54 +$GPGSA,A,3,29,12,30,23,04,31,16,,,,,,2.2,1.2,1.9*32 +$GPRMC,080341.000,A,6503.0192,N,02528.3525,E,0.16,233.14,051209,,,A*69 +{"class":"TPV","tag":"RMC","time":1260000221.000,"ept":0.005,"lat":65.050320000,"lon":25.472541667,"alt":0.100,"epx":13.935,"epy":14.650,"epv":55.925,"track":233.1400,"speed":0.082,"climb":-1.600,"eps":29.13,"mode":3} +$GPGGA,080342.000,6503.0194,N,02528.3526,E,1,08,1.0,-0.9,M,21.6,M,,0000*7A +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080342.000,A,6503.0194,N,02528.3526,E,0.10,352.68,051209,,,A*64 +{"class":"TPV","tag":"RMC","time":1260000222.000,"ept":0.005,"lat":65.050323333,"lon":25.472543333,"alt":-0.900,"epx":13.935,"epy":14.650,"epv":43.700,"track":352.6800,"speed":0.051,"climb":-1.000,"eps":29.30,"mode":3} +$GPGGA,080343.000,6503.0192,N,02528.3526,E,1,08,1.0,-2.0,M,21.6,M,,0000*76 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080343.000,A,6503.0192,N,02528.3526,E,0.17,125.18,051209,,,A*61 +{"class":"TPV","tag":"RMC","time":1260000223.000,"ept":0.005,"lat":65.050320000,"lon":25.472543333,"alt":-2.000,"epx":13.935,"epy":14.650,"epv":39.100,"track":125.1800,"speed":0.087,"climb":-1.100,"eps":29.30,"mode":3} +$GPGGA,080344.000,6503.0194,N,02528.3524,E,1,08,1.0,-1.7,M,21.6,M,,0000*71 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080344.000,A,6503.0194,N,02528.3524,E,0.26,17.55,051209,,,A*59 +{"class":"TPV","tag":"RMC","time":1260000224.000,"ept":0.005,"lat":65.050323333,"lon":25.472540000,"alt":-1.700,"epx":13.935,"epy":14.650,"epv":39.100,"track":17.5500,"speed":0.134,"climb":0.300,"eps":29.30,"mode":3} +$GPGGA,080345.000,6503.0200,N,02528.3521,E,1,08,1.0,0.2,M,21.6,M,,0000*52 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPGSV,3,1,11,29,66,214,21,30,52,154,29,31,45,272,31,02,41,068,17*72 +$GPGSV,3,2,11,12,23,132,19,23,18,348,12,10,16,098,,04,12,040,25*75 +$GPGSV,3,3,11,05,12,110,22,16,07,296,31,13,07,020,21*44 +{"class":"SKY","tag":"GSV","xdop":0.87,"ydop":0.89,"vdop":2.22,"tdop":1.42,"hdop":1.25,"gdop":2.92,"pdop":2.55,"satellites":[{"PRN":29,"el":66,"az":214,"ss":21,"used":true},{"PRN":30,"el":52,"az":154,"ss":29,"used":true},{"PRN":31,"el":45,"az":272,"ss":31,"used":true},{"PRN":2,"el":41,"az":68,"ss":17,"used":true},{"PRN":12,"el":23,"az":132,"ss":19,"used":true},{"PRN":23,"el":18,"az":348,"ss":12,"used":true},{"PRN":10,"el":16,"az":98,"ss":0,"used":false},{"PRN":4,"el":12,"az":40,"ss":25,"used":true},{"PRN":5,"el":12,"az":110,"ss":22,"used":false},{"PRN":16,"el":7,"az":296,"ss":31,"used":true},{"PRN":13,"el":7,"az":20,"ss":21,"used":false}]} +$GPRMC,080345.000,A,6503.0200,N,02528.3521,E,0.02,174.00,051209,,,A*61 +{"class":"TPV","tag":"RMC","time":1260000225.000,"ept":0.005,"lat":65.050333333,"lon":25.472535000,"alt":0.200,"epx":13.935,"epy":14.650,"epv":39.100,"track":174.0000,"speed":0.010,"climb":1.900,"eps":29.30,"mode":3} +$GPGGA,080346.000,6503.0204,N,02528.3519,E,1,08,1.0,1.5,M,21.6,M,,0000*58 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080346.000,A,6503.0204,N,02528.3519,E,0.74,16.87,051209,,,A*56 +{"class":"TPV","tag":"RMC","time":1260000226.000,"ept":0.005,"lat":65.050340000,"lon":25.472531667,"alt":1.500,"epx":13.114,"epy":13.403,"epv":51.160,"track":16.8700,"speed":0.381,"climb":1.300,"eps":28.05,"mode":3} +$GPGGA,080347.000,6503.0207,N,02528.3518,E,1,08,1.0,2.5,M,21.6,M,,0000*58 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080347.000,A,6503.0207,N,02528.3518,E,0.43,19.41,051209,,,A*54 +{"class":"TPV","tag":"RMC","time":1260000227.000,"ept":0.005,"lat":65.050345000,"lon":25.472530000,"alt":2.500,"epx":13.114,"epy":13.403,"epv":39.100,"track":19.4100,"speed":0.221,"climb":1.000,"eps":26.81,"mode":3} +$GPGGA,080348.000,6503.0210,N,02528.3517,E,1,06,1.4,3.2,M,21.6,M,,0000*52 +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPRMC,080348.000,A,6503.0210,N,02528.3517,E,0.37,36.42,051209,,,A*5F +{"class":"TPV","tag":"RMC","time":1260000228.000,"ept":0.005,"lat":65.050350000,"lon":25.472528333,"alt":3.200,"epx":13.114,"epy":13.403,"epv":39.100,"track":36.4200,"speed":0.190,"climb":0.700,"eps":26.81,"mode":3} +$GPGGA,080349.000,6503.0212,N,02528.3517,E,1,06,1.4,3.6,M,21.6,M,,0000*55 +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPRMC,080349.000,A,6503.0212,N,02528.3517,E,0.50,28.72,051209,,,A*51 +{"class":"TPV","tag":"RMC","time":1260000229.000,"ept":0.005,"lat":65.050353333,"lon":25.472528333,"alt":3.600,"epx":13.114,"epy":13.403,"epv":43.700,"track":28.7200,"speed":0.257,"climb":0.400,"eps":26.81,"mode":3} +$GPGGA,080350.000,6503.0211,N,02528.3517,E,1,06,1.4,3.4,M,21.6,M,,0000*5C +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPGSV,3,1,12,29,66,213,20,30,52,154,29,31,45,271,30,02,41,068,16*74 +$GPGSV,3,2,12,12,23,132,21,23,18,348,,10,16,097,,04,12,040,25*71 +$GPGSV,3,3,12,05,12,110,22,16,07,296,31,13,07,020,20,21,00,196,*7B +{"class":"SKY","tag":"GSV","xdop":0.93,"ydop":0.97,"vdop":2.43,"tdop":1.59,"hdop":1.34,"gdop":3.20,"pdop":2.78,"satellites":[{"PRN":29,"el":66,"az":213,"ss":20,"used":true},{"PRN":30,"el":52,"az":154,"ss":29,"used":true},{"PRN":31,"el":45,"az":271,"ss":30,"used":true},{"PRN":2,"el":41,"az":68,"ss":16,"used":false},{"PRN":12,"el":23,"az":132,"ss":21,"used":true},{"PRN":23,"el":18,"az":348,"ss":0,"used":false},{"PRN":10,"el":16,"az":97,"ss":0,"used":false},{"PRN":4,"el":12,"az":40,"ss":25,"used":true},{"PRN":5,"el":12,"az":110,"ss":22,"used":false},{"PRN":16,"el":7,"az":296,"ss":31,"used":true},{"PRN":13,"el":7,"az":20,"ss":20,"used":false},{"PRN":21,"el":0,"az":196,"ss":0,"used":false}]} +$GPRMC,080350.000,A,6503.0211,N,02528.3517,E,0.15,309.98,051209,,,A*6F +{"class":"TPV","tag":"RMC","time":1260000230.000,"ept":0.005,"lat":65.050351667,"lon":25.472528333,"alt":3.400,"epx":13.114,"epy":13.403,"epv":43.700,"track":309.9800,"speed":0.077,"climb":-0.200,"eps":26.81,"mode":3} +$GPGGA,080351.000,6503.0211,N,02528.3515,E,1,07,1.2,3.8,M,21.6,M,,0000*54 +$GPGSA,A,3,29,12,30,04,31,02,16,,,,,,2.1,1.2,1.7*3C +$GPRMC,080351.000,A,6503.0211,N,02528.3515,E,0.03,195.01,051209,,,A*6C +{"class":"TPV","tag":"RMC","time":1260000231.000,"ept":0.005,"lat":65.050351667,"lon":25.472525000,"alt":3.800,"epx":13.890,"epy":14.620,"epv":55.882,"track":195.0100,"speed":0.015,"climb":0.400,"eps":28.02,"mode":3} +$GPGGA,080352.000,6503.0210,N,02528.3519,E,1,07,1.2,3.1,M,21.6,M,,0000*53 +$GPGSA,A,3,29,12,30,04,31,02,16,,,,,,2.1,1.2,1.7*3C +$GPRMC,080352.000,A,6503.0210,N,02528.3519,E,0.17,300.87,051209,,,A*67 +{"class":"TPV","tag":"RMC","time":1260000232.000,"ept":0.005,"lat":65.050350000,"lon":25.472531667,"alt":3.100,"epx":13.890,"epy":14.620,"epv":39.100,"track":300.8700,"speed":0.087,"climb":-0.700,"eps":29.24,"mode":3} +$GPGGA,080353.000,6503.0211,N,02528.3521,E,1,07,1.2,3.8,M,21.6,M,,0000*51 +$GPGSA,A,3,29,12,30,04,31,02,16,,,,,,2.1,1.2,1.7*3C +$GPRMC,080353.000,A,6503.0211,N,02528.3521,E,0.05,235.43,051209,,,A*60 +{"class":"TPV","tag":"RMC","time":1260000233.000,"ept":0.005,"lat":65.050351667,"lon":25.472535000,"alt":3.800,"epx":13.890,"epy":14.620,"epv":39.100,"track":235.4300,"speed":0.026,"climb":0.700,"eps":29.24,"mode":3} +$GPGGA,080354.000,6503.0205,N,02528.3519,E,1,08,1.0,2.1,M,21.6,M,,0000*5D +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080354.000,A,6503.0205,N,02528.3519,E,0.18,82.11,051209,,,A*5C +{"class":"TPV","tag":"RMC","time":1260000234.000,"ept":0.005,"lat":65.050341667,"lon":25.472531667,"alt":2.100,"epx":13.890,"epy":14.620,"epv":39.100,"track":82.1100,"speed":0.093,"climb":-1.700,"eps":29.24,"mode":3} +$GPGGA,080355.000,6503.0204,N,02528.3517,E,1,08,1.0,2.5,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPGSV,3,1,12,29,66,213,20,30,52,154,29,31,45,271,30,02,41,068,15*77 +$GPGSV,3,2,12,12,23,132,22,23,18,348,18,10,16,097,,04,12,040,25*7B +$GPGSV,3,3,12,05,12,110,12,16,07,296,30,13,07,020,19,21,00,196,*73 +{"class":"SKY","tag":"GSV","xdop":0.87,"ydop":0.90,"vdop":2.23,"tdop":1.42,"hdop":1.25,"gdop":2.92,"pdop":2.55,"satellites":[{"PRN":29,"el":66,"az":213,"ss":20,"used":true},{"PRN":30,"el":52,"az":154,"ss":29,"used":true},{"PRN":31,"el":45,"az":271,"ss":30,"used":true},{"PRN":2,"el":41,"az":68,"ss":15,"used":true},{"PRN":12,"el":23,"az":132,"ss":22,"used":true},{"PRN":23,"el":18,"az":348,"ss":18,"used":true},{"PRN":10,"el":16,"az":97,"ss":0,"used":false},{"PRN":4,"el":12,"az":40,"ss":25,"used":true},{"PRN":5,"el":12,"az":110,"ss":12,"used":false},{"PRN":16,"el":7,"az":296,"ss":30,"used":true},{"PRN":13,"el":7,"az":20,"ss":19,"used":false},{"PRN":21,"el":0,"az":196,"ss":0,"used":false}]} +$GPRMC,080355.000,A,6503.0204,N,02528.3517,E,0.14,17.41,051209,,,A*57 +{"class":"TPV","tag":"RMC","time":1260000235.000,"ept":0.005,"lat":65.050340000,"lon":25.472528333,"alt":2.500,"epx":13.890,"epy":14.620,"epv":39.100,"track":17.4100,"speed":0.072,"climb":0.400,"eps":29.24,"mode":3} +$GPGGA,080356.000,6503.0205,N,02528.3514,E,1,08,1.0,3.5,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080356.000,A,6503.0205,N,02528.3514,E,0.26,318.83,051209,,,A*65 +{"class":"TPV","tag":"RMC","time":1260000236.000,"ept":0.005,"lat":65.050341667,"lon":25.472523333,"alt":3.500,"epx":13.052,"epy":13.425,"epv":51.227,"track":318.8300,"speed":0.134,"climb":1.000,"eps":28.04,"mode":3} +$GPGGA,080357.000,6503.0206,N,02528.3510,E,1,08,1.0,4.3,M,21.6,M,,0000*50 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080357.000,A,6503.0206,N,02528.3510,E,0.22,274.62,051209,,,A*63 +{"class":"TPV","tag":"RMC","time":1260000237.000,"ept":0.005,"lat":65.050343333,"lon":25.472516667,"alt":4.300,"epx":13.052,"epy":13.425,"epv":39.100,"track":274.6200,"speed":0.113,"climb":0.800,"eps":26.85,"mode":3} +$GPGGA,080358.000,6503.0202,N,02528.3508,E,1,08,1.0,2.6,M,21.6,M,,0000*51 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080358.000,A,6503.0202,N,02528.3508,E,0.29,327.42,051209,,,A*6F +{"class":"TPV","tag":"RMC","time":1260000238.000,"ept":0.005,"lat":65.050336667,"lon":25.472513333,"alt":2.600,"epx":13.052,"epy":13.425,"epv":39.100,"track":327.4200,"speed":0.149,"climb":-1.700,"eps":26.85,"mode":3} +$GPGGA,080359.000,6503.0200,N,02528.3505,E,1,08,1.0,2.3,M,21.6,M,,0000*5A +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080359.000,A,6503.0200,N,02528.3505,E,0.15,188.94,051209,,,A*62 +{"class":"TPV","tag":"RMC","time":1260000239.000,"ept":0.005,"lat":65.050333333,"lon":25.472508333,"alt":2.300,"epx":13.052,"epy":13.425,"epv":39.100,"track":188.9400,"speed":0.077,"climb":-0.300,"eps":26.85,"mode":3} +$GPGGA,080400.000,6503.0198,N,02528.3504,E,1,08,1.0,1.5,M,21.6,M,,0000*57 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPGSV,3,1,12,29,66,213,20,30,52,154,29,31,45,271,30,02,41,068,15*77 +$GPGSV,3,2,12,12,23,132,23,23,18,348,18,10,16,097,,04,12,040,25*7A +$GPGSV,3,3,12,05,12,110,15,16,07,296,30,13,07,020,18,21,00,196,*75 +{"class":"SKY","tag":"GSV","xdop":0.87,"ydop":0.90,"vdop":2.23,"tdop":1.42,"hdop":1.25,"gdop":2.92,"pdop":2.55,"satellites":[{"PRN":29,"el":66,"az":213,"ss":20,"used":true},{"PRN":30,"el":52,"az":154,"ss":29,"used":true},{"PRN":31,"el":45,"az":271,"ss":30,"used":true},{"PRN":2,"el":41,"az":68,"ss":15,"used":true},{"PRN":12,"el":23,"az":132,"ss":23,"used":true},{"PRN":23,"el":18,"az":348,"ss":18,"used":true},{"PRN":10,"el":16,"az":97,"ss":0,"used":false},{"PRN":4,"el":12,"az":40,"ss":25,"used":true},{"PRN":5,"el":12,"az":110,"ss":15,"used":false},{"PRN":16,"el":7,"az":296,"ss":30,"used":true},{"PRN":13,"el":7,"az":20,"ss":18,"used":false},{"PRN":21,"el":0,"az":196,"ss":0,"used":false}]} +$GPRMC,080400.000,A,6503.0198,N,02528.3504,E,0.40,159.57,051209,,,A*69 +{"class":"TPV","tag":"RMC","time":1260000240.000,"ept":0.005,"lat":65.050330000,"lon":25.472506667,"alt":1.500,"epx":13.052,"epy":13.425,"epv":39.100,"track":159.5700,"speed":0.206,"climb":-0.800,"eps":26.85,"mode":3} +$GPGGA,080401.000,6503.0194,N,02528.3504,E,1,08,1.0,-0.2,M,21.6,M,,0000*71 +$GPGSA,A,3,29,12,30,23,04,31,02,16,,,,,2.0,1.0,1.7*3E +$GPRMC,080401.000,A,6503.0194,N,02528.3504,E,0.41,126.31,051209,,,A*6D +{"class":"TPV","tag":"RMC","time":1260000241.000,"ept":0.005,"lat":65.050323333,"lon":25.472506667,"alt":-0.200,"epx":13.052,"epy":13.425,"epv":51.227,"track":126.3100,"speed":0.211,"climb":-1.700,"eps":26.85,"mode":3} +$GPGGA,080402.000,6503.0192,N,02528.3504,E,1,06,1.4,-1.4,M,21.6,M,,0000*79 +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPRMC,080402.000,A,6503.0192,N,02528.3504,E,0.14,155.29,051209,,,A*65 +{"class":"TPV","tag":"RMC","time":1260000242.000,"ept":0.005,"lat":65.050320000,"lon":25.472506667,"alt":-1.400,"epx":13.052,"epy":13.425,"epv":39.100,"track":155.2900,"speed":0.072,"climb":-1.200,"eps":26.85,"mode":3} +$GPGGA,080403.000,6503.0185,N,02528.3502,E,1,06,1.4,-3.6,M,21.6,M,,0000*78 +$GPGSA,A,3,29,12,30,04,31,16,,,,,,,2.4,1.4,1.9*33 +$GPRMC,080403.000,A,6503.0185,N,02528.3502,E,0.10,233.34,051209,,,A*6F +{"class":"TPV","tag":"RMC","time":1260000243.000,"ept":0.005,"lat":65.050308333,"lon":25.472503333,"alt":-3.600,"epx":13.052,"epy":13.425,"epv":43.700,"track":233.3400,"speed":0.051,"climb":-2.200,"eps":26.85,"mode":3} diff --git a/test/daemon/oncore.log b/test/daemon/oncore.log new file mode 100644 index 0000000..1665e86 --- /dev/null +++ b/test/daemon/oncore.log @@ -0,0 +1,53 @@ +# Name: Oncore GT+ +# Submitted-by: Wojciech Kazubski +# Date: 12 Apr 2005 +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGSV,3,1,09,02,33,299,27,04,43,242,26,08,12,202,,13,85,356,*70 +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,39,195,15,,,,,,,,,,,,*46 +$GPRMC,171244.00,A,5209.7838,N,02048.4818,E,0.6,71.0,080405,3.5,E*63 +$GPGGA,171245.00,5209.7838,N,02048.4819,E,1,03,5.3,76.6,M,36.5,M,,*5A +$GPGLL,5209.7838,N,02048.4819,E,171245.00,A*00 +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,27,04,43,242,26,08,12,202,,13,85,356,*70 +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,39,195,13,,,,,,,,,,,,*40 +$GPRMC,171245.00,A,5209.7838,N,02048.4819,E,0.3,41.9,080405,3.5,E*6C +$GPGGA,171246.00,5209.7839,N,02048.4824,E,1,03,5.3,76.6,M,36.5,M,,*56 +$GPGLL,5209.7839,N,02048.4824,E,171246.00,A*0C +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,27,04,43,242,26,08,12,202,,13,85,356,*70 +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,39,195,16,,,,,,,,,,,,*45 +$GPRMC,171246.00,A,5209.7839,N,02048.4824,E,0.5,75.4,080405,3.5,E*6C +$GPGGA,171247.00,5209.7838,N,02048.4821,E,1,03,5.3,76.6,M,36.5,M,,*53 +$GPGLL,5209.7838,N,02048.4821,E,171247.00,A*09 +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,28,04,43,242,26,08,12,202,,13,85,357,*7E +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,40,195,15,,,,,,,,,,,,*48 +$GPRMC,171247.00,A,5209.7838,N,02048.4821,E,0.5,269.3,080405,3.5,E*51 +$GPGGA,171248.00,5209.7839,N,02048.4824,E,1,03,5.3,76.6,M,36.5,M,,*58 +$GPGLL,5209.7839,N,02048.4824,E,171248.00,A*02 +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,28,04,43,242,25,08,12,202,,13,85,357,*7D +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,40,195,15,,,,,,,,,,,,*48 +$GPRMC,171248.00,A,5209.7839,N,02048.4824,E,0.2,0.0,080405,3.5,E*53 +$GPGGA,171249.00,5209.7839,N,02048.4827,E,1,03,5.3,76.6,M,36.5,M,,*5A +$GPGLL,5209.7839,N,02048.4827,E,171249.00,A*00 +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,27,04,43,242,26,08,12,202,,13,85,357,*71 +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,40,195,15,,,,,,,,,,,,*48 +$GPRMC,171249.00,A,5209.7839,N,02048.4827,E,0.3,80.9,080405,3.5,E*61 +$GPGGA,171250.00,5209.7839,N,02048.4829,E,1,03,5.3,76.6,M,36.5,M,,*5C +$GPGLL,5209.7839,N,02048.4829,E,171250.00,A*06 +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,28,04,43,242,26,08,12,202,,13,85,357,*7E +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,40,195,15,,,,,,,,,,,,*48 +$GPRMC,171250.00,A,5209.7839,N,02048.4829,E,0.3,77.8,080405,3.5,E*6E diff --git a/test/daemon/oncore.log.chk b/test/daemon/oncore.log.chk new file mode 100644 index 0000000..18853e3 --- /dev/null +++ b/test/daemon/oncore.log.chk @@ -0,0 +1,60 @@ +$GPGSV,3,1,09,02,33,299,27,04,43,242,26,08,12,202,,13,85,356,*70 +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,39,195,15,,,,,,,,,,,,*46 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":2,"el":33,"az":299,"ss":27,"used":false},{"PRN":4,"el":43,"az":242,"ss":26,"used":false},{"PRN":8,"el":12,"az":202,"ss":0,"used":false},{"PRN":13,"el":85,"az":356,"ss":0,"used":false},{"PRN":16,"el":22,"az":59,"ss":0,"used":false},{"PRN":20,"el":21,"az":131,"ss":0,"used":false},{"PRN":23,"el":54,"az":74,"ss":0,"used":false},{"PRN":24,"el":23,"az":195,"ss":0,"used":false},{"PRN":27,"el":39,"az":195,"ss":15,"used":false}]} +$GPRMC,171244.00,A,5209.7838,N,02048.4818,E,0.6,71.0,080405,3.5,E*63 +{"class":"TPV","tag":"RMC","time":1112980364.000,"ept":0.005,"lat":52.163063333,"lon":20.808030000,"track":71.0000,"speed":0.309,"mode":2} +$GPGGA,171245.00,5209.7838,N,02048.4819,E,1,03,5.3,76.6,M,36.5,M,,*5A +$GPGLL,5209.7838,N,02048.4819,E,171245.00,A*00 +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,27,04,43,242,26,08,12,202,,13,85,356,*70 +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,39,195,13,,,,,,,,,,,,*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":2,"el":33,"az":299,"ss":27,"used":true},{"PRN":4,"el":43,"az":242,"ss":26,"used":true},{"PRN":8,"el":12,"az":202,"ss":0,"used":false},{"PRN":13,"el":85,"az":356,"ss":0,"used":false},{"PRN":16,"el":22,"az":59,"ss":0,"used":false},{"PRN":20,"el":21,"az":131,"ss":0,"used":false},{"PRN":23,"el":54,"az":74,"ss":0,"used":false},{"PRN":24,"el":23,"az":195,"ss":0,"used":false},{"PRN":27,"el":39,"az":195,"ss":13,"used":true}]} +$GPRMC,171245.00,A,5209.7838,N,02048.4819,E,0.3,41.9,080405,3.5,E*6C +{"class":"TPV","tag":"RMC","time":1112980365.000,"ept":0.005,"lat":52.163063333,"lon":20.808031667,"alt":76.600,"epv":0.000,"track":41.9000,"speed":0.154,"climb":0.000,"mode":3} +$GPGGA,171246.00,5209.7839,N,02048.4824,E,1,03,5.3,76.6,M,36.5,M,,*56 +$GPGLL,5209.7839,N,02048.4824,E,171246.00,A*0C +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,27,04,43,242,26,08,12,202,,13,85,356,*70 +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,39,195,16,,,,,,,,,,,,*45 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":2,"el":33,"az":299,"ss":27,"used":true},{"PRN":4,"el":43,"az":242,"ss":26,"used":true},{"PRN":8,"el":12,"az":202,"ss":0,"used":false},{"PRN":13,"el":85,"az":356,"ss":0,"used":false},{"PRN":16,"el":22,"az":59,"ss":0,"used":false},{"PRN":20,"el":21,"az":131,"ss":0,"used":false},{"PRN":23,"el":54,"az":74,"ss":0,"used":false},{"PRN":24,"el":23,"az":195,"ss":0,"used":false},{"PRN":27,"el":39,"az":195,"ss":16,"used":true}]} +$GPRMC,171246.00,A,5209.7839,N,02048.4824,E,0.5,75.4,080405,3.5,E*6C +{"class":"TPV","tag":"RMC","time":1112980366.000,"ept":0.005,"lat":52.163065000,"lon":20.808040000,"alt":76.600,"epv":0.000,"track":75.4000,"speed":0.257,"climb":0.000,"mode":3} +$GPGGA,171247.00,5209.7838,N,02048.4821,E,1,03,5.3,76.6,M,36.5,M,,*53 +$GPGLL,5209.7838,N,02048.4821,E,171247.00,A*09 +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,28,04,43,242,26,08,12,202,,13,85,357,*7E +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,40,195,15,,,,,,,,,,,,*48 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":2,"el":33,"az":299,"ss":28,"used":true},{"PRN":4,"el":43,"az":242,"ss":26,"used":true},{"PRN":8,"el":12,"az":202,"ss":0,"used":false},{"PRN":13,"el":85,"az":357,"ss":0,"used":false},{"PRN":16,"el":22,"az":59,"ss":0,"used":false},{"PRN":20,"el":21,"az":131,"ss":0,"used":false},{"PRN":23,"el":54,"az":74,"ss":0,"used":false},{"PRN":24,"el":23,"az":195,"ss":0,"used":false},{"PRN":27,"el":40,"az":195,"ss":15,"used":true}]} +$GPRMC,171247.00,A,5209.7838,N,02048.4821,E,0.5,269.3,080405,3.5,E*51 +{"class":"TPV","tag":"RMC","time":1112980367.000,"ept":0.005,"lat":52.163063333,"lon":20.808035000,"alt":76.600,"epv":0.000,"track":269.3000,"speed":0.257,"climb":0.000,"mode":3} +$GPGGA,171248.00,5209.7839,N,02048.4824,E,1,03,5.3,76.6,M,36.5,M,,*58 +$GPGLL,5209.7839,N,02048.4824,E,171248.00,A*02 +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,28,04,43,242,25,08,12,202,,13,85,357,*7D +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,40,195,15,,,,,,,,,,,,*48 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":2,"el":33,"az":299,"ss":28,"used":true},{"PRN":4,"el":43,"az":242,"ss":25,"used":true},{"PRN":8,"el":12,"az":202,"ss":0,"used":false},{"PRN":13,"el":85,"az":357,"ss":0,"used":false},{"PRN":16,"el":22,"az":59,"ss":0,"used":false},{"PRN":20,"el":21,"az":131,"ss":0,"used":false},{"PRN":23,"el":54,"az":74,"ss":0,"used":false},{"PRN":24,"el":23,"az":195,"ss":0,"used":false},{"PRN":27,"el":40,"az":195,"ss":15,"used":true}]} +$GPRMC,171248.00,A,5209.7839,N,02048.4824,E,0.2,0.0,080405,3.5,E*53 +{"class":"TPV","tag":"RMC","time":1112980368.000,"ept":0.005,"lat":52.163065000,"lon":20.808040000,"alt":76.600,"epv":0.000,"track":0.0000,"speed":0.103,"climb":0.000,"mode":3} +$GPGGA,171249.00,5209.7839,N,02048.4827,E,1,03,5.3,76.6,M,36.5,M,,*5A +$GPGLL,5209.7839,N,02048.4827,E,171249.00,A*00 +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,27,04,43,242,26,08,12,202,,13,85,357,*71 +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,40,195,15,,,,,,,,,,,,*48 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":2,"el":33,"az":299,"ss":27,"used":true},{"PRN":4,"el":43,"az":242,"ss":26,"used":true},{"PRN":8,"el":12,"az":202,"ss":0,"used":false},{"PRN":13,"el":85,"az":357,"ss":0,"used":false},{"PRN":16,"el":22,"az":59,"ss":0,"used":false},{"PRN":20,"el":21,"az":131,"ss":0,"used":false},{"PRN":23,"el":54,"az":74,"ss":0,"used":false},{"PRN":24,"el":23,"az":195,"ss":0,"used":false},{"PRN":27,"el":40,"az":195,"ss":15,"used":true}]} +$GPRMC,171249.00,A,5209.7839,N,02048.4827,E,0.3,80.9,080405,3.5,E*61 +{"class":"TPV","tag":"RMC","time":1112980369.000,"ept":0.005,"lat":52.163065000,"lon":20.808045000,"alt":76.600,"epv":0.000,"track":80.9000,"speed":0.154,"climb":0.000,"mode":3} +$GPGGA,171250.00,5209.7839,N,02048.4829,E,1,03,5.3,76.6,M,36.5,M,,*5C +$GPGLL,5209.7839,N,02048.4829,E,171250.00,A*06 +$GPGSA,A,2,02,04,27,,,,,,,,,,,5.3,*36 +$GPGSV,3,1,09,02,33,299,28,04,43,242,26,08,12,202,,13,85,357,*7E +$GPGSV,3,2,09,16,22,059,,20,21,131,,23,54,074,,24,23,195,*71 +$GPGSV,3,3,09,27,40,195,15,,,,,,,,,,,,*48 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":2,"el":33,"az":299,"ss":28,"used":true},{"PRN":4,"el":43,"az":242,"ss":26,"used":true},{"PRN":8,"el":12,"az":202,"ss":0,"used":false},{"PRN":13,"el":85,"az":357,"ss":0,"used":false},{"PRN":16,"el":22,"az":59,"ss":0,"used":false},{"PRN":20,"el":21,"az":131,"ss":0,"used":false},{"PRN":23,"el":54,"az":74,"ss":0,"used":false},{"PRN":24,"el":23,"az":195,"ss":0,"used":false},{"PRN":27,"el":40,"az":195,"ss":15,"used":true}]} +$GPRMC,171250.00,A,5209.7839,N,02048.4829,E,0.3,77.8,080405,3.5,E*6E +{"class":"TPV","tag":"RMC","time":1112980370.000,"ept":0.005,"lat":52.163065000,"lon":20.808048333,"alt":76.600,"epv":0.000,"track":77.8000,"speed":0.154,"climb":0.000,"mode":3} diff --git a/test/daemon/pharos-360.log b/test/daemon/pharos-360.log new file mode 100644 index 0000000..ef7513f --- /dev/null +++ b/test/daemon/pharos-360.log @@ -0,0 +1,259 @@ +# Name: Pharos GPS-360 +# Chipset: Sirf-II +# Submitted-by: "Jeff Fisher" +# Date: 27 July 2006 +# Location: Regina, Saskatchewan, Canada, 50N104W +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021612.949,A,5029.3800,N,10441.0390,W,0.039560,189.06,280706,,*18 +$GPGGA,021613.949,5029.3800,N,10441.0389,W,1,04,12.5,572.4,M,-20.3,M,0.0,0000*7E +$GPGLL,5029.3800,N,10441.0389,W,021613.949,A*22 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021613.949,A,5029.3800,N,10441.0389,W,0.009850,267.99,280706,,*19 +$GPGGA,021614.949,5029.3800,N,10441.0388,W,1,04,12.5,572.3,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3800,N,10441.0388,W,021614.949,A*24 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,49,156,27,17,49,212,0,28,82,35,36,11,38,84,37*4A +$GPGSV,3,2,9,26,32,278,39,29,31,270,38,19,6,48,0,27,22,152,26*71 +$GPGSV,3,3,9,123,0,0,0*40 +$GPRMC,021614.949,A,5029.3800,N,10441.0388,W,0.016538,341.48,280706,,*1B +$GPGGA,021615.949,5029.3799,N,10441.0387,W,1,04,12.5,572.1,M,-20.3,M,0.0,0000*7C +$GPGLL,5029.3799,N,10441.0387,W,021615.949,A*25 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021615.949,A,5029.3799,N,10441.0387,W,0.024470,357.79,280706,,*13 +$GPGGA,021616.949,5029.3800,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7B +$GPGLL,5029.3800,N,10441.0387,W,021616.949,A*29 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021616.949,A,5029.3800,N,10441.0387,W,0.064679,355.50,280706,,*19 +$GPGGA,021617.949,5029.3800,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7A +$GPGLL,5029.3800,N,10441.0387,W,021617.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021617.949,A,5029.3800,N,10441.0387,W,0.081945,359.64,280706,,*18 +$GPGGA,021618.949,5029.3801,N,10441.0387,W,1,04,12.5,571.8,M,-20.3,M,0.0,0000*75 +$GPGLL,5029.3801,N,10441.0387,W,021618.949,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021618.949,A,5029.3801,N,10441.0387,W,0.123681,359.07,280706,,*1D +$GPGGA,021619.949,5029.3802,N,10441.0387,W,1,04,12.5,571.6,M,-20.3,M,0.0,0000*79 +$GPGLL,5029.3802,N,10441.0387,W,021619.949,A*24 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,25,17,50,212,0,28,82,37,36,11,38,84,36*42 +$GPGSV,3,2,9,26,32,277,39,29,31,270,38,19,6,48,0,27,22,152,20*78 +$GPGSV,3,3,9,123,0,0,0*40 +$GPRMC,021619.949,A,5029.3802,N,10441.0387,W,0.152675,359.28,280706,,*1F +$GPGGA,021620.949,5029.3803,N,10441.0387,W,1,04,12.5,571.7,M,-20.3,M,0.0,0000*73 +$GPGLL,5029.3803,N,10441.0387,W,021620.949,A*2F +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021620.949,A,5029.3803,N,10441.0387,W,0.149670,359.57,280706,,*13 +$GPGGA,021621.949,5029.3805,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7A +$GPGLL,5029.3805,N,10441.0387,W,021621.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021621.949,A,5029.3805,N,10441.0387,W,0.139805,358.04,280706,,*18 +$GPGGA,021622.949,5029.3806,N,10441.0387,W,1,04,12.5,571.7,M,-20.3,M,0.0,0000*74 +$GPGLL,5029.3806,N,10441.0387,W,021622.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021622.949,A,5029.3806,N,10441.0387,W,0.159851,358.60,280706,,*1D +$GPGGA,021623.949,5029.3808,N,10441.0387,W,1,04,12.5,571.2,M,-20.3,M,0.0,0000*7E +$GPGLL,5029.3808,N,10441.0387,W,021623.949,A*27 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021623.949,A,5029.3808,N,10441.0387,W,0.211601,1.82,280706,,*15 +$GPGGA,021624.949,5029.3810,N,10441.0386,W,1,04,12.5,570.7,M,-20.3,M,0.0,0000*75 +$GPGLL,5029.3810,N,10441.0386,W,021624.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,25,17,50,212,0,28,82,37,37,11,38,84,37*42 +$GPGSV,3,2,9,26,32,277,39,29,31,270,38,19,6,48,0,27,22,152,21*79 +$GPGSV,3,3,9,123,0,0,0*40 +$GPRMC,021624.949,A,5029.3810,N,10441.0386,W,0.200234,356.84,280706,,*1F +$GPGGA,021625.949,5029.3812,N,10441.0386,W,1,04,12.5,570.1,M,-20.3,M,0.0,0000*70 +$GPGLL,5029.3812,N,10441.0386,W,021625.949,A*2B +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021625.949,A,5029.3812,N,10441.0386,W,0.222299,359.84,280706,,*14 +$GPGGA,021626.949,5029.3814,N,10441.0385,W,1,04,12.5,569.4,M,-20.3,M,0.0,0000*7B +$GPGLL,5029.3814,N,10441.0385,W,021626.949,A*2D +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021626.949,A,5029.3814,N,10441.0385,W,0.196906,0.09,280706,,*19 +$GPGGA,021627.948,5029.3815,N,10441.0384,W,1,04,12.5,568.8,M,-20.3,M,0.0,0000*76 +$GPGLL,5029.3815,N,10441.0384,W,021627.948,A*2D +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021627.948,A,5029.3815,N,10441.0384,W,0.200037,355.83,280706,,*1F +$GPGGA,021628.948,5029.3828,N,10441.0382,W,1,05,2.0,567.6,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3828,N,10441.0382,W,021628.948,A*2A +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021628.948,A,5029.3828,N,10441.0382,W,0.144151,5.63,280706,,*12 +$GPGGA,021629.948,5029.3826,N,10441.0381,W,1,05,2.0,567.0,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3826,N,10441.0381,W,021629.948,A*26 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,39,29,31,270,37,19,6,48,0,27,22,152,28*7F +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021629.948,A,5029.3826,N,10441.0381,W,0.066422,8.45,280706,,*17 +$GPGGA,021630.948,5029.3826,N,10441.0380,W,1,04,12.5,567.0,M,-20.3,M,0.0,0000*73 +$GPGLL,5029.3826,N,10441.0380,W,021630.948,A*2F +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021630.948,A,5029.3826,N,10441.0380,W,0.067726,5.22,280706,,*14 +$GPGGA,021631.948,5029.3826,N,10441.0377,W,1,04,12.5,567.2,M,-20.3,M,0.0,0000*78 +$GPGLL,5029.3826,N,10441.0377,W,021631.948,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021631.948,A,5029.3826,N,10441.0377,W,0.050347,4.93,280706,,*11 +$GPGGA,021632.948,5029.3826,N,10441.0370,W,1,05,2.0,567.2,M,-20.3,M,0.0,0000*49 +$GPGLL,5029.3826,N,10441.0370,W,021632.948,A*22 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021632.948,A,5029.3826,N,10441.0370,W,0.033580,1.77,280706,,*12 +$GPGGA,021633.948,5029.3826,N,10441.0370,W,1,04,12.5,566.9,M,-20.3,M,0.0,0000*77 +$GPGLL,5029.3826,N,10441.0370,W,021633.948,A*23 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021633.948,A,5029.3826,N,10441.0370,W,0.019509,345.64,280706,,*1B +$GPGGA,021634.948,5029.3825,N,10441.0370,W,1,04,12.5,566.7,M,-20.3,M,0.0,0000*7D +$GPGLL,5029.3825,N,10441.0370,W,021634.948,A*27 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,38,29,31,270,37,19,6,48,0,27,22,152,27*71 +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021634.948,A,5029.3825,N,10441.0370,W,0.003955,192.84,280706,,*17 +$GPGGA,021635.948,5029.3825,N,10441.0370,W,1,04,12.5,566.4,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3825,N,10441.0370,W,021635.948,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021635.948,A,5029.3825,N,10441.0370,W,0.095177,180.09,280706,,*17 +$GPGGA,021636.948,5029.3825,N,10441.0371,W,1,05,2.0,565.5,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3825,N,10441.0371,W,021636.948,A*24 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021636.948,A,5029.3825,N,10441.0371,W,0.023886,330.86,280706,,*11 +$GPGGA,021637.948,5029.3827,N,10441.0372,W,1,05,2.0,566.2,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3827,N,10441.0372,W,021637.948,A*24 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021637.948,A,5029.3827,N,10441.0372,W,0.061487,357.24,280706,,*13 +$GPGGA,021638.948,5029.3824,N,10441.0374,W,1,05,2.0,566.2,M,-20.3,M,0.0,0000*44 +$GPGLL,5029.3824,N,10441.0374,W,021638.948,A*2E +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021638.948,A,5029.3824,N,10441.0374,W,0.024092,262.30,280706,,*1A +$GPGGA,021639.948,5029.3825,N,10441.0375,W,1,05,2.0,565.6,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3825,N,10441.0375,W,021639.948,A*2F +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,38,29,31,270,36,19,6,48,0,27,22,152,28*7F +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021639.948,A,5029.3825,N,10441.0375,W,0.024297,20.59,280706,,*27 +$GPGGA,021640.948,5029.3825,N,10441.0376,W,1,04,12.5,565.3,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3825,N,10441.0376,W,021640.948,A*22 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021640.948,A,5029.3825,N,10441.0376,W,0.027357,327.53,280706,,*1A +$GPGGA,021641.948,5029.3825,N,10441.0376,W,1,04,12.5,565.0,M,-20.3,M,0.0,0000*7D +$GPGLL,5029.3825,N,10441.0376,W,021641.948,A*23 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021641.948,A,5029.3825,N,10441.0376,W,0.039535,27.78,280706,,*2C +$GPGGA,021642.948,5029.3829,N,10441.0379,W,1,05,2.0,564.7,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3829,N,10441.0379,W,021642.948,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021642.948,A,5029.3829,N,10441.0379,W,0.167129,0.94,280706,,*18 +$GPGGA,021643.947,5029.3837,N,10441.0381,W,1,05,2.0,563.6,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3837,N,10441.0381,W,021643.947,A*25 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021643.947,A,5029.3837,N,10441.0381,W,0.234120,354.99,280706,,*1D +$GPGGA,021644.947,5029.3844,N,10441.0383,W,1,05,2.0,562.5,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3844,N,10441.0383,W,021644.947,A*24 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,33,28,82,37,36,11,38,84,35*46 +$GPGSV,3,2,9,26,32,277,37,29,31,270,36,19,6,48,0,27,22,152,25*7D +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021644.947,A,5029.3844,N,10441.0383,W,0.225686,357.97,280706,,*1A +$GPGGA,021645.947,5029.3848,N,10441.0383,W,1,06,1.4,561.4,M,-20.3,M,0.0,0000*46 +$GPGLL,5029.3848,N,10441.0383,W,021645.947,A*29 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021645.947,A,5029.3848,N,10441.0383,W,0.073479,119.81,280706,,*1B +$GPGGA,021646.947,5029.3851,N,10441.0382,W,1,05,2.0,561.1,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3851,N,10441.0382,W,021646.947,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021646.947,A,5029.3851,N,10441.0382,W,0.079997,2.84,280706,,*18 +$GPGGA,021647.947,5029.3853,N,10441.0382,W,1,05,2.0,560.4,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3853,N,10441.0382,W,021647.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021647.947,A,5029.3853,N,10441.0382,W,0.134821,345.50,280706,,*16 +$GPGGA,021648.947,5029.3855,N,10441.0380,W,1,05,2.0,560.0,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3855,N,10441.0380,W,021648.947,A*2B +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021648.947,A,5029.3855,N,10441.0380,W,0.135447,3.49,280706,,*19 +$GPGGA,021649.947,5029.3856,N,10441.0379,W,1,05,2.0,559.3,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3856,N,10441.0379,W,021649.947,A*2F +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,34,28,82,39,35,11,38,84,33*4A +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,28*7A +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021649.947,A,5029.3856,N,10441.0379,W,0.118754,16.61,280706,,*2D +$GPGGA,021650.947,5029.3857,N,10441.0380,W,1,05,2.0,559.1,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3857,N,10441.0380,W,021650.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021650.947,A,5029.3857,N,10441.0380,W,0.122534,2.49,280706,,*10 +$GPGGA,021651.947,5029.3856,N,10441.0382,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3856,N,10441.0382,W,021651.947,A*22 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021651.947,A,5029.3856,N,10441.0382,W,0.117097,1.44,280706,,*16 +$GPGGA,021652.947,5029.3856,N,10441.0383,W,1,05,2.0,559.6,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3856,N,10441.0383,W,021652.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021652.947,A,5029.3856,N,10441.0383,W,0.110183,9.39,280706,,*15 +$GPGGA,021653.947,5029.3855,N,10441.0382,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*43 +$GPGLL,5029.3855,N,10441.0382,W,021653.947,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021653.947,A,5029.3855,N,10441.0382,W,0.104481,9.00,280706,,*1E +$GPGGA,021654.947,5029.3855,N,10441.0381,W,1,05,2.0,559.5,M,-20.3,M,0.0,0000*46 +$GPGLL,5029.3855,N,10441.0381,W,021654.947,A*27 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,34,28,82,39,36,11,38,84,33*49 +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,0*40 +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021654.947,A,5029.3855,N,10441.0381,W,0.142516,3.80,280706,,*15 +$GPGGA,021655.947,5029.3855,N,10441.0381,W,1,05,2.0,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0381,W,021655.947,A*26 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021655.947,A,5029.3855,N,10441.0381,W,0.120701,358.47,280706,,*12 +$GPGGA,021656.947,5029.3855,N,10441.0379,W,1,06,1.4,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0379,W,021656.947,A*22 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021656.947,A,5029.3855,N,10441.0379,W,0.094143,14.12,280706,,*23 +$GPGGA,021657.947,5029.3855,N,10441.0378,W,1,06,1.4,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0378,W,021657.947,A*22 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021657.947,A,5029.3855,N,10441.0378,W,0.096695,9.89,280706,,*13 +$GPGGA,021658.947,5029.3855,N,10441.0378,W,1,05,2.0,560.0,M,-20.3,M,0.0,0000*43 +$GPGLL,5029.3855,N,10441.0378,W,021658.947,A*2D +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021658.947,A,5029.3855,N,10441.0378,W,0.111024,0.77,280706,,*16 +$GPGGA,021659.946,5029.3855,N,10441.0376,W,1,05,2.0,559.8,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3855,N,10441.0376,W,021659.946,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,33,28,82,39,36,11,38,84,32*4F +$GPGSV,3,2,9,26,32,277,36,29,31,269,34,19,6,48,0,27,22,152,27*74 +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021659.946,A,5029.3855,N,10441.0376,W,0.144243,359.38,280706,,*1F +$GPGGA,021700.946,5029.3856,N,10441.0373,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3856,N,10441.0373,W,021700.946,A*28 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021700.946,A,5029.3856,N,10441.0373,W,0.127513,359.47,280706,,*1B +$GPGGA,021701.946,5029.3856,N,10441.0369,W,1,05,2.0,558.6,M,-20.3,M,0.0,0000*41 +$GPGLL,5029.3856,N,10441.0369,W,021701.946,A*22 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021701.946,A,5029.3856,N,10441.0369,W,0.082985,16.78,280706,,*28 +$GPGGA,021702.946,5029.3856,N,10441.0365,W,1,05,2.0,557.8,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3856,N,10441.0365,W,021702.946,A*2D +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021702.946,A,5029.3856,N,10441.0365,W,0.108057,8.59,280706,,*1E +$GPGGA,021703.946,5029.3857,N,10441.0363,W,1,05,2.0,556.8,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3857,N,10441.0363,W,021703.946,A*2B +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021703.946,A,5029.3857,N,10441.0363,W,0.193741,10.55,280706,,*2F +$GPGGA,021704.946,5029.3858,N,10441.0363,W,1,07,1.3,556.0,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3858,N,10441.0363,W,021704.946,A*23 +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A +$GPGSV,3,1,9,8,48,156,31,17,50,212,32,28,82,39,39,11,38,84,33*72 +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,30*73 +$GPGSV,3,3,9,124,0,0,0*47 +$GPRMC,021704.946,A,5029.3858,N,10441.0363,W,0.096613,335.19,280706,,*19 +$GPGGA,021705.946,5029.3859,N,10441.0363,W,1,07,1.3,555.4,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3859,N,10441.0363,W,021705.946,A*23 +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A +$GPRMC,021705.946,A,5029.3859,N,10441.0363,W,0.061763,22.98,280706,,*2B +$GPGGA,021706.946,5029.3860,N,10441.0364,W,1,07,1.3,554.9,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3860,N,10441.0364,W,021706.946,A*2D +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A diff --git a/test/daemon/pharos-360.log.chk b/test/daemon/pharos-360.log.chk new file mode 100644 index 0000000..67fe25c --- /dev/null +++ b/test/daemon/pharos-360.log.chk @@ -0,0 +1,316 @@ +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +{"class":"TPV","tag":"GSA","epv":71.300,"mode":3} +$GPRMC,021612.949,A,5029.3800,N,10441.0390,W,0.039560,189.06,280706,,*18 +{"class":"TPV","tag":"RMC","time":1154052972.949,"ept":0.005,"lat":50.489666667,"lon":-104.683983333,"track":189.0600,"speed":0.020,"mode":2} +$GPGGA,021613.949,5029.3800,N,10441.0389,W,1,04,12.5,572.4,M,-20.3,M,0.0,0000*7E +$GPGLL,5029.3800,N,10441.0389,W,021613.949,A*22 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021613.949,A,5029.3800,N,10441.0389,W,0.009850,267.99,280706,,*19 +{"class":"TPV","tag":"RMC","time":1154052973.949,"ept":0.005,"lat":50.489666667,"lon":-104.683981667,"alt":572.400,"epv":71.300,"track":267.9900,"speed":0.005,"climb":0.000,"mode":3} +$GPGGA,021614.949,5029.3800,N,10441.0388,W,1,04,12.5,572.3,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3800,N,10441.0388,W,021614.949,A*24 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,49,156,27,17,49,212,0,28,82,35,36,11,38,84,37*4A +$GPGSV,3,2,9,26,32,278,39,29,31,270,38,19,6,48,0,27,22,152,26*71 +$GPGSV,3,3,9,123,0,0,0*40 +{"class":"SKY","tag":"GSV","xdop":2.18,"ydop":2.31,"vdop":5.67,"tdop":5.16,"hdop":3.18,"gdop":8.30,"pdop":6.50,"satellites":[{"PRN":8,"el":49,"az":156,"ss":27,"used":false},{"PRN":17,"el":49,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":35,"ss":36,"used":true},{"PRN":11,"el":38,"az":84,"ss":37,"used":true},{"PRN":26,"el":32,"az":278,"ss":39,"used":true},{"PRN":29,"el":31,"az":270,"ss":38,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":26,"used":false},{"PRN":123,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021614.949,A,5029.3800,N,10441.0388,W,0.016538,341.48,280706,,*1B +{"class":"TPV","tag":"RMC","time":1154052974.949,"ept":0.005,"lat":50.489666667,"lon":-104.683980000,"alt":572.300,"epx":32.645,"epy":34.721,"epv":71.300,"track":341.4800,"speed":0.009,"climb":-0.100,"mode":3} +$GPGGA,021615.949,5029.3799,N,10441.0387,W,1,04,12.5,572.1,M,-20.3,M,0.0,0000*7C +$GPGLL,5029.3799,N,10441.0387,W,021615.949,A*25 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021615.949,A,5029.3799,N,10441.0387,W,0.024470,357.79,280706,,*13 +{"class":"TPV","tag":"RMC","time":1154052975.949,"ept":0.005,"lat":50.489665000,"lon":-104.683978333,"alt":572.100,"epx":32.645,"epy":34.721,"epv":130.377,"track":357.7900,"speed":0.013,"climb":-0.200,"eps":69.44,"mode":3} +$GPGGA,021616.949,5029.3800,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7B +$GPGLL,5029.3800,N,10441.0387,W,021616.949,A*29 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021616.949,A,5029.3800,N,10441.0387,W,0.064679,355.50,280706,,*19 +{"class":"TPV","tag":"RMC","time":1154052976.949,"ept":0.005,"lat":50.489666667,"lon":-104.683978333,"alt":571.900,"epx":32.645,"epy":34.721,"epv":71.300,"track":355.5000,"speed":0.033,"climb":-0.200,"eps":69.44,"mode":3} +$GPGGA,021617.949,5029.3800,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7A +$GPGLL,5029.3800,N,10441.0387,W,021617.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021617.949,A,5029.3800,N,10441.0387,W,0.081945,359.64,280706,,*18 +{"class":"TPV","tag":"RMC","time":1154052977.949,"ept":0.005,"lat":50.489666667,"lon":-104.683978333,"alt":571.900,"epx":32.645,"epy":34.721,"epv":71.300,"track":359.6400,"speed":0.042,"climb":0.000,"eps":69.44,"mode":3} +$GPGGA,021618.949,5029.3801,N,10441.0387,W,1,04,12.5,571.8,M,-20.3,M,0.0,0000*75 +$GPGLL,5029.3801,N,10441.0387,W,021618.949,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021618.949,A,5029.3801,N,10441.0387,W,0.123681,359.07,280706,,*1D +{"class":"TPV","tag":"RMC","time":1154052978.949,"ept":0.005,"lat":50.489668333,"lon":-104.683978333,"alt":571.800,"epx":32.645,"epy":34.721,"epv":71.300,"track":359.0700,"speed":0.064,"climb":-0.100,"eps":69.44,"mode":3} +$GPGGA,021619.949,5029.3802,N,10441.0387,W,1,04,12.5,571.6,M,-20.3,M,0.0,0000*79 +$GPGLL,5029.3802,N,10441.0387,W,021619.949,A*24 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,25,17,50,212,0,28,82,37,36,11,38,84,36*42 +$GPGSV,3,2,9,26,32,277,39,29,31,270,38,19,6,48,0,27,22,152,20*78 +$GPGSV,3,3,9,123,0,0,0*40 +{"class":"SKY","tag":"GSV","xdop":2.28,"ydop":2.35,"vdop":5.94,"tdop":5.42,"hdop":3.27,"gdop":8.68,"pdop":6.79,"satellites":[{"PRN":8,"el":48,"az":156,"ss":25,"used":false},{"PRN":17,"el":50,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":37,"ss":36,"used":true},{"PRN":11,"el":38,"az":84,"ss":36,"used":true},{"PRN":26,"el":32,"az":277,"ss":39,"used":true},{"PRN":29,"el":31,"az":270,"ss":38,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":20,"used":false},{"PRN":123,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021619.949,A,5029.3802,N,10441.0387,W,0.152675,359.28,280706,,*1F +{"class":"TPV","tag":"RMC","time":1154052979.949,"ept":0.005,"lat":50.489670000,"lon":-104.683978333,"alt":571.600,"epx":32.645,"epy":34.721,"epv":71.300,"track":359.2800,"speed":0.079,"climb":-0.200,"eps":69.44,"mode":3} +$GPGGA,021620.949,5029.3803,N,10441.0387,W,1,04,12.5,571.7,M,-20.3,M,0.0,0000*73 +$GPGLL,5029.3803,N,10441.0387,W,021620.949,A*2F +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021620.949,A,5029.3803,N,10441.0387,W,0.149670,359.57,280706,,*13 +{"class":"TPV","tag":"RMC","time":1154052980.949,"ept":0.005,"lat":50.489671667,"lon":-104.683978333,"alt":571.700,"epx":34.137,"epy":35.324,"epv":136.685,"track":359.5700,"speed":0.077,"climb":0.100,"eps":70.04,"mode":3} +$GPGGA,021621.949,5029.3805,N,10441.0387,W,1,04,12.5,571.9,M,-20.3,M,0.0,0000*7A +$GPGLL,5029.3805,N,10441.0387,W,021621.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021621.949,A,5029.3805,N,10441.0387,W,0.139805,358.04,280706,,*18 +{"class":"TPV","tag":"RMC","time":1154052981.949,"ept":0.005,"lat":50.489675000,"lon":-104.683978333,"alt":571.900,"epx":34.137,"epy":35.324,"epv":71.300,"track":358.0400,"speed":0.072,"climb":0.200,"eps":70.65,"mode":3} +$GPGGA,021622.949,5029.3806,N,10441.0387,W,1,04,12.5,571.7,M,-20.3,M,0.0,0000*74 +$GPGLL,5029.3806,N,10441.0387,W,021622.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021622.949,A,5029.3806,N,10441.0387,W,0.159851,358.60,280706,,*1D +{"class":"TPV","tag":"RMC","time":1154052982.949,"ept":0.005,"lat":50.489676667,"lon":-104.683978333,"alt":571.700,"epx":34.137,"epy":35.324,"epv":71.300,"track":358.6000,"speed":0.082,"climb":-0.200,"eps":70.65,"mode":3} +$GPGGA,021623.949,5029.3808,N,10441.0387,W,1,04,12.5,571.2,M,-20.3,M,0.0,0000*7E +$GPGLL,5029.3808,N,10441.0387,W,021623.949,A*27 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021623.949,A,5029.3808,N,10441.0387,W,0.211601,1.82,280706,,*15 +{"class":"TPV","tag":"RMC","time":1154052983.949,"ept":0.005,"lat":50.489680000,"lon":-104.683978333,"alt":571.200,"epx":34.137,"epy":35.324,"epv":71.300,"track":1.8200,"speed":0.109,"climb":-0.500,"eps":70.65,"mode":3} +$GPGGA,021624.949,5029.3810,N,10441.0386,W,1,04,12.5,570.7,M,-20.3,M,0.0,0000*75 +$GPGLL,5029.3810,N,10441.0386,W,021624.949,A*28 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,25,17,50,212,0,28,82,37,37,11,38,84,37*42 +$GPGSV,3,2,9,26,32,277,39,29,31,270,38,19,6,48,0,27,22,152,21*79 +$GPGSV,3,3,9,123,0,0,0*40 +{"class":"SKY","tag":"GSV","xdop":2.28,"ydop":2.35,"vdop":5.94,"tdop":5.42,"hdop":3.27,"gdop":8.68,"pdop":6.79,"satellites":[{"PRN":8,"el":48,"az":156,"ss":25,"used":false},{"PRN":17,"el":50,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":37,"ss":37,"used":true},{"PRN":11,"el":38,"az":84,"ss":37,"used":true},{"PRN":26,"el":32,"az":277,"ss":39,"used":true},{"PRN":29,"el":31,"az":270,"ss":38,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":21,"used":false},{"PRN":123,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021624.949,A,5029.3810,N,10441.0386,W,0.200234,356.84,280706,,*1F +{"class":"TPV","tag":"RMC","time":1154052984.949,"ept":0.005,"lat":50.489683333,"lon":-104.683976667,"alt":570.700,"epx":34.137,"epy":35.324,"epv":71.300,"track":356.8400,"speed":0.103,"climb":-0.500,"eps":70.65,"mode":3} +$GPGGA,021625.949,5029.3812,N,10441.0386,W,1,04,12.5,570.1,M,-20.3,M,0.0,0000*70 +$GPGLL,5029.3812,N,10441.0386,W,021625.949,A*2B +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021625.949,A,5029.3812,N,10441.0386,W,0.222299,359.84,280706,,*14 +{"class":"TPV","tag":"RMC","time":1154052985.949,"ept":0.005,"lat":50.489686667,"lon":-104.683976667,"alt":570.100,"epx":34.137,"epy":35.324,"epv":136.685,"track":359.8400,"speed":0.114,"climb":-0.600,"eps":70.65,"mode":3} +$GPGGA,021626.949,5029.3814,N,10441.0385,W,1,04,12.5,569.4,M,-20.3,M,0.0,0000*7B +$GPGLL,5029.3814,N,10441.0385,W,021626.949,A*2D +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021626.949,A,5029.3814,N,10441.0385,W,0.196906,0.09,280706,,*19 +{"class":"TPV","tag":"RMC","time":1154052986.949,"ept":0.005,"lat":50.489690000,"lon":-104.683975000,"alt":569.400,"epx":34.137,"epy":35.324,"epv":71.300,"track":0.0900,"speed":0.101,"climb":-0.700,"eps":70.65,"mode":3} +$GPGGA,021627.948,5029.3815,N,10441.0384,W,1,04,12.5,568.8,M,-20.3,M,0.0,0000*76 +$GPGLL,5029.3815,N,10441.0384,W,021627.948,A*2D +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021627.948,A,5029.3815,N,10441.0384,W,0.200037,355.83,280706,,*1F +{"class":"TPV","tag":"RMC","time":1154052987.948,"ept":0.005,"lat":50.489691667,"lon":-104.683973333,"alt":568.800,"epx":34.137,"epy":35.324,"epv":71.300,"track":355.8300,"speed":0.103,"climb":-0.601,"eps":70.72,"mode":3} +$GPGGA,021628.948,5029.3828,N,10441.0382,W,1,05,2.0,567.6,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3828,N,10441.0382,W,021628.948,A*2A +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021628.948,A,5029.3828,N,10441.0382,W,0.144151,5.63,280706,,*12 +{"class":"TPV","tag":"RMC","time":1154052988.948,"ept":0.005,"lat":50.489713333,"lon":-104.683970000,"alt":567.600,"epx":34.137,"epy":35.324,"epv":71.300,"track":5.6300,"speed":0.074,"climb":-1.200,"eps":70.65,"mode":3} +$GPGGA,021629.948,5029.3826,N,10441.0381,W,1,05,2.0,567.0,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3826,N,10441.0381,W,021629.948,A*26 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,39,29,31,270,37,19,6,48,0,27,22,152,28*7F +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.35,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":37,"ss":37,"used":true},{"PRN":11,"el":38,"az":84,"ss":36,"used":true},{"PRN":26,"el":32,"az":277,"ss":39,"used":true},{"PRN":29,"el":31,"az":270,"ss":37,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":28,"used":true},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021629.948,A,5029.3826,N,10441.0381,W,0.066422,8.45,280706,,*17 +{"class":"TPV","tag":"RMC","time":1154052989.948,"ept":0.005,"lat":50.489710000,"lon":-104.683968333,"alt":567.000,"epx":34.137,"epy":35.324,"epv":69.000,"track":8.4500,"speed":0.034,"climb":-0.600,"eps":70.65,"mode":3} +$GPGGA,021630.948,5029.3826,N,10441.0380,W,1,04,12.5,567.0,M,-20.3,M,0.0,0000*73 +$GPGLL,5029.3826,N,10441.0380,W,021630.948,A*2F +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021630.948,A,5029.3826,N,10441.0380,W,0.067726,5.22,280706,,*14 +{"class":"TPV","tag":"RMC","time":1154052990.948,"ept":0.005,"lat":50.489710000,"lon":-104.683966667,"alt":567.000,"epx":12.458,"epy":20.312,"epv":67.773,"track":5.2200,"speed":0.035,"climb":0.000,"eps":55.64,"mode":3} +$GPGGA,021631.948,5029.3826,N,10441.0377,W,1,04,12.5,567.2,M,-20.3,M,0.0,0000*78 +$GPGLL,5029.3826,N,10441.0377,W,021631.948,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021631.948,A,5029.3826,N,10441.0377,W,0.050347,4.93,280706,,*11 +{"class":"TPV","tag":"RMC","time":1154052991.948,"ept":0.005,"lat":50.489710000,"lon":-104.683961667,"alt":567.200,"epx":12.458,"epy":20.312,"epv":71.300,"track":4.9300,"speed":0.026,"climb":0.200,"eps":40.62,"mode":3} +$GPGGA,021632.948,5029.3826,N,10441.0370,W,1,05,2.0,567.2,M,-20.3,M,0.0,0000*49 +$GPGLL,5029.3826,N,10441.0370,W,021632.948,A*22 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021632.948,A,5029.3826,N,10441.0370,W,0.033580,1.77,280706,,*12 +{"class":"TPV","tag":"RMC","time":1154052992.948,"ept":0.005,"lat":50.489710000,"lon":-104.683950000,"alt":567.200,"epx":12.458,"epy":20.312,"epv":71.300,"track":1.7700,"speed":0.017,"climb":0.000,"eps":40.62,"mode":3} +$GPGGA,021633.948,5029.3826,N,10441.0370,W,1,04,12.5,566.9,M,-20.3,M,0.0,0000*77 +$GPGLL,5029.3826,N,10441.0370,W,021633.948,A*23 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021633.948,A,5029.3826,N,10441.0370,W,0.019509,345.64,280706,,*1B +{"class":"TPV","tag":"RMC","time":1154052993.948,"ept":0.005,"lat":50.489710000,"lon":-104.683950000,"alt":566.900,"epx":12.458,"epy":20.312,"epv":69.000,"track":345.6400,"speed":0.010,"climb":-0.300,"eps":40.62,"mode":3} +$GPGGA,021634.948,5029.3825,N,10441.0370,W,1,04,12.5,566.7,M,-20.3,M,0.0,0000*7D +$GPGLL,5029.3825,N,10441.0370,W,021634.948,A*27 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,38,29,31,270,37,19,6,48,0,27,22,152,27*71 +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":2.28,"ydop":2.35,"vdop":5.94,"tdop":5.42,"hdop":3.27,"gdop":8.68,"pdop":6.79,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":37,"ss":37,"used":true},{"PRN":11,"el":38,"az":84,"ss":36,"used":true},{"PRN":26,"el":32,"az":277,"ss":38,"used":true},{"PRN":29,"el":31,"az":270,"ss":37,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":27,"used":false},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021634.948,A,5029.3825,N,10441.0370,W,0.003955,192.84,280706,,*17 +{"class":"TPV","tag":"RMC","time":1154052994.948,"ept":0.005,"lat":50.489708333,"lon":-104.683950000,"alt":566.700,"epx":12.458,"epy":20.312,"epv":71.300,"track":192.8400,"speed":0.002,"climb":-0.200,"eps":40.62,"mode":3} +$GPGGA,021635.948,5029.3825,N,10441.0370,W,1,04,12.5,566.4,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3825,N,10441.0370,W,021635.948,A*26 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021635.948,A,5029.3825,N,10441.0370,W,0.095177,180.09,280706,,*17 +{"class":"TPV","tag":"RMC","time":1154052995.948,"ept":0.005,"lat":50.489708333,"lon":-104.683950000,"alt":566.400,"epx":34.137,"epy":35.324,"epv":136.685,"track":180.0900,"speed":0.049,"climb":-0.300,"eps":55.64,"mode":3} +$GPGGA,021636.948,5029.3825,N,10441.0371,W,1,05,2.0,565.5,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3825,N,10441.0371,W,021636.948,A*24 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021636.948,A,5029.3825,N,10441.0371,W,0.023886,330.86,280706,,*11 +{"class":"TPV","tag":"RMC","time":1154052996.948,"ept":0.005,"lat":50.489708333,"lon":-104.683951667,"alt":565.500,"epx":34.137,"epy":35.324,"epv":71.300,"track":330.8600,"speed":0.012,"climb":-0.900,"eps":70.65,"mode":3} +$GPGGA,021637.948,5029.3827,N,10441.0372,W,1,05,2.0,566.2,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3827,N,10441.0372,W,021637.948,A*24 +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021637.948,A,5029.3827,N,10441.0372,W,0.061487,357.24,280706,,*13 +{"class":"TPV","tag":"RMC","time":1154052997.948,"ept":0.005,"lat":50.489711667,"lon":-104.683953333,"alt":566.200,"epx":34.137,"epy":35.324,"epv":69.000,"track":357.2400,"speed":0.032,"climb":0.700,"eps":70.65,"mode":3} +$GPGGA,021638.948,5029.3824,N,10441.0374,W,1,05,2.0,566.2,M,-20.3,M,0.0,0000*44 +$GPGLL,5029.3824,N,10441.0374,W,021638.948,A*2E +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPRMC,021638.948,A,5029.3824,N,10441.0374,W,0.024092,262.30,280706,,*1A +{"class":"TPV","tag":"RMC","time":1154052998.948,"ept":0.005,"lat":50.489706667,"lon":-104.683956667,"alt":566.200,"epx":34.137,"epy":35.324,"epv":69.000,"track":262.3000,"speed":0.012,"climb":0.000,"eps":70.65,"mode":3} +$GPGGA,021639.948,5029.3825,N,10441.0375,W,1,05,2.0,565.6,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3825,N,10441.0375,W,021639.948,A*2F +$GPGSA,A,3,28,11,26,29,27,,,,,,,,3.6,2.0,3.0*36 +$GPGSV,3,1,9,8,48,156,0,17,50,212,0,28,82,37,37,11,38,84,36*74 +$GPGSV,3,2,9,26,32,277,38,29,31,270,36,19,6,48,0,27,22,152,28*7F +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.35,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":0,"used":false},{"PRN":28,"el":82,"az":37,"ss":37,"used":true},{"PRN":11,"el":38,"az":84,"ss":36,"used":true},{"PRN":26,"el":32,"az":277,"ss":38,"used":true},{"PRN":29,"el":31,"az":270,"ss":36,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":28,"used":true},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021639.948,A,5029.3825,N,10441.0375,W,0.024297,20.59,280706,,*27 +{"class":"TPV","tag":"RMC","time":1154052999.948,"ept":0.005,"lat":50.489708333,"lon":-104.683958333,"alt":565.600,"epx":34.137,"epy":35.324,"epv":69.000,"track":20.5900,"speed":0.012,"climb":-0.600,"eps":70.65,"mode":3} +$GPGGA,021640.948,5029.3825,N,10441.0376,W,1,04,12.5,565.3,M,-20.3,M,0.0,0000*7F +$GPGLL,5029.3825,N,10441.0376,W,021640.948,A*22 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021640.948,A,5029.3825,N,10441.0376,W,0.027357,327.53,280706,,*1A +{"class":"TPV","tag":"RMC","time":1154053000.948,"ept":0.005,"lat":50.489708333,"lon":-104.683960000,"alt":565.300,"epx":12.458,"epy":20.312,"epv":67.773,"track":327.5300,"speed":0.014,"climb":-0.300,"eps":55.64,"mode":3} +$GPGGA,021641.948,5029.3825,N,10441.0376,W,1,04,12.5,565.0,M,-20.3,M,0.0,0000*7D +$GPGLL,5029.3825,N,10441.0376,W,021641.948,A*23 +$GPGSA,A,3,28,11,26,29,,,,,,,,,12.9,12.5,3.1*39 +$GPRMC,021641.948,A,5029.3825,N,10441.0376,W,0.039535,27.78,280706,,*2C +{"class":"TPV","tag":"RMC","time":1154053001.948,"ept":0.005,"lat":50.489708333,"lon":-104.683960000,"alt":565.000,"epx":12.458,"epy":20.312,"epv":71.300,"track":27.7800,"speed":0.020,"climb":-0.300,"eps":40.62,"mode":3} +$GPGGA,021642.948,5029.3829,N,10441.0379,W,1,05,2.0,564.7,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3829,N,10441.0379,W,021642.948,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021642.948,A,5029.3829,N,10441.0379,W,0.167129,0.94,280706,,*18 +{"class":"TPV","tag":"RMC","time":1154053002.948,"ept":0.005,"lat":50.489715000,"lon":-104.683965000,"alt":564.700,"epx":12.458,"epy":20.312,"epv":71.300,"track":0.9400,"speed":0.086,"climb":-0.300,"eps":40.62,"mode":3} +$GPGGA,021643.947,5029.3837,N,10441.0381,W,1,05,2.0,563.6,M,-20.3,M,0.0,0000*4E +$GPGLL,5029.3837,N,10441.0381,W,021643.947,A*25 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021643.947,A,5029.3837,N,10441.0381,W,0.234120,354.99,280706,,*1D +{"class":"TPV","tag":"RMC","time":1154053003.947,"ept":0.005,"lat":50.489728333,"lon":-104.683968333,"alt":563.600,"epx":12.458,"epy":20.312,"epv":64.400,"track":354.9900,"speed":0.120,"climb":-1.101,"eps":40.66,"mode":3} +$GPGGA,021644.947,5029.3844,N,10441.0383,W,1,05,2.0,562.5,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3844,N,10441.0383,W,021644.947,A*24 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,33,28,82,37,36,11,38,84,35*46 +$GPGSV,3,2,9,26,32,277,37,29,31,270,36,19,6,48,0,27,22,152,25*7D +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.35,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":33,"used":true},{"PRN":28,"el":82,"az":37,"ss":36,"used":true},{"PRN":11,"el":38,"az":84,"ss":35,"used":true},{"PRN":26,"el":32,"az":277,"ss":37,"used":true},{"PRN":29,"el":31,"az":270,"ss":36,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":25,"used":false},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021644.947,A,5029.3844,N,10441.0383,W,0.225686,357.97,280706,,*1A +{"class":"TPV","tag":"RMC","time":1154053004.947,"ept":0.005,"lat":50.489740000,"lon":-104.683971667,"alt":562.500,"epx":12.458,"epy":20.312,"epv":64.400,"track":357.9700,"speed":0.116,"climb":-1.100,"eps":40.62,"mode":3} +$GPGGA,021645.947,5029.3848,N,10441.0383,W,1,06,1.4,561.4,M,-20.3,M,0.0,0000*46 +$GPGLL,5029.3848,N,10441.0383,W,021645.947,A*29 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021645.947,A,5029.3848,N,10441.0383,W,0.073479,119.81,280706,,*1B +{"class":"TPV","tag":"RMC","time":1154053005.947,"ept":0.005,"lat":50.489746667,"lon":-104.683971667,"alt":561.400,"epx":12.458,"epy":20.312,"epv":67.773,"track":119.8100,"speed":0.038,"climb":-1.100,"eps":40.62,"mode":3} +$GPGGA,021646.947,5029.3851,N,10441.0382,W,1,05,2.0,561.1,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3851,N,10441.0382,W,021646.947,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021646.947,A,5029.3851,N,10441.0382,W,0.079997,2.84,280706,,*18 +{"class":"TPV","tag":"RMC","time":1154053006.947,"ept":0.005,"lat":50.489751667,"lon":-104.683970000,"alt":561.100,"epx":12.458,"epy":20.312,"epv":52.900,"track":2.8400,"speed":0.041,"climb":-0.300,"eps":40.62,"mode":3} +$GPGGA,021647.947,5029.3853,N,10441.0382,W,1,05,2.0,560.4,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3853,N,10441.0382,W,021647.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021647.947,A,5029.3853,N,10441.0382,W,0.134821,345.50,280706,,*16 +{"class":"TPV","tag":"RMC","time":1154053007.947,"ept":0.005,"lat":50.489755000,"lon":-104.683970000,"alt":560.400,"epx":12.458,"epy":20.312,"epv":64.400,"track":345.5000,"speed":0.069,"climb":-0.700,"eps":40.62,"mode":3} +$GPGGA,021648.947,5029.3855,N,10441.0380,W,1,05,2.0,560.0,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3855,N,10441.0380,W,021648.947,A*2B +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021648.947,A,5029.3855,N,10441.0380,W,0.135447,3.49,280706,,*19 +{"class":"TPV","tag":"RMC","time":1154053008.947,"ept":0.005,"lat":50.489758333,"lon":-104.683966667,"alt":560.000,"epx":12.458,"epy":20.312,"epv":64.400,"track":3.4900,"speed":0.070,"climb":-0.400,"eps":40.62,"mode":3} +$GPGGA,021649.947,5029.3856,N,10441.0379,W,1,05,2.0,559.3,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3856,N,10441.0379,W,021649.947,A*2F +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,34,28,82,39,35,11,38,84,33*4A +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,28*7A +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.36,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":34,"used":true},{"PRN":28,"el":82,"az":39,"ss":35,"used":true},{"PRN":11,"el":38,"az":84,"ss":33,"used":true},{"PRN":26,"el":32,"az":277,"ss":37,"used":true},{"PRN":29,"el":31,"az":269,"ss":34,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":28,"used":false},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021649.947,A,5029.3856,N,10441.0379,W,0.118754,16.61,280706,,*2D +{"class":"TPV","tag":"RMC","time":1154053009.947,"ept":0.005,"lat":50.489760000,"lon":-104.683965000,"alt":559.300,"epx":12.458,"epy":20.312,"epv":64.400,"track":16.6100,"speed":0.061,"climb":-0.700,"eps":40.62,"mode":3} +$GPGGA,021650.947,5029.3857,N,10441.0380,W,1,05,2.0,559.1,M,-20.3,M,0.0,0000*45 +$GPGLL,5029.3857,N,10441.0380,W,021650.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021650.947,A,5029.3857,N,10441.0380,W,0.122534,2.49,280706,,*10 +{"class":"TPV","tag":"RMC","time":1154053010.947,"ept":0.005,"lat":50.489761667,"lon":-104.683966667,"alt":559.100,"epx":12.462,"epy":20.352,"epv":67.836,"track":2.4900,"speed":0.063,"climb":-0.200,"eps":40.66,"mode":3} +$GPGGA,021651.947,5029.3856,N,10441.0382,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3856,N,10441.0382,W,021651.947,A*22 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021651.947,A,5029.3856,N,10441.0382,W,0.117097,1.44,280706,,*16 +{"class":"TPV","tag":"RMC","time":1154053011.947,"ept":0.005,"lat":50.489760000,"lon":-104.683970000,"alt":559.400,"epx":12.462,"epy":20.352,"epv":64.400,"track":1.4400,"speed":0.060,"climb":0.300,"eps":40.70,"mode":3} +$GPGGA,021652.947,5029.3856,N,10441.0383,W,1,05,2.0,559.6,M,-20.3,M,0.0,0000*42 +$GPGLL,5029.3856,N,10441.0383,W,021652.947,A*20 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021652.947,A,5029.3856,N,10441.0383,W,0.110183,9.39,280706,,*15 +{"class":"TPV","tag":"RMC","time":1154053012.947,"ept":0.005,"lat":50.489760000,"lon":-104.683971667,"alt":559.600,"epx":12.462,"epy":20.352,"epv":64.400,"track":9.3900,"speed":0.057,"climb":0.200,"eps":40.70,"mode":3} +$GPGGA,021653.947,5029.3855,N,10441.0382,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*43 +$GPGLL,5029.3855,N,10441.0382,W,021653.947,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021653.947,A,5029.3855,N,10441.0382,W,0.104481,9.00,280706,,*1E +{"class":"TPV","tag":"RMC","time":1154053013.947,"ept":0.005,"lat":50.489758333,"lon":-104.683970000,"alt":559.400,"epx":12.462,"epy":20.352,"epv":64.400,"track":9.0000,"speed":0.054,"climb":-0.200,"eps":40.70,"mode":3} +$GPGGA,021654.947,5029.3855,N,10441.0381,W,1,05,2.0,559.5,M,-20.3,M,0.0,0000*46 +$GPGLL,5029.3855,N,10441.0381,W,021654.947,A*27 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,34,28,82,39,36,11,38,84,33*49 +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,0*40 +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.36,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":34,"used":true},{"PRN":28,"el":82,"az":39,"ss":36,"used":true},{"PRN":11,"el":38,"az":84,"ss":33,"used":true},{"PRN":26,"el":32,"az":277,"ss":37,"used":true},{"PRN":29,"el":31,"az":269,"ss":34,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":0,"used":false},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021654.947,A,5029.3855,N,10441.0381,W,0.142516,3.80,280706,,*15 +{"class":"TPV","tag":"RMC","time":1154053014.947,"ept":0.005,"lat":50.489758333,"lon":-104.683968333,"alt":559.500,"epx":12.462,"epy":20.352,"epv":64.400,"track":3.8000,"speed":0.073,"climb":0.100,"eps":40.70,"mode":3} +$GPGGA,021655.947,5029.3855,N,10441.0381,W,1,05,2.0,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0381,W,021655.947,A*26 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021655.947,A,5029.3855,N,10441.0381,W,0.120701,358.47,280706,,*12 +{"class":"TPV","tag":"RMC","time":1154053015.947,"ept":0.005,"lat":50.489758333,"lon":-104.683968333,"alt":559.800,"epx":12.462,"epy":20.352,"epv":67.836,"track":358.4700,"speed":0.062,"climb":0.300,"eps":40.70,"mode":3} +$GPGGA,021656.947,5029.3855,N,10441.0379,W,1,06,1.4,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0379,W,021656.947,A*22 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021656.947,A,5029.3855,N,10441.0379,W,0.094143,14.12,280706,,*23 +{"class":"TPV","tag":"RMC","time":1154053016.947,"ept":0.005,"lat":50.489758333,"lon":-104.683965000,"alt":559.800,"epx":12.462,"epy":20.352,"epv":64.400,"track":14.1200,"speed":0.048,"climb":0.000,"eps":40.70,"mode":3} +$GPGGA,021657.947,5029.3855,N,10441.0378,W,1,06,1.4,559.8,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3855,N,10441.0378,W,021657.947,A*22 +$GPGSA,A,3,17,28,11,26,29,27,,,,,,,2.7,1.4,2.3*35 +$GPRMC,021657.947,A,5029.3855,N,10441.0378,W,0.096695,9.89,280706,,*13 +{"class":"TPV","tag":"RMC","time":1154053017.947,"ept":0.005,"lat":50.489758333,"lon":-104.683963333,"alt":559.800,"epx":12.462,"epy":20.352,"epv":52.900,"track":9.8900,"speed":0.050,"climb":0.000,"eps":40.70,"mode":3} +$GPGGA,021658.947,5029.3855,N,10441.0378,W,1,05,2.0,560.0,M,-20.3,M,0.0,0000*43 +$GPGLL,5029.3855,N,10441.0378,W,021658.947,A*2D +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021658.947,A,5029.3855,N,10441.0378,W,0.111024,0.77,280706,,*16 +{"class":"TPV","tag":"RMC","time":1154053018.947,"ept":0.005,"lat":50.489758333,"lon":-104.683963333,"alt":560.000,"epx":12.462,"epy":20.352,"epv":52.900,"track":0.7700,"speed":0.057,"climb":0.200,"eps":40.70,"mode":3} +$GPGGA,021659.946,5029.3855,N,10441.0376,W,1,05,2.0,559.8,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3855,N,10441.0376,W,021659.946,A*23 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPGSV,3,1,9,8,48,156,0,17,50,212,33,28,82,39,36,11,38,84,32*4F +$GPGSV,3,2,9,26,32,277,36,29,31,269,34,19,6,48,0,27,22,152,27*74 +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.83,"ydop":1.36,"vdop":2.95,"tdop":2.18,"hdop":1.59,"gdop":4.00,"pdop":3.35,"satellites":[{"PRN":8,"el":48,"az":156,"ss":0,"used":false},{"PRN":17,"el":50,"az":212,"ss":33,"used":true},{"PRN":28,"el":82,"az":39,"ss":36,"used":true},{"PRN":11,"el":38,"az":84,"ss":32,"used":true},{"PRN":26,"el":32,"az":277,"ss":36,"used":true},{"PRN":29,"el":31,"az":269,"ss":34,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":27,"used":false},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021659.946,A,5029.3855,N,10441.0376,W,0.144243,359.38,280706,,*1F +{"class":"TPV","tag":"RMC","time":1154053019.946,"ept":0.005,"lat":50.489758333,"lon":-104.683960000,"alt":559.800,"epx":12.462,"epy":20.352,"epv":64.400,"track":359.3800,"speed":0.074,"climb":-0.200,"eps":40.74,"mode":3} +$GPGGA,021700.946,5029.3856,N,10441.0373,W,1,05,2.0,559.4,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3856,N,10441.0373,W,021700.946,A*28 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021700.946,A,5029.3856,N,10441.0373,W,0.127513,359.47,280706,,*1B +{"class":"TPV","tag":"RMC","time":1154053020.946,"ept":0.005,"lat":50.489760000,"lon":-104.683955000,"alt":559.400,"epx":12.462,"epy":20.352,"epv":67.836,"track":359.4700,"speed":0.066,"climb":-0.400,"eps":40.70,"mode":3} +$GPGGA,021701.946,5029.3856,N,10441.0369,W,1,05,2.0,558.6,M,-20.3,M,0.0,0000*41 +$GPGLL,5029.3856,N,10441.0369,W,021701.946,A*22 +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021701.946,A,5029.3856,N,10441.0369,W,0.082985,16.78,280706,,*28 +{"class":"TPV","tag":"RMC","time":1154053021.946,"ept":0.005,"lat":50.489760000,"lon":-104.683948333,"alt":558.600,"epx":12.462,"epy":20.352,"epv":64.400,"track":16.7800,"speed":0.043,"climb":-0.800,"eps":40.70,"mode":3} +$GPGGA,021702.946,5029.3856,N,10441.0365,W,1,05,2.0,557.8,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3856,N,10441.0365,W,021702.946,A*2D +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021702.946,A,5029.3856,N,10441.0365,W,0.108057,8.59,280706,,*1E +{"class":"TPV","tag":"RMC","time":1154053022.946,"ept":0.005,"lat":50.489760000,"lon":-104.683941667,"alt":557.800,"epx":12.462,"epy":20.352,"epv":64.400,"track":8.5900,"speed":0.056,"climb":-0.800,"eps":40.70,"mode":3} +$GPGGA,021703.946,5029.3857,N,10441.0363,W,1,05,2.0,556.8,M,-20.3,M,0.0,0000*48 +$GPGLL,5029.3857,N,10441.0363,W,021703.946,A*2B +$GPGSA,A,3,17,28,11,26,29,,,,,,,,3.5,2.0,2.8*3F +$GPRMC,021703.946,A,5029.3857,N,10441.0363,W,0.193741,10.55,280706,,*2F +{"class":"TPV","tag":"RMC","time":1154053023.946,"ept":0.005,"lat":50.489761667,"lon":-104.683938333,"alt":556.800,"epx":12.462,"epy":20.352,"epv":64.400,"track":10.5500,"speed":0.100,"climb":-1.000,"eps":40.70,"mode":3} +$GPGGA,021704.946,5029.3858,N,10441.0363,W,1,07,1.3,556.0,M,-20.3,M,0.0,0000*4A +$GPGLL,5029.3858,N,10441.0363,W,021704.946,A*23 +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A +$GPGSV,3,1,9,8,48,156,31,17,50,212,32,28,82,39,39,11,38,84,33*72 +$GPGSV,3,2,9,26,32,277,37,29,31,269,34,19,6,48,0,27,22,152,30*73 +$GPGSV,3,3,9,124,0,0,0*47 +{"class":"SKY","tag":"GSV","xdop":0.62,"ydop":1.27,"vdop":1.94,"tdop":1.22,"hdop":1.41,"gdop":2.69,"pdop":2.40,"satellites":[{"PRN":8,"el":48,"az":156,"ss":31,"used":true},{"PRN":17,"el":50,"az":212,"ss":32,"used":true},{"PRN":28,"el":82,"az":39,"ss":39,"used":true},{"PRN":11,"el":38,"az":84,"ss":33,"used":true},{"PRN":26,"el":32,"az":277,"ss":37,"used":true},{"PRN":29,"el":31,"az":269,"ss":34,"used":true},{"PRN":19,"el":6,"az":48,"ss":0,"used":false},{"PRN":27,"el":22,"az":152,"ss":30,"used":true},{"PRN":124,"el":0,"az":0,"ss":0,"used":false}]} +$GPRMC,021704.946,A,5029.3858,N,10441.0363,W,0.096613,335.19,280706,,*19 +{"class":"TPV","tag":"RMC","time":1154053024.946,"ept":0.005,"lat":50.489763333,"lon":-104.683938333,"alt":556.000,"epx":12.462,"epy":20.352,"epv":64.400,"track":335.1900,"speed":0.050,"climb":-0.800,"eps":40.70,"mode":3} +$GPGGA,021705.946,5029.3859,N,10441.0363,W,1,07,1.3,555.4,M,-20.3,M,0.0,0000*4D +$GPGLL,5029.3859,N,10441.0363,W,021705.946,A*23 +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A +$GPRMC,021705.946,A,5029.3859,N,10441.0363,W,0.061763,22.98,280706,,*2B +{"class":"TPV","tag":"RMC","time":1154053025.946,"ept":0.005,"lat":50.489765000,"lon":-104.683938333,"alt":555.400,"epx":9.353,"epy":18.976,"epv":44.702,"track":22.9800,"speed":0.032,"climb":-0.600,"eps":39.33,"mode":3} +$GPGGA,021706.946,5029.3860,N,10441.0364,W,1,07,1.3,554.9,M,-20.3,M,0.0,0000*4F +$GPGLL,5029.3860,N,10441.0364,W,021706.946,A*2D +$GPGSA,A,3,08,17,28,11,26,29,27,,,,,,2.5,1.3,2.1*3A diff --git a/test/daemon/rgm3800.log b/test/daemon/rgm3800.log new file mode 100644 index 0000000..cf7b641 --- /dev/null +++ b/test/daemon/rgm3800.log @@ -0,0 +1,46 @@ +# Name: Royaltek RGM-3800 +# Chipset: Sirf GSC3f/LP ? +# Submitted-by: "Philipp Klenze" +# Location: TU Munich, Garching, DE, 48.3N, 11.7E +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# this log has been generated with the format set to 4: +# ./rgm3800.py -d /dev/ttyUSB0 format 4 +# (the existence of $LOG-lines seem to be correlated with this format) +# +# Generated by running: +# ./rgm3800.py -d /dev/ttyUSB0 gmouse on +# cat /dev/ttyUSB0 +# +# First 15 lines is startup output; remainder is stationary +$LOG108,1,100,100,0,0,5,0,4,462*61 +$GPGGA,235951.952,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*44 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,3,1,12,20,00,000,,10,00,000,,31,00,000,,27,00,000,*7C +$GPGSV,3,2,12,19,00,000,,07,00,000,,04,00,000,,24,00,000,*76 +$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78 +$GPRMC,235951.952,V,0000.0000,N,00000.0000,E,,0.00,050180,,,N*63 +$LOG108,1,100,100,0,0,5,0,4,462*61 +$GPGGA,235952.953,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*46 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +$GPGSV,3,1,12,20,00,000,,10,00,000,,31,00,000,,27,00,000,*7C +$GPGSV,3,2,12,19,00,000,,07,00,000,,04,00,000,,24,00,000,*76 +$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78 +$GPRMC,235952.953,V,0000.0000,N,00000.0000,E,,0.00,050180,,,N*61 +$GPGGA,102523.342,4815.6883,N,01140.3675,E,1,03,4.1,-47.5,M,47.5,M,,0000*4B +$GPGSA,A,2,09,18,15,,,,,,,,,,4.2,4.1,1.0*35 +$GPGSV,3,1,11,15,78,236,41,09,30,277,44,18,26,303,36,22,04,332,34*73 +$GPGSV,3,2,11,26,64,298,,29,53,146,,28,45,057,25,17,28,119,22*78 +$GPGSV,3,3,11,08,13,081,27,12,06,219,22,10,05,190,21*4F +$GPRMC,102523.342,A,4815.6883,N,01140.3675,E,0.00,0.00,210808,,,A*61 +$LOG108,1,100,100,0,0,5,192,4,474*6C +$GPGGA,102524.342,4815.6880,N,01140.3673,E,1,03,4.1,-47.5,M,47.5,M,,0000*49 +$GPGSA,A,2,09,18,15,,,,,,,,,,4.2,4.1,1.0*35 +$GPGSV,3,1,11,15,78,236,41,09,30,277,44,18,26,303,36,22,04,332,34*73 +$GPGSV,3,2,11,26,64,298,,29,53,146,,28,45,057,25,17,28,119,22*78 +$GPGSV,3,3,11,08,13,081,28,12,06,219,22,10,05,190,21*40 +$GPRMC,102524.342,A,4815.6880,N,01140.3673,E,0.00,0.00,210808,,,A*63 +$LOG108,1,100,100,0,0,5,192,4,474*6C + diff --git a/test/daemon/rgm3800.log.chk b/test/daemon/rgm3800.log.chk new file mode 100644 index 0000000..b2658c2 --- /dev/null +++ b/test/daemon/rgm3800.log.chk @@ -0,0 +1,31 @@ +$GPGGA,235951.952,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*44 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,20,00,000,,10,00,000,,31,00,000,,27,00,000,*7C +$GPGSV,3,2,12,19,00,000,,07,00,000,,04,00,000,,24,00,000,*76 +$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78 +$GPRMC,235951.952,V,0000.0000,N,00000.0000,E,,0.00,050180,,,N*63 +$GPGGA,235952.953,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*46 +$GPGSA,A,1,,,,,,,,,,,,,,,*1E +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,20,00,000,,10,00,000,,31,00,000,,27,00,000,*7C +$GPGSV,3,2,12,19,00,000,,07,00,000,,04,00,000,,24,00,000,*76 +$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78 +$GPRMC,235952.953,V,0000.0000,N,00000.0000,E,,0.00,050180,,,N*61 +$GPGGA,102523.342,4815.6883,N,01140.3675,E,1,03,4.1,-47.5,M,47.5,M,,0000*4B +{"class":"TPV","tag":"GGA","lat":48.261471667,"lon":11.672791667,"alt":-47.500,"mode":3} +$GPGSA,A,2,09,18,15,,,,,,,,,,4.2,4.1,1.0*35 +$GPGSV,3,1,11,15,78,236,41,09,30,277,44,18,26,303,36,22,04,332,34*73 +$GPGSV,3,2,11,26,64,298,,29,53,146,,28,45,057,25,17,28,119,22*78 +$GPGSV,3,3,11,08,13,081,27,12,06,219,22,10,05,190,21*4F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":15,"el":78,"az":236,"ss":41,"used":true},{"PRN":9,"el":30,"az":277,"ss":44,"used":true},{"PRN":18,"el":26,"az":303,"ss":36,"used":true},{"PRN":22,"el":4,"az":332,"ss":34,"used":false},{"PRN":26,"el":64,"az":298,"ss":0,"used":false},{"PRN":29,"el":53,"az":146,"ss":0,"used":false},{"PRN":28,"el":45,"az":57,"ss":25,"used":false},{"PRN":17,"el":28,"az":119,"ss":22,"used":false},{"PRN":8,"el":13,"az":81,"ss":27,"used":false},{"PRN":12,"el":6,"az":219,"ss":22,"used":false},{"PRN":10,"el":5,"az":190,"ss":21,"used":false}]} +$GPRMC,102523.342,A,4815.6883,N,01140.3675,E,0.00,0.00,210808,,,A*61 +{"class":"TPV","tag":"RMC","time":1219314323.342,"ept":0.005,"lat":48.261471667,"lon":11.672791667,"alt":-47.500,"epv":23.000,"track":0.0000,"speed":0.000,"mode":3} +$GPGGA,102524.342,4815.6880,N,01140.3673,E,1,03,4.1,-47.5,M,47.5,M,,0000*49 +$GPGSA,A,2,09,18,15,,,,,,,,,,4.2,4.1,1.0*35 +$GPGSV,3,1,11,15,78,236,41,09,30,277,44,18,26,303,36,22,04,332,34*73 +$GPGSV,3,2,11,26,64,298,,29,53,146,,28,45,057,25,17,28,119,22*78 +$GPGSV,3,3,11,08,13,081,28,12,06,219,22,10,05,190,21*40 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":15,"el":78,"az":236,"ss":41,"used":true},{"PRN":9,"el":30,"az":277,"ss":44,"used":true},{"PRN":18,"el":26,"az":303,"ss":36,"used":true},{"PRN":22,"el":4,"az":332,"ss":34,"used":false},{"PRN":26,"el":64,"az":298,"ss":0,"used":false},{"PRN":29,"el":53,"az":146,"ss":0,"used":false},{"PRN":28,"el":45,"az":57,"ss":25,"used":false},{"PRN":17,"el":28,"az":119,"ss":22,"used":false},{"PRN":8,"el":13,"az":81,"ss":28,"used":false},{"PRN":12,"el":6,"az":219,"ss":22,"used":false},{"PRN":10,"el":5,"az":190,"ss":21,"used":false}]} +$GPRMC,102524.342,A,4815.6880,N,01140.3673,E,0.00,0.00,210808,,,A*63 +{"class":"TPV","tag":"RMC","time":1219314324.342,"ept":0.005,"lat":48.261466667,"lon":11.672788333,"alt":-47.500,"epv":23.000,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} diff --git a/test/daemon/rtcm2.log b/test/daemon/rtcm2.log new file mode 100644 index 0000000..07713d9 --- /dev/null +++ b/test/daemon/rtcm2.log @@ -0,0 +1,10 @@ +# Name: RTCM-104 source from a DGPSIP server +# Type: RTCM +# Submitted-by: Wolfgang Rupprecht +# Has leading garbage, to test parity locking. This is a truncated version +# of the sample.rtcm file used to test gpsdecode. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +YpgA_]qS@oglgyC|~oAxCJxqBHsDzu_FsHEfOXAdbwg@Es~]ywJ@x]Cxv^[_m_xRrLwzyBXQb`Z[@hMmOzbzjOXU}t_UUUEsHEfOXIfByS@oSpG|cBPAFvtGN}wl`xN@KsHEF}gV^]}g@EAx}~ywwWd\uv^{mrAÁðÜ×ðôÈGmÅÁäÞuLwzyBXye@bdWLhO{bz\pkJCE`jjJHsHEF}gZ\]Kl`_XHF|CNPAGvIxqBHSK{w_BsHEfOXUgB|__WSZ[{Iao~aJB`a@dPUrA diff --git a/test/daemon/rtcm2.log.chk b/test/daemon/rtcm2.log.chk new file mode 100644 index 0000000..710f886 --- /dev/null +++ b/test/daemon/rtcm2.log.chk @@ -0,0 +1,5 @@ +{"class":"RTCM2","type":9,"station_id":268,"zcount":252.0,"seqnum":3,"length":5,"station_health":0,"satellites":[{"ident":27,"udre":0,"issuedata":62,"rangerr":-39.680,"rangerate":-0.016},{"ident":7,"udre":0,"issuedata":15,"rangerr":25.660,"rangerate":0.026},{"ident":26,"udre":0,"issuedata":128,"rangerr":12.840,"rangerate":0.118}]} +{"class":"RTCM2","type":9,"station_id":268,"zcount":252.6,"seqnum":4,"length":5,"station_health":0,"satellites":[{"ident":13,"udre":0,"issuedata":3,"rangerr":-25.940,"rangerate":0.066},{"ident":2,"udre":0,"issuedata":73,"rangerr":0.920,"rangerate":-0.080},{"ident":8,"udre":0,"issuedata":22,"rangerr":23.820,"rangerate":0.014}]} +{"class":"RTCM2","type":9,"station_id":268,"zcount":253.8,"seqnum":5,"length":4,"station_health":0,"satellites":[{"ident":19,"udre":0,"issuedata":186,"rangerr":-59.520,"rangerate":-0.224},{"ident":11,"udre":1,"issuedata":2,"rangerr":-39.260,"rangerate":0.206}]} +{"class":"RTCM2","type":9,"station_id":268,"zcount":255.0,"seqnum":6,"length":5,"station_health":0,"satellites":[{"ident":27,"udre":0,"issuedata":62,"rangerr":-39.700,"rangerate":-0.018},{"ident":7,"udre":0,"issuedata":15,"rangerr":25.740,"rangerate":0.026},{"ident":26,"udre":0,"issuedata":128,"rangerr":13.240,"rangerate":0.128}]} +{"class":"RTCM2","type":9,"station_id":268,"zcount":255.6,"seqnum":7,"length":5,"station_health":0,"satellites":[{"ident":2,"udre":0,"issuedata":73,"rangerr":0.680,"rangerate":-0.092},{"ident":13,"udre":0,"issuedata":3,"rangerr":-25.680,"rangerate":0.084},{"ident":8,"udre":0,"issuedata":22,"rangerr":23.880,"rangerate":0.000}]} diff --git a/test/daemon/superstar2.log b/test/daemon/superstar2.log new file mode 100644 index 0000000000000000000000000000000000000000..462d425162da2474d99738bbdb262daad456b858 GIT binary patch literal 24044 zcmb{4cU%+M76^CVUJeFog#R@wJ{et=l!^cXZ!nJILKGQ}=h6@=9`ghyY@CW@Sg-(z#On8`c=rnhs z&$w6#E$kIOjTsj%6pbD~DIER_F=3P>vTbO1Y@{TbZW|Wv34hHOuHr82;NsHN*~QJ- zr7QfAfAr{4j3heBT{tOfd{p$5C@ov~)BfY&1II|+8k2Zi(q^b<;= z@SlZAXeL$?Itg7|7#khU2**Un3d6z~_}X+^_!eptmwO26{-b9v5Hze&6X>>`p5Jg* zfj*HmxNF~2i{9in(7375u!BIVRV|nIByQBo2yPi3i1E}UqGGfplM+-g1p^x5A$kr5Au?8 z7z^WQ!VA-<&@RC1n<26AkHb4d7pP#Q){vN9#61p-j`4p41BtO-FPCpbFlXot3A1@w ze}FmDv_{N)l-U5xhEwxBn8-Ii0JGBdU_Kq6v>qkqz%)I&+T+S{%0LBE42ki_iAnxY zZG~Vm8%2*qFri=hVLV+a^8Kn%7Ung7V)pkrJtix6UiP{YiePL6*1V+@|D`)=A|J`Z=$i5- zCVtTFKkh%*B(7vT`z5eFroagj<4;s`U|O5-B!-1)`FDCuI3y+u!4yYrk}$$12?(as z6EV|x$O!~6!;LSh1NVvNi7 z7$KPH2~J}W%&Ug{FsVh|$lJ^a7RHr7F~{;6>%2(QBkq;99j6zsDkWk%Bqo4JeGZ7&0NBF4#C2U{*KVrAKd; z`YoYEs>Gy0ViYh`Q)rJB)>C&kys*J@=lIe10QFK1)k? z<|M`w5)(kY;lOnHc`5y^#2kafY{Q8eyHUbWNAoX3Vg}w3Gv$t>0A}OW^&ZT{-OM3? z889QCmJL~l5|efuMx`3F1nQ2W$8;13R_1(?zw$z((wCXkfqFmT0-_t6zMa$sWkMx}pPN^er+@*Nn)DP6*R zO&$y|CHrqeDOt8hFfB4Xn4`4?2VK-xjgHKx3G+V?jQv?X+AaKPJk>~%82Fm;#b4!e z3=_O=ga(4qeV`YOV0s$x!<10oq@KnQfN7x^u5Ao?VH|qh*_-Vn_mVrT`27M0X8SF4 zMSl*=K(@!USIuJ_QS-I?)p^VTW%D)JAeZj~7|Yd`xAbV@Y|bJ|yLjeRF=M8w1~8d7 zws|maZcPDZ&Ew(ubf*i=3|-Vt4+F&7iSI61T~+iLfC-NIF4w?4=GNSE0t90dDV~U6 zQtL@fFGrG`xgmswd11f{)577zFo)T4uXm5OTD zL;;}}+iBv$C3VdgU{*$>D~2E#n8Bi%ZwOy0{Sz2yzDpo6*%+oDz)&5X0H$R9Ie>Y) z3Bg=D;K5W~+_E2Fq~7`Tc2O#V$@-#4-(E6&fpWNpuW8a%E;qz5Lxap-A(#M{;WUC7 zsKF0o^vRPve|sPc^MOAxNj)DtJy86~YoyK`(-01f&=Xzp2nR-&P0YV5B}mLINX$M2 zbJ}WOPR=F_iV-vF4^_S*XNjr;B5s4`Vz z4tJExO)*UWlt&K`Oz(^=3^Vu}{{&CJT1<)-4PasX`A4PvT=UDR)pDBsf^E@Kl@ z;D)X^mII^3H!87-`IWWOL1mB8h9$uPoESfVaZw+IV2+;!JO(AkT`sr4FwM;^{y;D;gGXQ(r?>nt>9<6rt6P5- zhT%_4{QQA#Gc*N6SVWUNZ4QjJ7rJ5*2PQ)Qr#U=eu;!)UFSFiYQmxd5f4 zClfQ<-|L~o*qw&N+)LOCFwUm=v|xNNf=PDLr$?^4JeO*0t%Nz;NiJ`WVHzwCxP)MA z8>?ZMX4U*K$yYqcg|GUuFnjrX%--2u-#<=lNC;OwlWpL@6hQGdCnj@XO4(9kSJyZ( zt$uY>I;2d@LP*RJ3?l-V2k(;*%=IH;risqohX8ZyoCnip!1Zhw^`u>zFe-ISK``@0 z`n2ztEGdj z1GD!_*;3Nlgsym%19O)zF?b%sf$@ZGhZgm2JG{p*keE_P%rOL0{54g=h~(`NjPrgm zV=guG3bMAF$@vmc?!WKCdA<3 z`tl8am_Zl2lEY$xSQtP49@DDp+srFWV`6s4Zwbzv#00^uuqEbmV79VLg1?DRb2X4}FjwhB>~%Iv>G2k{89GQEB8Aewc^lZsfwQy;>{zW7?V|q%%d2%n^ zSa}!S%y=z1!Gq7EJJZZWl8*ruRWGEh?b- z-jwZeQBNf+^XS{DgN$K<_dG?y5a#2~TlH3z68a!}3}dsw>o|fj?i_?++|KjENGiIJ zK8*uenDhM2*X`3>?RVh~3Gc7|HFhglm@{xI?1|MJm|lE6=AV=jB!-4XWIiq>b10>Q zlsY8ljMio`<5p;cN~!d|2lH``Ccq@;Ud*FE&P#^GtO=i`PfO#U%%CQzV9*CSVwmfF z`X59vZx+45OM<8pewedQT*=7W{wz!te~-xvY0=Ygwh>|X)pt$=XCCtb65~j`=D@6E z6T>#&e*y!E*$OxM1coV3mN1(Zrk4TCuyir=)#B{~fYE#6!34Pt+zp8-J&{MBntB~z z*4|pGPrEe8nNBTM&1299IboRaY|lLiW^+Jt6e^{Nll(9*KXoRr9qPrxMDWA(cRxBa zM7JrSS-y8xKhBb%HQWj(B8>yHjBn=q4`J@ZBC-&}EK8CwM&(@*%gjA3+ociE0$LIdALBAC~C{4jY< zJCj4!_GDp-`B&FPd5?z8zo|!T%kKJU$YQpX#=@;|CVFyU9`KbC96M1z?4;IFpKQWU`BCmaueDv}+ zC~eb<(|l(_V%iZ~IWWJ~!StFSfKlm+;wb@63>QZ4XD~I&;W_}81jPvEG?OS{rgn<~ znBt=4@RXqKXjDplK6^0nQ6dC0Dk+cd)GHY!ra-1o%YxcXp*kyjjC5r*ZFeCYg>vE4qxiO|+yapc(7Hwvmue7=hU2zZxrjQTj zhs698rWU~j2-F+J!6NbuhS>x#!Wr5CQxu;7r8KuAN=zd)5wo)8;vFvP8}7#E(Hoqu zqr@C8)2Eqjg2|M1T+2&2u@6NTJ_hErP)=#Q&&%cQ6;-uyMmjRG*>igw3eTW?ej~5p z9Y~V^KZQ{vc#^XAhe>cF^oVKBmQ3{-%jI6o#3xI(uToW&H0}brB3@5gD;C;c>y}MF z4bSYK8g*=njO6N#Dj_`Qu+h-95~kqT)^lJ~5hrGtN_7;TfJP#w`oY!h5S|y)^61U_ zrlt@c*9tHaTxKZid6qYFVh4C@d<@**Qfc%Ga?}AE^@x_GBBP>4Eyg0FSM?aJ`RGD^ zcI(a>S^iL9*l6~>WDWPiMnvl1PxF#kBSCw(D;2n@7Q8pXpm?ud;RZ1YJ(M)@CSha;n*^$c5Y*R&(89lNnc6Mv{R zY!qMNabay=eWLPxad#(8;F>ph0)s}N72JzJa3Z>Mv3db>C;EwF|m~O{ArJKVk@>zc^|l~ zmD0!_x_uk&vTH*k}Y8mA9RSj5be(M!jzmGJ0qxVzyVywnC2X_s*kb zlIti(^K}g9*Qwnng3!#DyBrw})DOasqjsO;H;O82 zLuMQMutx8H80B$}j28KsR#+PoLaP}By-?MU1Ro(sor%lH$V$mFe-i-BW7eV-N9&6OKTC+Uq=fWy(IGJHkqbokfVmy2DH%C zEQYe4d*ppi?A~eBwSj8NT9fvG9Jyj6$LR%&k&%AMIQ%Sg#U*~D`Qx3)`}*FjQ7ymG zK9@7cM#6Tw)1{`v8!4Ym!5-35xGS#2ERNBGy1Db8jPSVTfM!C!k|S4TKROCIx{8g& zU{o+*?-?-K9tm@2b5k(NENdxZ)(Qu0aZyhn*)flBz`7q3uxAkIw(WZ}ecN1DRz^utxj%d-guzmJg3cz3^IdCLp7d9oM91 z;I6n4OE^aQriz`xKjrAJ6Gzmu>o-!=8jNdwU|M<;8(FN9FuRGzB{25y355-?UPr+w z>v9x`Y<)WVU$Rv+$a_Kr4t)1H2fHs@HG?KEO9j_yct@2*=Hn37vYYxyIx?&@T z3-=gg6w_wuU}Pk!j?Yp)88dX1%MnI0b63;nC z>)ElN&Cx$Gg89*I$k8oqbZG?~s3@2RM#Ue8ikVF>mAqHD|@yftVQl%qwQcMvp!x7MsNGVo@!ESFiJm1ikPL@H!@&; z6!|Qd-W`yFjH2d1tvwM)DC?OyEoHI7$?mTMGgL;J&>ckB$mVdbp~%Rv`gMO~)Z#wB zkr81_22di_D2{)Aq~kQ;%$7iHqN}w0$#iz#S=tM7BvL#Lt;JSTCrADH#(sPxkh9oFJ=?n89JN#CXffpIJ~o;PMh&*UDFUM>6wI?F zrC^k{D?r4Q52H7M(WCRZbjl4gbLdBv8x80t4K|OVtfv}wlEs=W-SslC#7{)RF6M=izkzlO&X!edo$ zcwQ>E&}?Ah_!x)B7hqzBIim2~@f0&*F;OTyaUmi`jv!4rPnS>1(?J^1qO6* z2fr|?z493;LBYu@0>kth|H2o+WQ1PAFz+7o!x$d6CbN#Zu`p78nB>!M9*1S>5q8Gy zE=^-MU5O|7if1@5-}yQZhT%Tg`6FsEN7NEpHJ)29K(rYpdtdLfwo z!$r)gTSL-e(={Y3mlnuxBA6=|U`Bo4Y&2D&+*_0;J(9~6FwN6fPzdJW$-aRoF@v7+ z!xWiVlg;jRVPQP^VV+iGG)}2#N;GkH)tSdGHKbkObQz&|Mp~DcU3~54ucd?%WBLCR zGZ7N=3@4`H5(yI&J_=xp%Q}e};aNRYNu_L({?KD^DGeMFbhp#{21M&2 zf`Y3Ym~Z%sc%51YvxqM-d@vUE!l)8+021>8_n7R(FfWYyb_(XsP1}i?pl^4pV62)E zAz~i1_^<(B&MwTQiJHL(M)cZ%t|Db4DRt$9xnMUWMgh}k^6o$c6CugMFyiO@Fn1~} z$!}s;HZk>_K)xTASfDdjm$?1z=w1W1lmvm07?POFDW$V~Fnp!N3nN5l*0pi-g(qI6 zkeF9EF@*qgaDFPl6d!LbW?G6508E;}L=n^JsxQE#il^n$E|b89?V3@FaU|f7HNh+o@3#0kN>;@<1x9$_2gko)C!l`|2=W(82 z7*(SyR&Zdd>Yl3qbhU*_sa_bHw#rdS6IK#$aAGFJ!;z+x&IsmHOE{o1GY(+VMUzEL zeEjP5(0tt^a_NolNX}xeuOK84pYz*lz*Y?Axqsqh( za5Q_44^B+)_P_T-Fn6n8`lIG+`-H!goJ}l9w~CG|Od@}enU-TO*>pyY@LV_1zBOmA z2S>Bviuh=DU5|RDC*&v&MU>=x5Vm`G(iTQ0F%=KP5 zBbdzrxpY|7P=Hx$+}@C`z53fw>XR}t(n?5-0w$sTObl~q(Y0O(#_SP4Own9(GT)Q~ zbAo?V+ScV!tW8Q|A}w(KyA|v_Mmh%)<3pry5@XCakHO6s57&wfFjPwQCPvssnV1Yn z%m-BROCuNVRgv5M8FehpjNSITtx1NN=l<0|>s=_k} zrf8XniQIN31rpP^eJ;IMs}hyc+&+f%QSsIgDpvVaUHSnMqkwU+&c!fkmkN8L#6(u{ zCq{jEGjiS9_AJa?ewfDo^WO>V8xUE`t`a>sOM(DS`9EWOc9KrMJ_E}Wo-p8>Z1(lueYZJQ@fNsM$i*}<u$$&M+8KfMPc8SY>yE84vpAm{-y4JHfT1c3Yvn)6;ZTVpiPkn4LHM0TX zl)t(94*T$!ID)UZp9Axd?J;a(*m=yaz_eDD(oRT>9K(domoUKv(*dUBsQ_la)nb52 zJDe_JgsumYpvQza%%#n;HX@klxrTI#k;Ontu7r_B!2Rov6EiCNGoIk}sO*bj?$xui zEUt_*F*CZ>SDl$P)LV0xr~W1_&UbW$`6Bh`kk)}09Dz&vA1iQN(XdoYR~0~5S! zkQlWoXjGa8F#aZ{0CQ&fR}o_rtqU-4_(H_o=%NNN$z>m8bUalBFv$Z}8`7o4&-+uB z%H}KW4EIj~Q`P5l07}f0^Jg)P`c?i?DsnU>zwBzu!kql!F)^Ot<%>(ZC3V*)CZ<-# zMsj-0HGIVa4$K5LF-jN<#jiDg7?pHYzt$8ef31nJMN*E#z661#xQ?{`SPRxPe z#duV@U(OG+Y?BFj;Da*@^Nl|-P8-H-Uqu-Z$JR`EqRttW>>x3IL=*=mfK80Dl>RP^ zqLd&pwy-2(A}?}KfJ)oE)1rtK{mz4G=b1aoM=A-#G0 z%D&VDB}@TqJIEC<&x~tvVq6w)!xOyldJ=QN%!J(CjRP~9A0}{#FeqS{8sW2jbDwPX zVP^qsJHQpW+YX#X&-$VAi!eEMgiLJzE3k zNu5h&v}{Wzz@&6OX-HFDLiWxatCFm4h5@grYV-~D7CT}LT zVH0zXzxn3R>g=>|N3GY1SKov&oW!_8Vklw?Co#XVrS$J$ATg^UF`5Xb;1<9X7%m2w z;vUuTII7D)1and*Vu+fq2xe`bjE)<9A0@`&iXpwBrehFwOqm#I7~DSvOx&1i4D46htXcLZM-lgxvd%kPxDJ7Q#BQit8fq_Rzd_R@1Nw7RK>+UnJ(VYs!8k|vS z2qdNlv4{h6>c@GEg<3206SH4#zK+TzK`U4iG{uQY02m|nlX(DRQwawuR(z@uTBXb` z5i#R>URwn)jWT6)%d#+lNm^fHNSE}!9zX@C60;Z*qkyqqe+xI?Bi|MVp_y;SW&Y;d ztg#WM$uA$j1LBMW2ApO}~#0SR{(>J#FJ znV(JBQW8iZF+KmZi1hw>V(js$F2&YnJuo(^nQsy#MjyeP=m;=tL%-z0s8n-B#5fE| zLy2i!E@I-$=#`L|umv*uo`BV9h0%>LWsU=w)XEMJvo>?^eoR`gOBiNVDSu+V zH!&b>)i^NS`L{NwuGqTyl}{5weR1y>wrpYq_wf~bb6~vwbtwr|O9FFP5}0C`2>?TV zx+H^Ax>pF>cBzH{ll0~RB+-zm!G~ zZ(c4sbJgpaON-k}*~cdZwfKtoXm%Y;Io~{nEv3KJeCI)8EHI27z*Ozk2AGmv$3)D* z!Xp5aoc3D8xS4)k3eDF>ETg4`PBs8zA7(^To7Q%t4y#tzLb!j5mn*DyE**|wp816h zKs{!1J&CDF(<5nn4on{Zs1%y8Gk8jOx!0-Q<#(U3GhgWme8t0@QX2pB;riEMATgzo z7%L33eX0Zo=IuEEQ+@z8dLJ$Zn55iyuvRMQiC|3H!l+aliD1^yMs)4GF}~DFJ zhWn?033FEuLojWY+{7@4>Vaw4N{_T%X2&L`34f0nxzjtM&_tKeZP3gpfrSwm!8jP8 zcy?Wvn3;Ud*G@IT`vn-GY7zMW64M;_m^}cqeRVg0ITMi$r$H@-0!(6e*nyDFN?igy zW{yxs`#;}4A;Kdy5!2* zmMqLF{=}Fc*8U#6PM;vJgsyI=EG4+2^gX)bNls#-|HB?*3`+tVoEV=e5~g(Jz2lIW zwL4(CJD@E}%m_6xvzMq&fW%DJm(gp#zeF$#OabQXwpey2Shq}c0@Ricv zN{o$aRO$$eNLvik1Hq)tK`?D#cS^8PfD-dWL(Dud?1Er!smo|fTbC99b9A#2?HhEP zpaz)Z^DzKZ$|&DDF+sd@HcE^c3CC+8F`|05HancwA!nD^vWW@iFQp~ETi!e^(;_-P zYq9OUavlR$teTCkc#e}8c>UI2pAvAF1iw;Bs*S2BNQ@nZshA{TMjo<6FatJ<5VuFLW08H{?Lou`RetA3$*XPbCP zl~NNA^bQF0W}7vaT$2#Y=r+4BjJTd-ASrj6l3z1hu!)J~hauXuh?{v(hq$t$Sn^1@ zQ3bcch(K4wzX-1@rEx!B5;*+-wNl*!HyD+ULt-3pVxk!d<7+qw!5AdMk;U^iE+Y- zi2<0`18R=~%(j)V?GV%xB}T8gn2CHBy9g4)oCO%O&bBU=n+7}tm?14i)OXdWG#e75 zcx{~Cr(%yUSLGlo&4Au(H4A(*oXa9H||C4#YngAWddCl>*tNopFnrDT z7hu@Ln8UV1dz_eM6X8kZoYErzGgAu9S9B7=WWeF7k;_Le0GOTWIrPDRPXLqA#MqdQ zJHF118mLMP`XI$yClV#YE+814ZjKmcn>jy>>p^XDY*lkMF_rv1rqAa#Ir-H(#FEg( zK_lm~FdN}k*eYIKSO*i#!u;#Rw1ADOjyN$10Fxq@AQ(+J6tn63S_EV23a8HQX2$`H z#;P3p!CCi~0Q1t$nEqNF*@ZJ)qYqNNb>fu9yqgGSc;P@i!8_TKAEpDPO)i2Xt*Y0G zIrAsx({uCf7h*IBnf3CO&K#JnkQh6~)@B_H=l8vB|6EG=EHs-KtNJ#o>Y6W%N`2r) zcSbPBn#D+%+q4G26t#h4R3(ST0!*r<2fTW%wR}FD!K;~@L!WY+iD1Gz8`HZRc)3yw z6#FqyO6Y?WZ=Gm9|MfitQ+U}GuazpC`C%L@v`E8?)+|gme~)=^Wx^}+m^v}a)yaGV zr^j4{#Ml#SIP(~jdJ}_T9RL4tU3b(B<}nd)qq`uO;|Qif<>te%?I44LcjHF8Bbe1B zynrGi5W)0ea_G&exd4+%bvLFhb@e+_7n><(zUYG#Z=J}U9`O{xM0L%=8&$nK^TU|Z zT4ckX9GG+brL^kl-Db{0H6pZAmUa$jg7*><<4C;Xz?8A`n7@?LFDFKI25%4C=&lGR zXIqqnap>laU~Z3x;aaCDz@)724o79Sr_BQxzwjK|zxF#y%#i`cbd~P?j+CWpf`>jx z@z#mB)q;)bo^J;+({3mv?FqyNaV%Bq~?ekkJls zE1ZaQ4$Q)zC+1g5Nd@x~e!}B{VYIRHQ!!hM)2ivBnCfMVoRz19;1MPQqqKN2Qh+? zbpn`~;#mN5CT^67VOH%2m?Ts936K8(5x}Ibr*i0+GjjnZv&m#*dR(hT?WuFBQbHf3 zc^c>urA zaUlkBU;>q;^#5S2*-`1wFhT_kBnF+RA~DPnfGL@L^dP`E4iYg9f`buE$}ln0rpK*0 z0CUGFhhBQQK`Ve6o&-H+lv6uuv2s+Bwt?S*C|)%&`M_!|1ap9B+6}=h@5>L9AJv$w M$hTk<6K$mRKij1QaR2}S literal 0 HcmV?d00001 diff --git a/test/daemon/superstar2.log.chk b/test/daemon/superstar2.log.chk new file mode 100644 index 0000000..63b9800 --- /dev/null +++ b/test/daemon/superstar2.log.chk @@ -0,0 +1,756 @@ +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,39,03,41,063,36*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,00,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":36,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055054,5333.7867,N,11326.3743,W,1,05,3.10,631.80,M,,,*29 +$GPRMC,055054,A,5333.7867,N,11326.3743,W,0.0000,0.000,040709,,*38 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.3*34 +$GPGBS,055054,31.47,M,35.54,M,75.90,M*02 +{"class":"TPV","tag":"SS2-20","time":1246686655.000,"ept":0.005,"lat":53.563112132,"lon":-113.439571599,"alt":631.801,"epx":31.470,"epy":35.543,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,39,03,41,063,36*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,00,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":36,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055055,5333.7867,N,11326.3743,W,1,05,3.10,631.87,M,,,*2F +$GPRMC,055055,A,5333.7867,N,11326.3743,W,0.0000,0.000,040709,,*39 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.3*34 +$GPGBS,055055,31.47,M,35.54,M,75.90,M*03 +{"class":"TPV","tag":"SS2-20","time":1246686656.000,"ept":0.005,"lat":53.563111922,"lon":-113.439572138,"alt":631.867,"epx":31.470,"epy":35.543,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,39,03,41,063,36*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,00,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":36,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055056,5333.7867,N,11326.3744,W,1,05,3.10,631.94,M,,,*29 +$GPRMC,055056,A,5333.7867,N,11326.3744,W,0.0000,0.000,040709,,*3D +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.3*34 +$GPGBS,055056,31.47,M,35.54,M,75.90,M*00 +{"class":"TPV","tag":"SS2-20","time":1246686657.000,"ept":0.005,"lat":53.563111644,"lon":-113.439572583,"alt":631.943,"epx":31.470,"epy":35.543,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,40,03,41,063,36*72 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,00,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":36,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055057,5333.7867,N,11326.3744,W,1,05,3.10,632.00,M,,,*26 +$GPRMC,055057,A,5333.7867,N,11326.3744,W,0.0000,0.000,040709,,*3C +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.3*34 +$GPGBS,055057,31.47,M,35.54,M,75.90,M*01 +{"class":"TPV","tag":"SS2-20","time":1246686658.000,"ept":0.005,"lat":53.563111100,"lon":-113.439573094,"alt":632.002,"epx":31.470,"epy":35.543,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,40,03,41,063,36*72 +$GPGSV,3,2,12,28,22,023,36,09,18,156,00,30,15,073,00,23,14,223,00*73 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":36,"used":true},{"PRN":28,"el":22,"az":23,"ss":36,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055058,5333.7866,N,11326.3744,W,1,05,3.10,632.09,M,,,*21 +$GPRMC,055058,A,5333.7866,N,11326.3744,W,0.0000,0.000,040709,,*32 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.3*34 +$GPGBS,055058,31.47,M,35.54,M,75.90,M*0E +{"class":"TPV","tag":"SS2-20","time":1246686659.000,"ept":0.005,"lat":53.563110659,"lon":-113.439573808,"alt":632.093,"epx":31.470,"epy":35.543,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,39,03,41,063,36*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,00,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":36,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055059,5333.7866,N,11326.3745,W,1,05,3.10,632.20,M,,,*2A +$GPRMC,055059,A,5333.7866,N,11326.3745,W,0.0000,0.000,040709,,*32 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.3*34 +$GPGBS,055059,31.47,M,35.54,M,75.90,M*0F +{"class":"TPV","tag":"SS2-20","time":1246686660.000,"ept":0.005,"lat":53.563110309,"lon":-113.439574638,"alt":632.204,"epx":31.470,"epy":35.543,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,40,03,41,063,36*72 +$GPGSV,3,2,12,28,22,023,36,09,18,156,00,30,15,073,00,23,14,223,00*73 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":36,"used":true},{"PRN":28,"el":22,"az":23,"ss":36,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055100,5333.7866,N,11326.3745,W,1,05,3.10,632.27,M,,,*20 +$GPRMC,055100,A,5333.7866,N,11326.3745,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.3*34 +$GPGBS,055100,31.47,M,35.54,M,75.90,M*02 +{"class":"TPV","tag":"SS2-20","time":1246686661.000,"ept":0.005,"lat":53.563109836,"lon":-113.439575270,"alt":632.266,"epx":31.470,"epy":35.543,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,40,03,41,063,36*72 +$GPGSV,3,2,12,28,22,023,36,09,18,156,00,30,15,073,00,23,14,223,00*73 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":36,"used":true},{"PRN":28,"el":22,"az":23,"ss":36,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055101,5333.7866,N,11326.3745,W,1,05,3.10,632.29,M,,,*2F +$GPRMC,055101,A,5333.7866,N,11326.3745,W,0.0000,0.000,040709,,*3E +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055101,31.47,M,35.54,M,78.20,M*05 +{"class":"TPV","tag":"SS2-20","time":1246686662.000,"ept":0.005,"lat":53.563109239,"lon":-113.439575706,"alt":632.286,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,49,11,67,212,50,29,55,030,41,03,41,063,37*7A +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,00,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":49,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":37,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055102,5333.7865,N,11326.3746,W,1,05,3.10,632.27,M,,,*22 +$GPRMC,055102,A,5333.7865,N,11326.3746,W,0.0000,0.000,040709,,*3D +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055102,31.47,M,35.54,M,78.20,M*06 +{"class":"TPV","tag":"SS2-20","time":1246686663.000,"ept":0.005,"lat":53.563108537,"lon":-113.439576170,"alt":632.275,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,41,03,41,063,37*72 +$GPGSV,3,2,12,28,22,023,36,09,18,156,00,30,15,073,00,23,14,223,00*73 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":37,"used":true},{"PRN":28,"el":22,"az":23,"ss":36,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055103,5333.7865,N,11326.3746,W,1,05,3.10,632.22,M,,,*26 +$GPRMC,055103,A,5333.7865,N,11326.3746,W,0.0000,0.000,040709,,*3C +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055103,31.47,M,35.54,M,78.20,M*07 +{"class":"TPV","tag":"SS2-20","time":1246686664.000,"ept":0.005,"lat":53.563107673,"lon":-113.439576457,"alt":632.222,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,41,03,41,063,37*72 +$GPGSV,3,2,12,28,22,023,36,09,18,156,00,30,15,073,00,23,14,223,00*73 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":37,"used":true},{"PRN":28,"el":22,"az":23,"ss":36,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055104,5333.7864,N,11326.3746,W,1,05,3.10,632.11,M,,,*20 +$GPRMC,055104,A,5333.7864,N,11326.3746,W,0.0000,0.000,040709,,*3A +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055104,31.47,M,35.54,M,78.20,M*00 +{"class":"TPV","tag":"SS2-20","time":1246686665.000,"ept":0.005,"lat":53.563106648,"lon":-113.439576625,"alt":632.115,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,49,11,67,212,50,29,55,030,41,03,41,063,37*7A +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,00,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":49,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":37,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055105,5333.7863,N,11326.3746,W,1,05,3.10,631.96,M,,,*2A +$GPRMC,055105,A,5333.7863,N,11326.3746,W,0.0000,0.000,040709,,*3C +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055105,31.47,M,35.54,M,78.20,M*01 +{"class":"TPV","tag":"SS2-20","time":1246686666.000,"ept":0.005,"lat":53.563105560,"lon":-113.439576682,"alt":631.959,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,41,03,41,063,37*72 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,00,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":37,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055106,5333.7863,N,11326.3746,W,1,05,3.10,631.78,M,,,*29 +$GPRMC,055106,A,5333.7863,N,11326.3746,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055106,31.47,M,35.54,M,78.20,M*02 +{"class":"TPV","tag":"SS2-20","time":1246686667.000,"ept":0.005,"lat":53.563104408,"lon":-113.439576625,"alt":631.784,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,41,03,41,063,37*72 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,00,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":37,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055107,5333.7862,N,11326.3746,W,1,05,3.10,631.63,M,,,*23 +$GPRMC,055107,A,5333.7862,N,11326.3746,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055107,31.47,M,35.54,M,78.20,M*03 +{"class":"TPV","tag":"SS2-20","time":1246686668.000,"ept":0.005,"lat":53.563103469,"lon":-113.439576547,"alt":631.627,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,41,03,41,063,38*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,00,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":0,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055108,5333.7862,N,11326.3746,W,1,05,3.10,631.50,M,,,*2C +$GPRMC,055108,A,5333.7862,N,11326.3746,W,0.0000,0.000,040709,,*30 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055108,31.47,M,35.54,M,78.20,M*0C +{"class":"TPV","tag":"SS2-20","time":1246686669.000,"ept":0.005,"lat":53.563102745,"lon":-113.439576417,"alt":631.497,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,40,03,41,063,38*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,34,23,14,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":34,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055109,5333.7861,N,11326.3746,W,1,05,3.10,631.39,M,,,*21 +$GPRMC,055109,A,5333.7861,N,11326.3746,W,0.0000,0.000,040709,,*32 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055109,31.47,M,35.54,M,78.20,M*0D +{"class":"TPV","tag":"SS2-20","time":1246686670.000,"ept":0.005,"lat":53.563102075,"lon":-113.439576213,"alt":631.388,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,49,11,67,212,50,29,55,030,41,03,41,063,38*75 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,34,23,14,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":49,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":34,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055110,5333.7861,N,11326.3746,W,1,05,3.10,631.30,M,,,*20 +$GPRMC,055110,A,5333.7861,N,11326.3746,W,0.0000,0.000,040709,,*3A +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055110,31.47,M,35.54,M,78.20,M*05 +{"class":"TPV","tag":"SS2-20","time":1246686671.000,"ept":0.005,"lat":53.563101528,"lon":-113.439576072,"alt":631.303,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,49,11,67,212,50,29,55,030,41,03,41,063,38*75 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,34,23,14,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":49,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":34,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055111,5333.7861,N,11326.3746,W,1,05,3.10,631.22,M,,,*22 +$GPRMC,055111,A,5333.7861,N,11326.3746,W,0.0000,0.000,040709,,*3B +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055111,31.47,M,35.54,M,78.20,M*04 +{"class":"TPV","tag":"SS2-20","time":1246686672.000,"ept":0.005,"lat":53.563101008,"lon":-113.439575973,"alt":631.222,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,40,03,41,063,38*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,34,23,14,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":34,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055112,5333.7860,N,11326.3746,W,1,05,3.10,631.13,M,,,*22 +$GPRMC,055112,A,5333.7860,N,11326.3746,W,0.0000,0.000,040709,,*39 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055112,31.47,M,35.54,M,78.20,M*07 +{"class":"TPV","tag":"SS2-20","time":1246686673.000,"ept":0.005,"lat":53.563100377,"lon":-113.439575894,"alt":631.132,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,40,03,41,063,38*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,34,23,14,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":34,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055113,5333.7860,N,11326.3745,W,1,05,3.10,631.04,M,,,*26 +$GPRMC,055113,A,5333.7860,N,11326.3745,W,0.0000,0.000,040709,,*3B +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055113,31.47,M,35.54,M,78.20,M*06 +{"class":"TPV","tag":"SS2-20","time":1246686674.000,"ept":0.005,"lat":53.563099621,"lon":-113.439575605,"alt":631.038,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,40,03,41,063,38*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,34,23,14,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":34,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055114,5333.7859,N,11326.3745,W,1,05,3.10,630.98,M,,,*2F +$GPRMC,055114,A,5333.7859,N,11326.3745,W,0.0000,0.000,040709,,*36 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055114,31.47,M,35.54,M,78.20,M*01 +{"class":"TPV","tag":"SS2-20","time":1246686675.000,"ept":0.005,"lat":53.563099084,"lon":-113.439575256,"alt":630.983,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,76,110,50,11,67,212,50,29,55,030,41,03,41,063,39*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,15,073,33,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.10,"ydop":2.37,"vdop":4.13,"tdop":3.58,"hdop":3.16,"gdop":6.31,"pdop":5.20,"satellites":[{"PRN":1,"el":76,"az":110,"ss":50,"used":true},{"PRN":11,"el":67,"az":212,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":15,"az":73,"ss":33,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055115,5333.7859,N,11326.3745,W,1,05,3.10,630.95,M,,,*23 +$GPRMC,055115,A,5333.7859,N,11326.3745,W,0.0000,0.000,040709,,*37 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055115,31.47,M,35.54,M,78.20,M*00 +{"class":"TPV","tag":"SS2-20","time":1246686676.000,"ept":0.005,"lat":53.563098573,"lon":-113.439574925,"alt":630.952,"epx":31.470,"epy":35.543,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":71.09,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,33,23,14,223,00*71 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":33,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055116,5333.7859,N,11326.3745,W,1,05,3.10,630.96,M,,,*23 +$GPRMC,055116,A,5333.7859,N,11326.3745,W,0.0000,0.000,040709,,*34 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055116,31.42,M,35.32,M,78.20,M*06 +{"class":"TPV","tag":"SS2-20","time":1246686677.000,"ept":0.005,"lat":53.563098187,"lon":-113.439574627,"alt":630.959,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.87,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,41,03,41,063,39*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,33,23,14,223,00*71 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":33,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055117,5333.7859,N,11326.3745,W,1,06,3.10,630.99,M,,,*2E +$GPRMC,055117,A,5333.7859,N,11326.3745,W,0.0000,0.000,040709,,*35 +$GPGSA,A,3,01,11,29,03,28,,,,,,,,5.2,3.1,3.4*33 +$GPGBS,055117,31.42,M,35.32,M,78.20,M*07 +{"class":"TPV","tag":"SS2-20","time":1246686678.000,"ept":0.005,"lat":53.563098045,"lon":-113.439574382,"alt":630.990,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,33,23,14,223,00*71 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":33,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055118,5333.7859,N,11326.3744,W,1,06,3.10,631.00,M,,,*21 +$GPRMC,055118,A,5333.7859,N,11326.3744,W,0.0000,0.000,040709,,*3B +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,3.1,3.4*3D +$GPGBS,055118,29.35,M,11.61,M,78.20,M*01 +{"class":"TPV","tag":"SS2-20","time":1246686679.000,"ept":0.005,"lat":53.563097539,"lon":-113.439574013,"alt":630.999,"epx":29.347,"epy":11.605,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":64.67,"mode":3} +$GPGSV,3,1,12,01,75,109,50,11,67,211,50,29,55,030,40,03,41,063,39*75 +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,33,23,14,223,00*7E +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":50,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":33,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055119,5333.7858,N,11326.3744,W,1,06,3.10,631.04,M,,,*25 +$GPRMC,055119,A,5333.7858,N,11326.3744,W,0.0000,0.000,040709,,*3B +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,3.1,3.4*3D +$GPGBS,055119,29.35,M,11.61,M,78.20,M*00 +{"class":"TPV","tag":"SS2-20","time":1246686680.000,"ept":0.005,"lat":53.563097061,"lon":-113.439573664,"alt":631.037,"epx":29.347,"epy":11.605,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,50,11,67,211,50,29,55,030,40,03,41,063,39*75 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,33,23,14,223,00*71 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":50,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":33,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055120,5333.7858,N,11326.3744,W,1,06,3.10,631.09,M,,,*22 +$GPRMC,055120,A,5333.7858,N,11326.3744,W,0.0000,0.000,040709,,*31 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,3.1,3.4*3D +$GPGBS,055120,29.35,M,11.61,M,78.20,M*0A +{"class":"TPV","tag":"SS2-20","time":1246686681.000,"ept":0.005,"lat":53.563096658,"lon":-113.439573296,"alt":631.094,"epx":29.347,"epy":11.605,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,50,11,67,211,50,29,55,030,40,03,41,063,39*75 +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,33,23,14,223,00*7E +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":50,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":33,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055121,5333.7858,N,11326.3744,W,1,06,3.10,631.18,M,,,*23 +$GPRMC,055121,A,5333.7858,N,11326.3744,W,0.0000,0.000,040709,,*30 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,3.1,3.4*3D +$GPGBS,055121,29.35,M,11.61,M,78.20,M*0B +{"class":"TPV","tag":"SS2-20","time":1246686682.000,"ept":0.005,"lat":53.563096380,"lon":-113.439572984,"alt":631.182,"epx":29.347,"epy":11.605,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,32,23,14,223,00*70 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":32,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055122,5333.7857,N,11326.3744,W,1,06,3.10,631.27,M,,,*23 +$GPRMC,055122,A,5333.7857,N,11326.3744,W,0.0000,0.000,040709,,*3C +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,3.1,3.4*3D +$GPGBS,055122,29.35,M,11.61,M,78.20,M*08 +{"class":"TPV","tag":"SS2-20","time":1246686683.000,"ept":0.005,"lat":53.563095833,"lon":-113.439572578,"alt":631.274,"epx":29.347,"epy":11.605,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,41,03,41,063,40*72 +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,33,23,14,223,00*7E +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":40,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":33,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055123,5333.7857,N,11326.3743,W,1,06,2.70,631.36,M,,,*22 +$GPRMC,055123,A,5333.7857,N,11326.3743,W,0.0000,0.000,040709,,*3A +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,2.7,3.3*3D +$GPGBS,055123,29.35,M,11.61,M,75.90,M*0F +{"class":"TPV","tag":"SS2-20","time":1246686684.000,"ept":0.005,"lat":53.563095071,"lon":-113.439572079,"alt":631.359,"epx":29.347,"epy":11.605,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,41,03,41,063,40*72 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,32,23,14,223,00*70 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":41,"used":true},{"PRN":3,"el":41,"az":63,"ss":40,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":32,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055124,5333.7857,N,11326.3743,W,1,06,2.70,631.42,M,,,*26 +$GPRMC,055124,A,5333.7857,N,11326.3743,W,0.0000,0.000,040709,,*3D +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,2.7,3.3*3D +$GPGBS,055124,29.35,M,11.61,M,75.90,M*08 +{"class":"TPV","tag":"SS2-20","time":1246686685.000,"ept":0.005,"lat":53.563094246,"lon":-113.439571676,"alt":631.419,"epx":29.347,"epy":11.605,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,32,23,14,223,00*70 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":32,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055125,5333.7856,N,11326.3743,W,1,06,2.70,631.47,M,,,*23 +$GPRMC,055125,A,5333.7856,N,11326.3743,W,0.0000,0.000,040709,,*3D +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,2.7,3.3*3D +$GPGBS,055125,29.35,M,11.61,M,75.90,M*09 +{"class":"TPV","tag":"SS2-20","time":1246686686.000,"ept":0.005,"lat":53.563093606,"lon":-113.439571327,"alt":631.472,"epx":29.347,"epy":11.605,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,32,23,14,223,00*70 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":32,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055126,5333.7856,N,11326.3743,W,1,06,2.70,631.52,M,,,*24 +$GPRMC,055126,A,5333.7856,N,11326.3743,W,0.0000,0.000,040709,,*3E +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,2.7,3.3*3D +$GPGBS,055126,29.35,M,11.61,M,75.90,M*0A +{"class":"TPV","tag":"SS2-20","time":1246686687.000,"ept":0.005,"lat":53.563093093,"lon":-113.439571004,"alt":631.525,"epx":29.347,"epy":11.605,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,32,23,14,223,00*70 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":32,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055127,5333.7855,N,11326.3742,W,1,06,2.70,631.54,M,,,*21 +$GPRMC,055127,A,5333.7855,N,11326.3742,W,0.0000,0.000,040709,,*3D +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,2.7,3.3*3D +$GPGBS,055127,29.35,M,11.61,M,75.90,M*0B +{"class":"TPV","tag":"SS2-20","time":1246686688.000,"ept":0.005,"lat":53.563092169,"lon":-113.439570647,"alt":631.538,"epx":29.347,"epy":11.605,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,31,23,14,223,00*73 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":31,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055128,5333.7855,N,11326.3742,W,1,06,2.70,631.55,M,,,*2F +$GPRMC,055128,A,5333.7855,N,11326.3742,W,0.0000,0.000,040709,,*32 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,2.7,3.3*3D +$GPGBS,055128,29.35,M,11.61,M,75.90,M*04 +{"class":"TPV","tag":"SS2-20","time":1246686689.000,"ept":0.005,"lat":53.563090982,"lon":-113.439570130,"alt":631.549,"epx":29.347,"epy":11.605,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,31,23,14,223,00*73 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":31,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055129,5333.7854,N,11326.3742,W,1,06,2.70,631.56,M,,,*2C +$GPRMC,055129,A,5333.7854,N,11326.3742,W,0.0000,0.000,040709,,*32 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,2.7,3.3*3D +$GPGBS,055129,29.35,M,11.61,M,75.90,M*05 +{"class":"TPV","tag":"SS2-20","time":1246686690.000,"ept":0.005,"lat":53.563089873,"lon":-113.439569560,"alt":631.560,"epx":29.347,"epy":11.605,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,39,03,41,063,39*73 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,30,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":30,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055130,5333.7853,N,11326.3741,W,1,06,2.70,631.57,M,,,*21 +$GPRMC,055130,A,5333.7853,N,11326.3741,W,0.0000,0.000,040709,,*3E +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,2.7,3.3*3D +$GPGBS,055130,29.35,M,11.61,M,75.90,M*0D +{"class":"TPV","tag":"SS2-20","time":1246686691.000,"ept":0.005,"lat":53.563088792,"lon":-113.439568970,"alt":631.566,"epx":29.347,"epy":11.605,"epv":75.900,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,30,23,14,223,00*72 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":1.96,"ydop":0.77,"vdop":1.89,"tdop":1.69,"hdop":2.10,"gdop":3.30,"pdop":2.83,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":30,"used":true},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055131,5333.7853,N,11326.3741,W,1,05,3.10,631.59,M,,,*2A +$GPRMC,055131,A,5333.7853,N,11326.3741,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,2.8,3.1,3.4*3D +$GPGBS,055131,29.35,M,11.61,M,78.20,M*0A +{"class":"TPV","tag":"SS2-20","time":1246686692.000,"ept":0.005,"lat":53.563088066,"lon":-113.439568562,"alt":631.590,"epx":29.347,"epy":11.605,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":58.69,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,39,03,41,063,39*73 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,29,23,14,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":29,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055132,5333.7853,N,11326.3741,W,1,05,3.10,631.62,M,,,*21 +$GPRMC,055132,A,5333.7853,N,11326.3741,W,0.0000,0.000,040709,,*3C +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055132,31.42,M,35.32,M,78.20,M*00 +{"class":"TPV","tag":"SS2-20","time":1246686693.000,"ept":0.005,"lat":53.563088488,"lon":-113.439568610,"alt":631.624,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":64.67,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,39,03,41,063,38*72 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,29,23,14,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":29,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055133,5333.7853,N,11326.3741,W,1,05,3.10,631.66,M,,,*24 +$GPRMC,055133,A,5333.7853,N,11326.3741,W,0.0000,0.000,040709,,*3D +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055133,31.42,M,35.32,M,78.20,M*01 +{"class":"TPV","tag":"SS2-20","time":1246686694.000,"ept":0.005,"lat":53.563088876,"lon":-113.439568718,"alt":631.662,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,28,23,14,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055134,5333.7854,N,11326.3741,W,1,05,3.10,631.68,M,,,*2A +$GPRMC,055134,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3D +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055134,31.42,M,35.32,M,78.20,M*06 +{"class":"TPV","tag":"SS2-20","time":1246686695.000,"ept":0.005,"lat":53.563089191,"lon":-113.439568753,"alt":631.683,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,27,23,14,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":27,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055135,5333.7854,N,11326.3741,W,1,05,3.10,631.69,M,,,*2A +$GPRMC,055135,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3C +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055135,31.42,M,35.32,M,78.20,M*07 +{"class":"TPV","tag":"SS2-20","time":1246686696.000,"ept":0.005,"lat":53.563089528,"lon":-113.439568785,"alt":631.691,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,39,03,41,063,38*72 +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,27,23,14,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,00*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":27,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":0,"used":false}]} +$GPGGA,055136,5333.7854,N,11326.3741,W,1,05,3.10,631.69,M,,,*29 +$GPRMC,055136,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055136,31.42,M,35.32,M,78.20,M*04 +{"class":"TPV","tag":"SS2-20","time":1246686697.000,"ept":0.005,"lat":53.563089796,"lon":-113.439568755,"alt":631.694,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,27,23,14,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,33*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":27,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055137,5333.7854,N,11326.3741,W,1,05,3.10,631.68,M,,,*29 +$GPRMC,055137,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3E +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055137,31.42,M,35.32,M,78.20,M*05 +{"class":"TPV","tag":"SS2-20","time":1246686698.000,"ept":0.005,"lat":53.563089982,"lon":-113.439568607,"alt":631.676,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,26,23,14,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,33*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":26,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055138,5333.7854,N,11326.3741,W,1,05,3.10,631.64,M,,,*2A +$GPRMC,055138,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*31 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055138,31.42,M,35.32,M,78.20,M*0A +{"class":"TPV","tag":"SS2-20","time":1246686699.000,"ept":0.005,"lat":53.563090062,"lon":-113.439568421,"alt":631.643,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,39*7D +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,27,23,14,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,32*74 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":27,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055139,5333.7854,N,11326.3741,W,1,05,3.10,631.60,M,,,*2F +$GPRMC,055139,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*30 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055139,31.42,M,35.32,M,78.20,M*0B +{"class":"TPV","tag":"SS2-20","time":1246686700.000,"ept":0.005,"lat":53.563090041,"lon":-113.439568187,"alt":631.595,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,40,03,41,063,38*7C +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,26,23,14,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,32*74 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":26,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055140,5333.7854,N,11326.3741,W,1,05,3.10,631.55,M,,,*27 +$GPRMC,055140,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3E +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055140,31.42,M,35.32,M,78.20,M*05 +{"class":"TPV","tag":"SS2-20","time":1246686701.000,"ept":0.005,"lat":53.563089984,"lon":-113.439568032,"alt":631.547,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,030,40,03,41,063,39*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,26,23,14,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,32*74 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":26,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055141,5333.7854,N,11326.3741,W,1,05,3.10,631.51,M,,,*22 +$GPRMC,055141,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055141,31.42,M,35.32,M,78.20,M*04 +{"class":"TPV","tag":"SS2-20","time":1246686702.000,"ept":0.005,"lat":53.563089962,"lon":-113.439567958,"alt":631.507,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,030,40,03,41,063,39*7C +$GPGSV,3,2,12,28,22,023,37,09,18,156,00,30,16,073,26,23,14,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,32*74 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":37,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":26,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055142,5333.7854,N,11326.3741,W,1,05,3.10,631.46,M,,,*27 +$GPRMC,055142,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3C +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055142,31.42,M,35.32,M,78.20,M*07 +{"class":"TPV","tag":"SS2-20","time":1246686703.000,"ept":0.005,"lat":53.563089895,"lon":-113.439567895,"alt":631.460,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,030,40,03,41,063,39*7C +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,25,23,14,223,00*79 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,33*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":40,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":25,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055143,5333.7854,N,11326.3741,W,1,05,3.10,631.41,M,,,*21 +$GPRMC,055143,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3D +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055143,31.42,M,35.32,M,78.20,M*06 +{"class":"TPV","tag":"SS2-20","time":1246686704.000,"ept":0.005,"lat":53.563089707,"lon":-113.439567877,"alt":631.410,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,030,39,03,41,063,38*73 +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,25,23,14,223,00*79 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,33*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":25,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055144,5333.7854,N,11326.3741,W,1,05,3.10,631.36,M,,,*26 +$GPRMC,055144,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3A +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055144,31.42,M,35.32,M,78.20,M*01 +{"class":"TPV","tag":"SS2-20","time":1246686705.000,"ept":0.005,"lat":53.563089560,"lon":-113.439567864,"alt":631.358,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,030,39,03,41,063,38*72 +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,25,23,14,223,00*79 +$GPGSV,3,3,12,22,06,031,00,08,01,208,00,137,28,172,00,134,26,203,33*75 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.35,"vdop":4.14,"tdop":3.58,"hdop":3.15,"gdop":6.32,"pdop":5.20,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":30,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":25,"used":false},{"PRN":23,"el":14,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":1,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055145,5333.7854,N,11326.3741,W,1,05,3.10,631.33,M,,,*22 +$GPRMC,055145,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3B +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055145,31.42,M,35.32,M,78.20,M*00 +{"class":"TPV","tag":"SS2-20","time":1246686706.000,"ept":0.005,"lat":53.563089454,"lon":-113.439567964,"alt":631.328,"epx":31.423,"epy":35.323,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.65,"mode":3} +$GPGSV,3,1,12,01,75,109,49,11,67,211,50,29,55,029,39,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,26,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":49,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":26,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055146,5333.7854,N,11326.3741,W,1,05,3.10,631.33,M,,,*21 +$GPRMC,055146,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*38 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055146,31.24,M,34.77,M,78.20,M*03 +{"class":"TPV","tag":"SS2-20","time":1246686707.000,"ept":0.005,"lat":53.563089479,"lon":-113.439568123,"alt":631.326,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":70.10,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,39,03,41,063,38*7B +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,26,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":26,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055147,5333.7854,N,11326.3741,W,1,05,3.10,631.33,M,,,*20 +$GPRMC,055147,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*39 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055147,31.24,M,34.77,M,78.20,M*02 +{"class":"TPV","tag":"SS2-20","time":1246686708.000,"ept":0.005,"lat":53.563089451,"lon":-113.439568361,"alt":631.334,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,39,03,41,063,38*7B +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,26,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":26,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055148,5333.7854,N,11326.3741,W,1,05,3.10,631.35,M,,,*29 +$GPRMC,055148,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*36 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055148,31.24,M,34.77,M,78.20,M*0D +{"class":"TPV","tag":"SS2-20","time":1246686709.000,"ept":0.005,"lat":53.563089579,"lon":-113.439568599,"alt":631.354,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,39,03,41,063,38*7B +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,26,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":26,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055149,5333.7854,N,11326.3741,W,1,05,3.10,631.35,M,,,*28 +$GPRMC,055149,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*37 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055149,31.24,M,34.77,M,78.20,M*0C +{"class":"TPV","tag":"SS2-20","time":1246686710.000,"ept":0.005,"lat":53.563089660,"lon":-113.439568784,"alt":631.355,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,39,03,41,063,38*7B +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,26,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":39,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":26,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055150,5333.7854,N,11326.3741,W,1,05,3.10,631.34,M,,,*21 +$GPRMC,055150,A,5333.7854,N,11326.3741,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055150,31.24,M,34.77,M,78.20,M*04 +{"class":"TPV","tag":"SS2-20","time":1246686711.000,"ept":0.005,"lat":53.563089605,"lon":-113.439569004,"alt":631.337,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,26,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":26,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055151,5333.7854,N,11326.3742,W,1,05,3.10,631.29,M,,,*2F +$GPRMC,055151,A,5333.7854,N,11326.3742,W,0.0000,0.000,040709,,*3D +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055151,31.24,M,34.77,M,78.20,M*05 +{"class":"TPV","tag":"SS2-20","time":1246686712.000,"ept":0.005,"lat":53.563089548,"lon":-113.439569188,"alt":631.291,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,27,23,15,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,32*75 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":27,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055152,5333.7854,N,11326.3742,W,1,05,3.10,631.26,M,,,*23 +$GPRMC,055152,A,5333.7854,N,11326.3742,W,0.0000,0.000,040709,,*3E +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055152,31.24,M,34.77,M,78.20,M*06 +{"class":"TPV","tag":"SS2-20","time":1246686713.000,"ept":0.005,"lat":53.563089622,"lon":-113.439569398,"alt":631.259,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,39,09,18,156,00,30,16,073,28,23,15,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":39,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055153,5333.7854,N,11326.3742,W,1,05,3.10,631.25,M,,,*21 +$GPRMC,055153,A,5333.7854,N,11326.3742,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055153,31.24,M,34.77,M,78.20,M*07 +{"class":"TPV","tag":"SS2-20","time":1246686714.000,"ept":0.005,"lat":53.563089757,"lon":-113.439569660,"alt":631.246,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,28,23,15,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,32*75 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055154,5333.7854,N,11326.3742,W,1,05,3.10,631.22,M,,,*21 +$GPRMC,055154,A,5333.7854,N,11326.3742,W,0.0000,0.000,040709,,*38 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055154,31.24,M,34.77,M,78.20,M*00 +{"class":"TPV","tag":"SS2-20","time":1246686715.000,"ept":0.005,"lat":53.563089857,"lon":-113.439569832,"alt":631.223,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,38,09,18,156,00,30,16,073,28,23,15,223,00*75 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,32*75 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":38,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055155,5333.7854,N,11326.3742,W,1,05,3.10,631.20,M,,,*22 +$GPRMC,055155,A,5333.7854,N,11326.3742,W,0.0000,0.000,040709,,*39 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055155,31.24,M,34.77,M,78.20,M*01 +{"class":"TPV","tag":"SS2-20","time":1246686716.000,"ept":0.005,"lat":53.563090043,"lon":-113.439569890,"alt":631.196,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,39,09,18,156,00,30,16,073,28,23,15,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,32*75 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":39,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055156,5333.7854,N,11326.3742,W,1,05,3.10,631.19,M,,,*2B +$GPRMC,055156,A,5333.7854,N,11326.3742,W,0.0000,0.000,040709,,*3A +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055156,31.24,M,34.77,M,78.20,M*02 +{"class":"TPV","tag":"SS2-20","time":1246686717.000,"ept":0.005,"lat":53.563090391,"lon":-113.439569974,"alt":631.192,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,39,09,18,156,00,30,16,073,28,23,15,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":39,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055157,5333.7854,N,11326.3742,W,1,05,3.10,631.18,M,,,*2B +$GPRMC,055157,A,5333.7854,N,11326.3742,W,0.0000,0.000,040709,,*3B +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055157,31.24,M,34.77,M,78.20,M*03 +{"class":"TPV","tag":"SS2-20","time":1246686718.000,"ept":0.005,"lat":53.563090773,"lon":-113.439570082,"alt":631.184,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,39,09,18,156,00,30,16,073,28,23,15,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":39,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055158,5333.7855,N,11326.3742,W,1,05,3.10,631.19,M,,,*24 +$GPRMC,055158,A,5333.7855,N,11326.3742,W,0.0000,0.000,040709,,*35 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055158,31.24,M,34.77,M,78.20,M*0C +{"class":"TPV","tag":"SS2-20","time":1246686719.000,"ept":0.005,"lat":53.563091249,"lon":-113.439570226,"alt":631.195,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,39,09,18,156,00,30,16,073,28,23,15,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":39,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055159,5333.7855,N,11326.3742,W,1,05,3.10,631.20,M,,,*2F +$GPRMC,055159,A,5333.7855,N,11326.3742,W,0.0000,0.000,040709,,*34 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055159,31.24,M,34.77,M,78.20,M*0D +{"class":"TPV","tag":"SS2-20","time":1246686720.000,"ept":0.005,"lat":53.563091805,"lon":-113.439570324,"alt":631.199,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,37,03,41,063,38*75 +$GPGSV,3,2,12,28,22,023,39,09,18,156,00,30,16,073,28,23,15,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,32*75 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":37,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":39,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055200,5333.7856,N,11326.3742,W,1,05,3.10,631.24,M,,,*27 +$GPRMC,055200,A,5333.7856,N,11326.3742,W,0.0000,0.000,040709,,*38 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055200,31.24,M,34.77,M,78.20,M*02 +{"class":"TPV","tag":"SS2-20","time":1246686721.000,"ept":0.005,"lat":53.563092588,"lon":-113.439570470,"alt":631.244,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,39,09,18,156,00,30,16,073,28,23,15,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":39,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055201,5333.7856,N,11326.3742,W,1,05,3.10,631.32,M,,,*21 +$GPRMC,055201,A,5333.7856,N,11326.3742,W,0.0000,0.000,040709,,*39 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055201,31.24,M,34.77,M,78.20,M*03 +{"class":"TPV","tag":"SS2-20","time":1246686722.000,"ept":0.005,"lat":53.563093592,"lon":-113.439570561,"alt":631.323,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,37,03,41,063,38*75 +$GPGSV,3,2,12,28,22,023,39,09,18,156,00,30,16,073,28,23,15,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":37,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":39,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055202,5333.7857,N,11326.3742,W,1,05,3.10,631.41,M,,,*27 +$GPRMC,055202,A,5333.7857,N,11326.3742,W,0.0000,0.000,040709,,*3B +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055202,31.24,M,34.77,M,78.20,M*00 +{"class":"TPV","tag":"SS2-20","time":1246686723.000,"ept":0.005,"lat":53.563094650,"lon":-113.439570596,"alt":631.410,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,39,09,18,156,00,30,16,073,28,23,15,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,32*75 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":39,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055203,5333.7858,N,11326.3742,W,1,05,3.10,631.53,M,,,*2A +$GPRMC,055203,A,5333.7858,N,11326.3742,W,0.0000,0.000,040709,,*35 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055203,31.24,M,34.77,M,78.20,M*01 +{"class":"TPV","tag":"SS2-20","time":1246686724.000,"ept":0.005,"lat":53.563095871,"lon":-113.439570650,"alt":631.528,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,39,09,18,156,00,30,16,073,28,23,15,223,00*74 +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,32*75 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":39,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055204,5333.7858,N,11326.3742,W,1,05,3.10,631.66,M,,,*2B +$GPRMC,055204,A,5333.7858,N,11326.3742,W,0.0000,0.000,040709,,*32 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055204,31.24,M,34.77,M,78.20,M*06 +{"class":"TPV","tag":"SS2-20","time":1246686725.000,"ept":0.005,"lat":53.563097163,"lon":-113.439570712,"alt":631.660,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,40,09,18,156,00,30,16,073,28,23,15,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,32*75 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":40,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055205,5333.7859,N,11326.3742,W,1,05,3.10,631.82,M,,,*21 +$GPRMC,055205,A,5333.7859,N,11326.3742,W,0.0000,0.000,040709,,*32 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055205,31.24,M,34.77,M,78.20,M*07 +{"class":"TPV","tag":"SS2-20","time":1246686726.000,"ept":0.005,"lat":53.563098592,"lon":-113.439570797,"alt":631.816,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,40,09,18,156,00,30,16,073,28,23,15,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":40,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055206,5333.7860,N,11326.3742,W,1,05,3.10,631.97,M,,,*2C +$GPRMC,055206,A,5333.7860,N,11326.3742,W,0.0000,0.000,040709,,*3B +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055206,31.24,M,34.77,M,78.20,M*04 +{"class":"TPV","tag":"SS2-20","time":1246686727.000,"ept":0.005,"lat":53.563099872,"lon":-113.439570794,"alt":631.966,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,40,09,18,156,00,30,16,073,28,23,15,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,32*75 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":40,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055207,5333.7861,N,11326.3742,W,1,05,3.10,632.11,M,,,*21 +$GPRMC,055207,A,5333.7861,N,11326.3742,W,0.0000,0.000,040709,,*3B +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055207,31.24,M,34.77,M,78.20,M*05 +{"class":"TPV","tag":"SS2-20","time":1246686728.000,"ept":0.005,"lat":53.563101043,"lon":-113.439570776,"alt":632.114,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,47,11,67,211,50,29,55,029,38,03,41,063,38*75 +$GPGSV,3,2,12,28,22,023,40,09,18,156,00,30,16,073,28,23,15,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":47,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":40,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055208,5333.7861,N,11326.3742,W,1,05,3.10,632.27,M,,,*2B +$GPRMC,055208,A,5333.7861,N,11326.3742,W,0.0000,0.000,040709,,*34 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055208,31.24,M,34.77,M,78.20,M*0A +{"class":"TPV","tag":"SS2-20","time":1246686729.000,"ept":0.005,"lat":53.563102183,"lon":-113.439570719,"alt":632.265,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,48,11,67,211,50,29,55,029,38,03,41,063,38*7A +$GPGSV,3,2,12,28,22,023,40,09,18,156,00,30,16,073,28,23,15,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,32*75 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":48,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":40,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055209,5333.7862,N,11326.3742,W,1,05,3.10,632.42,M,,,*2A +$GPRMC,055209,A,5333.7862,N,11326.3742,W,0.0000,0.000,040709,,*36 +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055209,31.24,M,34.77,M,78.20,M*0B +{"class":"TPV","tag":"SS2-20","time":1246686730.000,"ept":0.005,"lat":53.563103262,"lon":-113.439570604,"alt":632.416,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,47,11,67,211,50,29,55,029,38,03,41,063,38*75 +$GPGSV,3,2,12,28,22,023,40,09,18,156,00,30,16,073,28,23,15,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":47,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":40,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055210,5333.7863,N,11326.3742,W,1,05,3.10,632.57,M,,,*27 +$GPRMC,055210,A,5333.7863,N,11326.3742,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055210,31.24,M,34.77,M,78.20,M*03 +{"class":"TPV","tag":"SS2-20","time":1246686731.000,"ept":0.005,"lat":53.563104344,"lon":-113.439570428,"alt":632.574,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,46,11,67,211,50,29,55,029,38,03,41,063,39*75 +$GPGSV,3,2,12,28,22,023,40,09,18,156,00,30,16,073,29,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":46,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":40,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":29,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055211,5333.7863,N,11326.3742,W,1,05,3.10,632.72,M,,,*21 +$GPRMC,055211,A,5333.7863,N,11326.3742,W,0.0000,0.000,040709,,*3E +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055211,31.24,M,34.77,M,78.20,M*02 +{"class":"TPV","tag":"SS2-20","time":1246686732.000,"ept":0.005,"lat":53.563105351,"lon":-113.439570188,"alt":632.717,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,47,11,67,211,50,29,55,029,38,03,41,063,39*74 +$GPGSV,3,2,12,28,22,023,41,09,18,156,00,30,16,073,28,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":47,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":41,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":28,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055212,5333.7864,N,11326.3742,W,1,05,3.10,632.83,M,,,*2B +$GPRMC,055212,A,5333.7864,N,11326.3742,W,0.0000,0.000,040709,,*3A +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055212,31.24,M,34.77,M,78.20,M*01 +{"class":"TPV","tag":"SS2-20","time":1246686733.000,"ept":0.005,"lat":53.563106149,"lon":-113.439569852,"alt":632.833,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,47,11,67,211,50,29,55,029,38,03,41,063,39*74 +$GPGSV,3,2,12,28,22,023,40,09,18,156,00,30,16,073,29,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":47,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":40,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":29,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055213,5333.7864,N,11326.3742,W,1,05,3.10,632.94,M,,,*2C +$GPRMC,055213,A,5333.7864,N,11326.3742,W,0.0000,0.000,040709,,*3B +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055213,31.24,M,34.77,M,78.20,M*00 +{"class":"TPV","tag":"SS2-20","time":1246686734.000,"ept":0.005,"lat":53.563106855,"lon":-113.439569440,"alt":632.937,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,47,11,67,211,50,29,55,029,38,03,41,063,39*74 +$GPGSV,3,2,12,28,22,023,40,09,18,156,00,30,16,073,29,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":47,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":39,"used":true},{"PRN":28,"el":22,"az":23,"ss":40,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":29,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055214,5333.7865,N,11326.3741,W,1,05,3.10,633.04,M,,,*21 +$GPRMC,055214,A,5333.7865,N,11326.3741,W,0.0000,0.000,040709,,*3E +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055214,31.24,M,34.77,M,78.20,M*07 +{"class":"TPV","tag":"SS2-20","time":1246686735.000,"ept":0.005,"lat":53.563107573,"lon":-113.439568900,"alt":633.038,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,109,47,11,67,211,50,29,55,029,38,03,41,063,38*75 +$GPGSV,3,2,12,28,22,023,41,09,18,156,00,30,16,073,29,23,15,223,00*7A +$GPGSV,3,3,12,22,06,031,00,08,00,208,00,137,28,172,00,134,26,203,33*74 +{"class":"SKY","tag":"SS2-33","xdop":2.08,"ydop":2.32,"vdop":4.11,"tdop":3.56,"hdop":3.12,"gdop":6.27,"pdop":5.16,"satellites":[{"PRN":1,"el":75,"az":109,"ss":47,"used":true},{"PRN":11,"el":67,"az":211,"ss":50,"used":true},{"PRN":29,"el":55,"az":29,"ss":38,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":41,"used":true},{"PRN":9,"el":18,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":29,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":8,"el":0,"az":208,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055215,5333.7865,N,11326.3741,W,1,05,3.10,633.12,M,,,*27 +$GPRMC,055215,A,5333.7865,N,11326.3741,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.2,3.1,3.4*30 +$GPGBS,055215,31.24,M,34.77,M,78.20,M*06 +{"class":"TPV","tag":"SS2-20","time":1246686736.000,"ept":0.005,"lat":53.563108215,"lon":-113.439568241,"alt":633.123,"epx":31.236,"epy":34.774,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.55,"mode":3} +$GPGSV,3,1,12,01,75,108,47,11,67,210,50,29,56,029,37,03,41,063,38*79 +$GPGSV,3,2,12,28,22,023,41,09,19,156,00,30,16,073,29,23,15,223,00*7B +$GPGSV,3,3,12,22,06,031,00,12,00,063,00,137,28,172,00,134,26,203,33*70 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.29,"vdop":4.04,"tdop":3.51,"hdop":3.10,"gdop":6.18,"pdop":5.09,"satellites":[{"PRN":1,"el":75,"az":108,"ss":47,"used":true},{"PRN":11,"el":67,"az":210,"ss":50,"used":true},{"PRN":29,"el":56,"az":29,"ss":37,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":41,"used":true},{"PRN":9,"el":19,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":29,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":12,"el":0,"az":63,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":33,"used":false}]} +$GPGGA,055216,5333.7865,N,11326.3741,W,1,05,3.10,633.20,M,,,*25 +$GPRMC,055216,A,5333.7865,N,11326.3741,W,0.0000,0.000,040709,,*3C +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.1,3.1,3.4*33 +$GPGBS,055216,31.42,M,34.35,M,78.20,M*03 +{"class":"TPV","tag":"SS2-20","time":1246686737.000,"ept":0.005,"lat":53.563108874,"lon":-113.439567501,"alt":633.204,"epx":31.422,"epy":34.350,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":69.12,"mode":3} +$GPGSV,3,1,12,01,75,108,47,11,67,210,50,29,56,029,37,03,41,063,38*79 +$GPGSV,3,2,12,28,22,023,41,09,19,156,00,30,16,073,30,23,15,223,00*73 +$GPGSV,3,3,12,22,06,031,00,12,00,063,00,137,28,172,00,134,26,203,32*71 +{"class":"SKY","tag":"SS2-33","xdop":2.09,"ydop":2.29,"vdop":4.04,"tdop":3.51,"hdop":3.10,"gdop":6.18,"pdop":5.09,"satellites":[{"PRN":1,"el":75,"az":108,"ss":47,"used":true},{"PRN":11,"el":67,"az":210,"ss":50,"used":true},{"PRN":29,"el":56,"az":29,"ss":37,"used":true},{"PRN":3,"el":41,"az":63,"ss":38,"used":true},{"PRN":28,"el":22,"az":23,"ss":41,"used":true},{"PRN":9,"el":19,"az":156,"ss":0,"used":false},{"PRN":30,"el":16,"az":73,"ss":30,"used":false},{"PRN":23,"el":15,"az":223,"ss":0,"used":false},{"PRN":22,"el":6,"az":31,"ss":0,"used":false},{"PRN":12,"el":0,"az":63,"ss":0,"used":false},{"PRN":137,"el":28,"az":172,"ss":0,"used":false},{"PRN":134,"el":26,"az":203,"ss":32,"used":false}]} +$GPGGA,055217,5333.7866,N,11326.3740,W,1,05,3.10,633.29,M,,,*2F +$GPRMC,055217,A,5333.7866,N,11326.3740,W,0.0000,0.000,040709,,*3F +$GPGSA,A,3,01,11,29,03,28,30,,,,,,,5.1,3.1,3.4*33 +$GPGBS,055217,31.42,M,34.35,M,78.20,M*02 +{"class":"TPV","tag":"SS2-20","time":1246686738.000,"ept":0.005,"lat":53.563109581,"lon":-113.439566739,"alt":633.290,"epx":31.422,"epy":34.350,"epv":78.200,"track":0.0000,"speed":0.000,"climb":0.000,"eps":68.70,"mode":3} diff --git a/test/daemon/tn200-all.log b/test/daemon/tn200-all.log new file mode 100644 index 0000000..1267246 --- /dev/null +++ b/test/daemon/tn200-all.log @@ -0,0 +1,419 @@ +# Name: Rayming Tripnav TN-200 +# Chipset: SiRF-II +# Submitted-by: "Chris Kuethe" +# Date: 8 Jun 2005 +# Location: Edmonton, Alberta, CA 53N113W +# Comments - Nearby airports include YEG and YXD. This capture was done +# at 57600 baud with all SiRF-supported NMEA messages set to 1Hz. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGGA,000452.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*75 +$GPGLL,36000.0000,N,72000.0000,E,000452.981,V*10 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000452.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*32 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000453.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*74 +$GPGLL,36000.0000,N,72000.0000,E,000453.981,V*11 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000453.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*33 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000454.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGLL,36000.0000,N,72000.0000,E,000454.981,V*16 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000454.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*34 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000455.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGLL,36000.0000,N,72000.0000,E,000455.981,V*17 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000455.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000456.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGLL,36000.0000,N,72000.0000,E,000456.981,V*14 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000456.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000457.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGLL,36000.0000,N,72000.0000,E,000457.981,V*15 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,00,13,77,000,00,08,71,000,,22,65,000,00*7F +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,00*7B +$GPRMC,000457.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000458.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGLL,36000.0000,N,72000.0000,E,000458.981,V*1A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,31*79 +$GPRMC,000458.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*38 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000459.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGLL,36000.0000,N,72000.0000,E,000459.981,V*1B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,31*79 +$GPRMC,000459.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*39 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000500.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGLL,36000.0000,N,72000.0000,E,000500.981,V*16 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,31*79 +$GPRMC,000500.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*34 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000501.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGLL,36000.0000,N,72000.0000,E,000501.981,V*17 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,31*79 +$GPRMC,000501.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000502.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGLL,36000.0000,N,72000.0000,E,000502.981,V*14 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,31*79 +$GPRMC,000502.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000503.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGLL,36000.0000,N,72000.0000,E,000503.981,V*15 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,000503.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000504.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*77 +$GPGLL,36000.0000,N,72000.0000,E,000504.981,V*12 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,000504.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*30 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204300.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGLL,36000.0000,N,72000.0000,E,204300.329,V*1E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204300.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*34 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204301.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGLL,36000.0000,N,72000.0000,E,204301.329,V*1F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204301.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204302.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGLL,36000.0000,N,72000.0000,E,204302.329,V*1C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204302.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204303.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGLL,36000.0000,N,72000.0000,E,204303.329,V*1D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204303.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204304.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGLL,36000.0000,N,72000.0000,E,204304.329,V*1A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204304.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*30 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204305.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGLL,36000.0000,N,72000.0000,E,204305.329,V*1B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204305.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*31 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204306.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7D +$GPGLL,36000.0000,N,72000.0000,E,204306.329,V*18 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204306.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*32 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204307.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7C +$GPGLL,36000.0000,N,72000.0000,E,204307.329,V*19 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204307.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*33 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204308.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGLL,36000.0000,N,72000.0000,E,204308.328,V*17 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204308.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*3D +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204309.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGLL,36000.0000,N,72000.0000,E,204309.328,V*16 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204309.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*3C +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204310.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGLL,36000.0000,N,72000.0000,E,204310.328,V*1E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204310.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*34 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204311.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGLL,36000.0000,N,72000.0000,E,204311.328,V*1F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204311.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204312.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGLL,36000.0000,N,72000.0000,E,204312.328,V*1C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204312.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204313.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGLL,36000.0000,N,72000.0000,E,204313.328,V*1D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204313.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204314.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGLL,36000.0000,N,72000.0000,E,204314.328,V*1A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204314.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*30 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204315.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGLL,36000.0000,N,72000.0000,E,204315.328,V*1B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204315.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*31 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204316.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7D +$GPGLL,36000.0000,N,72000.0000,E,204316.328,V*18 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204316.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*32 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204317.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7C +$GPGLL,36000.0000,N,72000.0000,E,204317.328,V*19 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204317.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*33 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204318.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGLL,36000.0000,N,72000.0000,E,204318.328,V*16 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204318.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*3C +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204319.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGLL,36000.0000,N,72000.0000,E,204319.328,V*17 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204319.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*3D +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204320.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGLL,36000.0000,N,72000.0000,E,204320.328,V*1D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204320.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204321.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGLL,36000.0000,N,72000.0000,E,204321.328,V*1C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204321.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204322.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGLL,36000.0000,N,72000.0000,E,204322.328,V*1F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204322.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204323.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGLL,36000.0000,N,72000.0000,E,204323.328,V*1E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204323.328,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3C +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204324.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGLL,36000.0000,N,72000.0000,E,204324.327,V*16 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204324.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*34 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204325.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGLL,36000.0000,N,72000.0000,E,204325.327,V*17 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,48,11,56,000,,14,47,000,00,25,41,000,*73 +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204325.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204326.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGLL,36000.0000,N,72000.0000,E,204326.327,V*14 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,00,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204326.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204327.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGLL,36000.0000,N,72000.0000,E,204327.327,V*15 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,00,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204327.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204328.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGLL,36000.0000,N,72000.0000,E,204328.327,V*1A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,00,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204328.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*38 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204329.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGLL,36000.0000,N,72000.0000,E,204329.327,V*1B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,00,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204329.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*39 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204330.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*76 +$GPGLL,36000.0000,N,72000.0000,E,204330.327,V*13 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,00,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204330.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*31 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204331.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*77 +$GPGLL,36000.0000,N,72000.0000,E,204331.327,V*12 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,40,25,41,000,*78 +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204331.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*30 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204332.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*74 +$GPGLL,36000.0000,N,72000.0000,E,204332.327,V*11 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,41,25,41,000,*79 +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204332.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*33 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204333.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*75 +$GPGLL,36000.0000,N,72000.0000,E,204333.327,V*10 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,40,25,41,000,*78 +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204333.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*32 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A diff --git a/test/daemon/tn200-all.log.chk b/test/daemon/tn200-all.log.chk new file mode 100644 index 0000000..2ca52a4 --- /dev/null +++ b/test/daemon/tn200-all.log.chk @@ -0,0 +1,409 @@ +$GPGGA,000452.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*75 +$GPGLL,36000.0000,N,72000.0000,E,000452.981,V*10 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000452.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*32 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000453.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*74 +$GPGLL,36000.0000,N,72000.0000,E,000453.981,V*11 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000453.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*33 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000454.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGLL,36000.0000,N,72000.0000,E,000454.981,V*16 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000454.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*34 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000455.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGLL,36000.0000,N,72000.0000,E,000455.981,V*17 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000455.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000456.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGLL,36000.0000,N,72000.0000,E,000456.981,V*14 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000456.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000457.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGLL,36000.0000,N,72000.0000,E,000457.981,V*15 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,00,13,77,000,00,08,71,000,,22,65,000,00*7F +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,00*7B +$GPRMC,000457.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000458.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGLL,36000.0000,N,72000.0000,E,000458.981,V*1A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,31*79 +$GPRMC,000458.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*38 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000459.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGLL,36000.0000,N,72000.0000,E,000459.981,V*1B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,31*79 +$GPRMC,000459.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*39 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000500.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGLL,36000.0000,N,72000.0000,E,000500.981,V*16 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,31*79 +$GPRMC,000500.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*34 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000501.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGLL,36000.0000,N,72000.0000,E,000501.981,V*17 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,31*79 +$GPRMC,000501.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000502.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGLL,36000.0000,N,72000.0000,E,000502.981,V*14 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,31*79 +$GPRMC,000502.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000503.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGLL,36000.0000,N,72000.0000,E,000503.981,V*15 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,000503.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,000504.981,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*77 +$GPGLL,36000.0000,N,72000.0000,E,000504.981,V*12 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,000504.981,V,36000.0000,N,72000.0000,E,0.000000,,190120,,*30 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204300.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGLL,36000.0000,N,72000.0000,E,204300.329,V*1E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204300.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*34 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204301.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGLL,36000.0000,N,72000.0000,E,204301.329,V*1F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204301.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204302.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGLL,36000.0000,N,72000.0000,E,204302.329,V*1C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204302.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204303.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGLL,36000.0000,N,72000.0000,E,204303.329,V*1D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204303.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204304.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGLL,36000.0000,N,72000.0000,E,204304.329,V*1A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204304.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*30 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204305.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGLL,36000.0000,N,72000.0000,E,204305.329,V*1B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204305.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*31 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204306.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7D +$GPGLL,36000.0000,N,72000.0000,E,204306.329,V*18 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204306.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*32 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204307.329,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7C +$GPGLL,36000.0000,N,72000.0000,E,204307.329,V*19 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204307.329,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*33 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204308.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGLL,36000.0000,N,72000.0000,E,204308.328,V*17 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204308.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*3D +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204309.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGLL,36000.0000,N,72000.0000,E,204309.328,V*16 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204309.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*3C +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204310.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGLL,36000.0000,N,72000.0000,E,204310.328,V*1E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204310.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*34 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204311.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGLL,36000.0000,N,72000.0000,E,204311.328,V*1F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204311.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204312.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGLL,36000.0000,N,72000.0000,E,204312.328,V*1C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204312.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204313.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGLL,36000.0000,N,72000.0000,E,204313.328,V*1D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204313.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204314.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGLL,36000.0000,N,72000.0000,E,204314.328,V*1A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204314.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*30 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204315.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGLL,36000.0000,N,72000.0000,E,204315.328,V*1B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204315.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*31 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204316.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7D +$GPGLL,36000.0000,N,72000.0000,E,204316.328,V*18 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204316.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*32 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204317.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7C +$GPGLL,36000.0000,N,72000.0000,E,204317.328,V*19 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,48,13,77,000,00,08,71,000,,22,65,000,00*73 +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204317.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*33 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204318.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGLL,36000.0000,N,72000.0000,E,204318.328,V*16 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204318.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*3C +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204319.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGLL,36000.0000,N,72000.0000,E,204319.328,V*17 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204319.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*3D +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204320.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGLL,36000.0000,N,72000.0000,E,204320.328,V*1D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204320.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204321.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGLL,36000.0000,N,72000.0000,E,204321.328,V*1C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204321.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204322.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGLL,36000.0000,N,72000.0000,E,204322.328,V*1F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204322.328,V,36000.0000,N,72000.0000,E,0.000000,,220120,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204323.328,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGLL,36000.0000,N,72000.0000,E,204323.328,V*1E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,90,000,47,13,77,000,00,08,71,000,,22,65,000,00*7C +$GPGSV,3,2,12,09,65,000,00,26,40,000,,24,33,000,00,04,28,000,00*79 +$GPGSV,3,3,12,27,25,000,00,16,23,000,00,15,21,000,00,11,13,000,*7B +$GPRMC,204323.328,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3C +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204324.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGLL,36000.0000,N,72000.0000,E,204324.327,V*16 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204324.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*34 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204325.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGLL,36000.0000,N,72000.0000,E,204325.327,V*17 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,48,11,56,000,,14,47,000,00,25,41,000,*73 +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204325.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*35 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204326.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGLL,36000.0000,N,72000.0000,E,204326.327,V*14 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,00,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204326.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*36 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204327.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGLL,36000.0000,N,72000.0000,E,204327.327,V*15 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,00,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204327.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*37 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204328.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGLL,36000.0000,N,72000.0000,E,204328.327,V*1A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,00,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204328.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*38 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204329.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGLL,36000.0000,N,72000.0000,E,204329.327,V*1B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,00,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204329.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*39 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204330.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*76 +$GPGLL,36000.0000,N,72000.0000,E,204330.327,V*13 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,00,25,41,000,*7C +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204330.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*31 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204331.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*77 +$GPGLL,36000.0000,N,72000.0000,E,204331.327,V*12 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,40,25,41,000,*78 +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204331.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*30 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204332.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*74 +$GPGLL,36000.0000,N,72000.0000,E,204332.327,V*11 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,41,25,41,000,*79 +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204332.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*33 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A +$GPGGA,204333.327,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*75 +$GPGLL,36000.0000,N,72000.0000,E,204333.327,V*10 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,01,89,000,47,11,56,000,,14,47,000,40,25,41,000,*78 +$GPGSV,3,2,12,19,21,000,00,20,21,000,,22,18,000,00,03,05,000,*7E +$GPGSV,3,3,12,23,02,000,00,15,00,000,00,07,00,000,00,24,-01,000,00*50 +$GPRMC,204333.327,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*32 +$GPVTG,,T,,M,0.000000,N,0.000000,K*4E +$GPMSS,0,0,0.000000,200,*5A diff --git a/test/daemon/tn200.log b/test/daemon/tn200.log new file mode 100644 index 0000000..20cb3a2 --- /dev/null +++ b/test/daemon/tn200.log @@ -0,0 +1,227 @@ +# Name: Rayming Tripnav TN-200 +# Chipset: SiRF-II +# Submitted-by: "Chris Kuethe" +# Date: 8 Jun 2005 +# Location: Edmonton, Alberta, CA 53N113W +# Comments - Nearby airports include YEG and YXD. This capture was done +# at 4800 baud with the SiRF default NMEA message set. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPGGA,000416.984,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000416.984,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3B +$GPGGA,000417.984,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000417.984,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3A +$GPGGA,000418.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000418.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*32 +$GPGGA,000419.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000419.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*33 +$GPGGA,000420.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000420.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*39 +$GPGGA,000421.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000421.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*38 +$GPGGA,000422.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000422.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3B +$GPGGA,000423.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000423.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3A +$GPGGA,000424.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*76 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000424.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3D +$GPGGA,000425.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*77 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000425.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3C +$GPGGA,000426.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*74 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,89,000,36,27,89,000,00,08,79,000,,26,79,000,00*73 +$GPGSV,3,2,12,01,62,000,46,05,57,000,00,22,42,000,00,13,32,000,00*7E +$GPGSV,3,3,12,09,20,000,00,24,20,000,00,04,17,000,00,15,12,000,00*70 +$GPRMC,000426.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3F +$GPGGA,000427.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*75 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000427.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3E +$GPGGA,000428.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000428.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*31 +$GPGGA,000429.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000429.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*30 +$GPGGA,000430.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,000430.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*38 +$GPGGA,000431.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,89,000,36,27,89,000,00,08,79,000,,26,79,000,00*73 +$GPGSV,3,2,12,01,62,000,45,05,57,000,00,22,42,000,00,13,32,000,00*7D +$GPGSV,3,3,12,09,20,000,00,24,20,000,00,04,17,000,00,15,12,000,00*70 +$GPRMC,000431.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*39 +$GPGGA,204137.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204137.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3F +$GPGGA,204138.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*74 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204138.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*30 +$GPGGA,204139.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*75 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204139.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*31 +$GPGGA,204140.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204140.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3F +$GPGGA,204141.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,89,000,36,27,89,000,00,08,79,000,,26,79,000,00*73 +$GPGSV,3,2,12,01,62,000,46,05,57,000,00,22,42,000,00,13,32,000,00*7E +$GPGSV,3,3,12,09,20,000,00,24,20,000,00,04,17,000,00,15,12,000,00*70 +$GPRMC,204141.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3E +$GPGGA,204142.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204142.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3D +$GPGGA,204143.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204143.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3C +$GPGGA,204144.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204144.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3B +$GPGGA,204145.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204145.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3A +$GPGGA,204146.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,89,000,34,27,89,000,00,08,79,000,,26,79,000,00*71 +$GPGSV,3,2,12,01,62,000,45,05,57,000,00,22,42,000,40,13,32,000,00*79 +$GPGSV,3,3,12,09,20,000,00,24,20,000,00,04,17,000,00,15,12,000,00*70 +$GPRMC,204146.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*39 +$GPGGA,204147.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204147.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*38 +$GPGGA,204148.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204148.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*37 +$GPGGA,204149.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204149.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*36 +$GPGGA,204150.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204150.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3E +$GPGGA,204151.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,89,000,34,27,89,000,00,08,79,000,,26,79,000,00*71 +$GPGSV,3,2,12,01,62,000,45,05,57,000,00,22,42,000,41,13,32,000,00*78 +$GPGSV,3,3,12,09,20,000,00,24,20,000,00,04,17,000,00,15,12,000,00*70 +$GPRMC,204151.078,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3E +$GPGGA,204152.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204152.078,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3D +$GPGGA,204153.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204153.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3F +$GPGGA,204154.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204154.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*38 +$GPGGA,204155.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204155.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*39 +$GPGGA,204156.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,65,000,34,01,51,000,45,14,51,000,00,22,48,000,42*74 +$GPGSV,3,2,12,15,26,000,00,11,20,000,00,30,20,000,00,18,19,000,*79 +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204156.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3A +$GPGGA,204157.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204157.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3B +$GPGGA,204158.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204158.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*34 +$GPGGA,204159.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204159.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*35 +$GPGGA,204200.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204200.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3A +$GPGGA,204201.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,65,000,,01,51,000,45,14,51,000,00,22,48,000,44*75 +$GPGSV,3,2,12,15,26,000,00,11,20,000,00,30,20,000,00,18,19,000,*79 +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204201.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3B +$GPGGA,204202.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204202.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*38 +$GPGGA,204203.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204203.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*39 +$GPGGA,204204.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204204.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3E +$GPGGA,204205.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204205.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3F +$GPGGA,204206.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,65,000,,01,51,000,45,14,51,000,45,22,48,000,44*74 +$GPGSV,3,2,12,15,26,000,00,11,20,000,43,30,20,000,00,18,19,000,*7E +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204206.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3C +$GPGGA,204207.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204207.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3D +$GPGGA,204208.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204208.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3D +$GPGGA,204209.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204209.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3C +$GPGGA,204210.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204210.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*34 +$GPGGA,204211.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,65,000,,01,51,000,45,14,51,000,46,22,48,000,44*77 +$GPGSV,3,2,12,15,26,000,00,11,20,000,42,30,20,000,00,18,19,000,*7F +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204211.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*35 +$GPGGA,204212.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204212.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*36 +$GPGGA,204213.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204213.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*37 +$GPGGA,204214.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*77 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204214.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*30 +$GPGGA,204215.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*76 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204215.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*31 +$GPGGA,204216.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*75 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,65,000,,01,51,000,44,14,51,000,46,22,48,000,44*76 +$GPGSV,3,2,12,15,26,000,00,11,20,000,42,30,20,000,00,18,19,000,*7F +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204216.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*32 +$GPGGA,204217.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*74 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204217.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*33 +$GPGGA,204218.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204218.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3C +$GPGGA,204219.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204219.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3D +$GPGGA,204220.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPRMC,204220.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*37 +$GPGGA,204221.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +$GPGSV,3,1,12,25,65,000,,01,51,000,44,14,51,000,46,22,48,000,43*71 +$GPGSV,3,2,12,15,26,000,00,11,20,000,42,30,20,000,00,18,19,000,*7F +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204221.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*36 diff --git a/test/daemon/tn200.log.chk b/test/daemon/tn200.log.chk new file mode 100644 index 0000000..600cc3f --- /dev/null +++ b/test/daemon/tn200.log.chk @@ -0,0 +1,277 @@ +$GPGGA,000416.984,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000416.984,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3B +$GPGGA,000417.984,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000417.984,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3A +$GPGGA,000418.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000418.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*32 +$GPGGA,000419.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000419.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*33 +$GPGGA,000420.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000420.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*39 +$GPGGA,000421.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000421.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*38 +$GPGGA,000422.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000422.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3B +$GPGGA,000423.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000423.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3A +$GPGGA,000424.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*76 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000424.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3D +$GPGGA,000425.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*77 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000425.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3C +$GPGGA,000426.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*74 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,89,000,36,27,89,000,00,08,79,000,,26,79,000,00*73 +$GPGSV,3,2,12,01,62,000,46,05,57,000,00,22,42,000,00,13,32,000,00*7E +$GPGSV,3,3,12,09,20,000,00,24,20,000,00,04,17,000,00,15,12,000,00*70 +$GPRMC,000426.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3F +$GPGGA,000427.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*75 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000427.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*3E +$GPGGA,000428.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000428.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*31 +$GPGGA,000429.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000429.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*30 +$GPGGA,000430.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,000430.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*38 +$GPGGA,000431.983,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,89,000,36,27,89,000,00,08,79,000,,26,79,000,00*73 +$GPGSV,3,2,12,01,62,000,45,05,57,000,00,22,42,000,00,13,32,000,00*7D +$GPGSV,3,3,12,09,20,000,00,24,20,000,00,04,17,000,00,15,12,000,00*70 +$GPRMC,000431.983,V,36000.0000,N,72000.0000,E,0.000000,,260120,,*39 +$GPGGA,204137.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204137.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3F +$GPGGA,204138.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*74 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204138.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*30 +$GPGGA,204139.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*75 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204139.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*31 +$GPGGA,204140.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204140.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3F +$GPGGA,204141.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,89,000,36,27,89,000,00,08,79,000,,26,79,000,00*73 +$GPGSV,3,2,12,01,62,000,46,05,57,000,00,22,42,000,00,13,32,000,00*7E +$GPGSV,3,3,12,09,20,000,00,24,20,000,00,04,17,000,00,15,12,000,00*70 +$GPRMC,204141.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3E +$GPGGA,204142.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204142.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3D +$GPGGA,204143.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204143.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3C +$GPGGA,204144.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204144.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3B +$GPGGA,204145.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204145.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3A +$GPGGA,204146.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,89,000,34,27,89,000,00,08,79,000,,26,79,000,00*71 +$GPGSV,3,2,12,01,62,000,45,05,57,000,00,22,42,000,40,13,32,000,00*79 +$GPGSV,3,3,12,09,20,000,00,24,20,000,00,04,17,000,00,15,12,000,00*70 +$GPRMC,204146.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*39 +$GPGGA,204147.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204147.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*38 +$GPGGA,204148.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204148.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*37 +$GPGGA,204149.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204149.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*36 +$GPGGA,204150.079,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204150.079,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3E +$GPGGA,204151.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,89,000,34,27,89,000,00,08,79,000,,26,79,000,00*71 +$GPGSV,3,2,12,01,62,000,45,05,57,000,00,22,42,000,41,13,32,000,00*78 +$GPGSV,3,3,12,09,20,000,00,24,20,000,00,04,17,000,00,15,12,000,00*70 +$GPRMC,204151.078,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3E +$GPGGA,204152.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204152.078,V,36000.0000,N,72000.0000,E,0.000000,,290120,,*3D +$GPGGA,204153.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204153.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3F +$GPGGA,204154.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204154.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*38 +$GPGGA,204155.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204155.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*39 +$GPGGA,204156.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,65,000,34,01,51,000,45,14,51,000,00,22,48,000,42*74 +$GPGSV,3,2,12,15,26,000,00,11,20,000,00,30,20,000,00,18,19,000,*79 +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204156.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3A +$GPGGA,204157.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204157.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3B +$GPGGA,204158.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204158.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*34 +$GPGGA,204159.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204159.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*35 +$GPGGA,204200.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7D +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204200.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3A +$GPGGA,204201.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7C +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,65,000,,01,51,000,45,14,51,000,00,22,48,000,44*75 +$GPGSV,3,2,12,15,26,000,00,11,20,000,00,30,20,000,00,18,19,000,*79 +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204201.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3B +$GPGGA,204202.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7F +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204202.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*38 +$GPGGA,204203.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7E +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204203.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*39 +$GPGGA,204204.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*79 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204204.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3E +$GPGGA,204205.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*78 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204205.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3F +$GPGGA,204206.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,65,000,,01,51,000,45,14,51,000,45,22,48,000,44*74 +$GPGSV,3,2,12,15,26,000,00,11,20,000,43,30,20,000,00,18,19,000,*7E +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204206.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3C +$GPGGA,204207.078,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204207.078,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3D +$GPGGA,204208.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204208.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3D +$GPGGA,204209.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204209.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3C +$GPGGA,204210.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*73 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204210.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*34 +$GPGGA,204211.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*72 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,65,000,,01,51,000,45,14,51,000,46,22,48,000,44*77 +$GPGSV,3,2,12,15,26,000,00,11,20,000,42,30,20,000,00,18,19,000,*7F +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204211.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*35 +$GPGGA,204212.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204212.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*36 +$GPGGA,204213.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204213.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*37 +$GPGGA,204214.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*77 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204214.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*30 +$GPGGA,204215.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*76 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204215.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*31 +$GPGGA,204216.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*75 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,65,000,,01,51,000,44,14,51,000,46,22,48,000,44*76 +$GPGSV,3,2,12,15,26,000,00,11,20,000,42,30,20,000,00,18,19,000,*7F +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204216.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*32 +$GPGGA,204217.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*74 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204217.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*33 +$GPGGA,204218.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7B +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204218.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3C +$GPGGA,204219.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*7A +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204219.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*3D +$GPGGA,204220.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*70 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPRMC,204220.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*37 +$GPGGA,204221.077,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*71 +$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,3,1,12,25,65,000,,01,51,000,44,14,51,000,46,22,48,000,43*71 +$GPGSV,3,2,12,15,26,000,00,11,20,000,42,30,20,000,00,18,19,000,*7F +$GPGSV,3,3,12,19,07,000,00,05,05,000,00,03,02,000,,16,-03,000,00*5D +$GPRMC,204221.077,V,36000.0000,N,72000.0000,E,0.000000,,080605,,*36 diff --git a/test/daemon/tn204.log b/test/daemon/tn204.log new file mode 100644 index 0000000..7a8a9df --- /dev/null +++ b/test/daemon/tn204.log @@ -0,0 +1,58 @@ +# Name: Rayming TripNav 204 +# Chipset: SiRF-II? +# Submitted-by: "Pascal F. Martin" +# Date: 18 Mar 2005 +# +# The NMEA looks like Garmin. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPRMC,230148,A,3348.605,N,11821.126,W,000.0,209.4,261002,013.8,E*6B +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,230149,3348.605,N,11821.126,W,1,05,1.7,49.4,M,-32.4,M,,*4E +$GPGSA,A,3,07,08,,,27,28,29,,,,,,4.2,1.7,3.8*32 +$GPGSV,2,1,08,07,43,197,44,08,68,062,43,11,18,089,00,26,24,314,43*73 +$GPGSV,2,2,08,27,48,103,46,28,66,323,42,29,33,306,43,31,10,040,00*78 +$PGRME,17.4,M,40.3,M,43.9,M*15 +$GPGLL,3348.605,N,11821.126,W,230149,A*34 +$PGRMZ,162,f,3*1E +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,230150,A,3348.606,N,11821.125,W,000.0,209.4,261002,013.8,E*62 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,230151,3348.607,N,11821.124,W,1,05,1.7,49.2,M,-32.4,M,,*41 +$GPGSA,A,3,07,08,,,27,28,29,,,,,,4.2,1.7,3.8*32 +$GPGSV,2,1,08,07,43,197,45,08,68,062,42,11,18,089,00,26,24,314,43*73 +$GPGSV,2,2,08,27,48,103,46,28,66,323,42,29,33,306,44,31,10,040,00*7F +$PGRME,17.4,M,40.3,M,43.9,M*15 +$GPGLL,3348.607,N,11821.124,W,230151,A*3D +$PGRMZ,161,f,3*1D +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,230152,A,3348.607,N,11821.124,W,000.0,209.4,261002,013.8,E*60 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,230153,3348.607,N,11821.124,W,1,05,1.7,49.1,M,-32.4,M,,*40 +$GPGSA,A,3,,08,,,,,29,,,,,,4.2,1.7,3.8*3A +$GPGSV,2,1,08,07,43,197,45,08,68,062,42,11,18,089,00,26,24,314,41*71 +$GPGSV,2,2,08,27,48,103,46,28,66,323,42,29,33,306,44,31,10,040,00*7F +$PGRME,17.4,M,40.3,M,43.9,M*15 +$GPGLL,3348.607,N,11821.124,W,230153,A*3F +$PGRMZ,161,f,3*1D +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,230154,A,3348.607,N,11821.124,W,000.0,209.4,261002,013.8,E*66 +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,230155,3348.608,N,11821.124,W,1,02,1.9,49.0,M,-32.4,M,,*41 +$GPGSA,A,3,07,08,,,27,28,,,,,,,1.9,1.9,1.0*33 +$GPGSV,2,1,08,07,43,197,45,08,68,062,43,11,18,089,00,26,24,314,41*70 +$GPGSV,2,2,08,27,48,103,46,28,66,323,43,29,33,306,44,31,10,040,00*7E +$PGRME,19.2,M,150.0,M,151.2,M*17 +$GPGLL,3348.608,N,11821.124,W,230155,A*36 +$PGRMZ,161,f,3*1D +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 diff --git a/test/daemon/tn204.log.chk b/test/daemon/tn204.log.chk new file mode 100644 index 0000000..4a82286 --- /dev/null +++ b/test/daemon/tn204.log.chk @@ -0,0 +1,59 @@ +$GPRMC,230148,A,3348.605,N,11821.126,W,000.0,209.4,261002,013.8,E*6B +{"class":"TPV","tag":"RMC","time":1035673308.000,"ept":0.005,"lat":33.810083333,"lon":-118.352100000,"track":209.4000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,230149,3348.605,N,11821.126,W,1,05,1.7,49.4,M,-32.4,M,,*4E +$GPGSA,A,3,07,08,,,27,28,29,,,,,,4.2,1.7,3.8*32 +$GPGSV,2,1,08,07,43,197,44,08,68,062,43,11,18,089,00,26,24,314,43*73 +$GPGSV,2,2,08,27,48,103,46,28,66,323,42,29,33,306,43,31,10,040,00*78 +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":1.11,"vdop":2.08,"tdop":1.37,"hdop":1.36,"gdop":2.83,"pdop":2.48,"satellites":[{"PRN":7,"el":43,"az":197,"ss":44,"used":true},{"PRN":8,"el":68,"az":62,"ss":43,"used":true},{"PRN":11,"el":18,"az":89,"ss":0,"used":false},{"PRN":26,"el":24,"az":314,"ss":43,"used":false},{"PRN":27,"el":48,"az":103,"ss":46,"used":true},{"PRN":28,"el":66,"az":323,"ss":42,"used":true},{"PRN":29,"el":33,"az":306,"ss":43,"used":true},{"PRN":31,"el":10,"az":40,"ss":0,"used":false}]} +$PGRME,17.4,M,40.3,M,43.9,M*15 +$GPGLL,3348.605,N,11821.126,W,230149,A*34 +$PGRMZ,162,f,3*1E +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,230150,A,3348.606,N,11821.125,W,000.0,209.4,261002,013.8,E*62 +{"class":"TPV","tag":"RMC","time":1035673310.000,"ept":0.005,"lat":33.810100000,"lon":-118.352083333,"epx":11.856,"epy":16.622,"track":209.4000,"speed":0.000,"eps":42.17,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,230151,3348.607,N,11821.124,W,1,05,1.7,49.2,M,-32.4,M,,*41 +$GPGSA,A,3,07,08,,,27,28,29,,,,,,4.2,1.7,3.8*32 +$GPGSV,2,1,08,07,43,197,45,08,68,062,42,11,18,089,00,26,24,314,43*73 +$GPGSV,2,2,08,27,48,103,46,28,66,323,42,29,33,306,44,31,10,040,00*7F +{"class":"SKY","tag":"GSV","xdop":0.79,"ydop":1.11,"vdop":2.08,"tdop":1.37,"hdop":1.36,"gdop":2.83,"pdop":2.48,"satellites":[{"PRN":7,"el":43,"az":197,"ss":45,"used":true},{"PRN":8,"el":68,"az":62,"ss":42,"used":true},{"PRN":11,"el":18,"az":89,"ss":0,"used":false},{"PRN":26,"el":24,"az":314,"ss":43,"used":false},{"PRN":27,"el":48,"az":103,"ss":46,"used":true},{"PRN":28,"el":66,"az":323,"ss":42,"used":true},{"PRN":29,"el":33,"az":306,"ss":44,"used":true},{"PRN":31,"el":10,"az":40,"ss":0,"used":false}]} +$PGRME,17.4,M,40.3,M,43.9,M*15 +$GPGLL,3348.607,N,11821.124,W,230151,A*3D +{"class":"TPV","tag":"GLL","time":1035673311.000,"ept":0.005,"lat":33.810116667,"lon":-118.352066667,"alt":49.200,"epx":25.546,"epy":25.546,"epv":83.674,"speed":2.408,"climb":0.000,"eps":33.24,"mode":3} +$PGRMZ,161,f,3*1D +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,230152,A,3348.607,N,11821.124,W,000.0,209.4,261002,013.8,E*60 +{"class":"TPV","tag":"RMC","time":1035673312.000,"ept":0.005,"lat":33.810116667,"lon":-118.352066667,"epx":11.856,"epy":16.622,"track":209.4000,"speed":0.000,"eps":42.17,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,230153,3348.607,N,11821.124,W,1,05,1.7,49.1,M,-32.4,M,,*40 +$GPGSA,A,3,,08,,,,,29,,,,,,4.2,1.7,3.8*3A +$GPGSV,2,1,08,07,43,197,45,08,68,062,42,11,18,089,00,26,24,314,41*71 +$GPGSV,2,2,08,27,48,103,46,28,66,323,42,29,33,306,44,31,10,040,00*7F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":7,"el":43,"az":197,"ss":45,"used":false},{"PRN":8,"el":68,"az":62,"ss":42,"used":true},{"PRN":11,"el":18,"az":89,"ss":0,"used":false},{"PRN":26,"el":24,"az":314,"ss":41,"used":false},{"PRN":27,"el":48,"az":103,"ss":46,"used":false},{"PRN":28,"el":66,"az":323,"ss":42,"used":false},{"PRN":29,"el":33,"az":306,"ss":44,"used":true},{"PRN":31,"el":10,"az":40,"ss":0,"used":false}]} +$PGRME,17.4,M,40.3,M,43.9,M*15 +$GPGLL,3348.607,N,11821.124,W,230153,A*3F +{"class":"TPV","tag":"GLL","time":1035673313.000,"ept":0.005,"lat":33.810116667,"lon":-118.352066667,"alt":49.100,"epx":25.546,"epy":25.546,"epv":83.674,"speed":0.000,"climb":0.000,"eps":33.24,"mode":3} +$PGRMZ,161,f,3*1D +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 +$GPRMC,230154,A,3348.607,N,11821.124,W,000.0,209.4,261002,013.8,E*66 +{"class":"TPV","tag":"RMC","time":1035673314.000,"ept":0.005,"lat":33.810116667,"lon":-118.352066667,"track":209.4000,"speed":0.000,"mode":2} +$GPRMB,A,,,,,,,,,,,,V*71 +$GPGGA,230155,3348.608,N,11821.124,W,1,02,1.9,49.0,M,-32.4,M,,*41 +$GPGSA,A,3,07,08,,,27,28,,,,,,,1.9,1.9,1.0*33 +$GPGSV,2,1,08,07,43,197,45,08,68,062,43,11,18,089,00,26,24,314,41*70 +$GPGSV,2,2,08,27,48,103,46,28,66,323,43,29,33,306,44,31,10,040,00*7E +{"class":"SKY","tag":"GSV","xdop":0.85,"ydop":1.11,"vdop":2.17,"tdop":1.38,"hdop":1.40,"gdop":2.93,"pdop":2.58,"satellites":[{"PRN":7,"el":43,"az":197,"ss":45,"used":true},{"PRN":8,"el":68,"az":62,"ss":43,"used":true},{"PRN":11,"el":18,"az":89,"ss":0,"used":false},{"PRN":26,"el":24,"az":314,"ss":41,"used":false},{"PRN":27,"el":48,"az":103,"ss":46,"used":true},{"PRN":28,"el":66,"az":323,"ss":43,"used":true},{"PRN":29,"el":33,"az":306,"ss":44,"used":false},{"PRN":31,"el":10,"az":40,"ss":0,"used":false}]} +$PGRME,19.2,M,150.0,M,151.2,M*17 +$GPGLL,3348.608,N,11821.124,W,230155,A*36 +{"class":"TPV","tag":"GLL","time":1035673315.000,"ept":0.005,"lat":33.810133333,"lon":-118.352066667,"alt":49.000,"epx":28.188,"epy":28.188,"epv":311.441,"speed":1.849,"climb":0.000,"mode":3} +$PGRMZ,161,f,3*1D +$PGRMM,NAD83*29 +$GPBOD,,T,,M,,*47 +$GPRTE,1,1,c,0*07 diff --git a/test/daemon/tnt-revolution.log b/test/daemon/tnt-revolution.log new file mode 100644 index 0000000..9ac7913 --- /dev/null +++ b/test/daemon/tnt-revolution.log @@ -0,0 +1,71 @@ +# Name: TNT Revolution +# Chipset: TNT +# Submitted-by: Eric S. Raymond +# Date: 10 Apr 2010 +# Location: Unknown +# Notes: Collected remotely from jon Schleuter's nog.yazug.com +# Can't be transmitting angles in degrees, heading figures are too large. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$PTNTHTM,14223,N,169,N,-43,N,13641,2454*15 +$PTNTHTM,14091,N,171,N,-43,N,13599,2454*11 +$PTNTHTM,14287,N,172,N,-39,N,13652,2452*18 +$PTNTHTM,14150,N,171,N,-40,N,13605,2452*1E +$PTNTHTM,14199,N,171,N,-40,N,13614,2452*1B +$HCXDR,A,171,D,PITCH,A,-37,D,ROLL,G,367,,MAGX,G,2420,,MAGY,G,-8984,,MAGZ*41 +$PTNTHTM,14168,N,171,N,-37,N,13615,2451*17 +$PTNTHTM,14359,N,172,N,-33,N,13647,2450*16 +$PTNTHTM,14243,N,172,N,-33,N,13608,2450*17 +$PTNTHTM,14340,N,176,N,-37,N,13616,2451*1B +$PTNTHTM,14230,N,175,N,-37,N,13597,2451*14 +$HCXDR,A,180,D,PITCH,A,-39,D,ROLL,G,389,,MAGX,G,2473,,MAGY,G,-9007,,MAGZ*44 +$PTNTHTM,14224,N,178,N,-42,N,13599,2452*13 +$PTNTHTM,14156,N,179,N,-42,N,13600,2452*17 +$PTNTHTM,14157,N,175,N,-42,N,13585,2454*12 +$PTNTHTM,14159,N,175,N,-42,N,13598,2454*10 +$PTNTHTM,14159,N,170,N,-40,N,13569,2455*18 +$HCXDR,A,170,D,PITCH,A,-40,D,ROLL,G,360,,MAGX,G,2419,,MAGY,G,-8947,,MAGZ*42 +$PTNTHTM,14199,N,170,N,-40,N,13610,2454*18 +$PTNTHTM,14094,N,167,N,-40,N,13571,2455*17 +$PTNTHTM,14185,N,167,N,-43,N,13626,2454*15 +$PTNTHTM,14043,N,169,N,-42,N,13592,2454*1D +$PTNTHTM,14236,N,169,N,-45,N,13644,2453*15 +$HCXDR,A,169,D,PITCH,A,-45,D,ROLL,G,352,,MAGX,G,2382,,MAGY,G,-8909,,MAGZ*41 +$PTNTHTM,14061,N,172,N,-45,N,13599,2452*1D +$PTNTHTM,14299,N,171,N,-42,N,13652,2450*1A +$PTNTHTM,14149,N,170,N,-43,N,13605,2450*16 +$PTNTHTM,14243,N,170,N,-39,N,13622,2450*17 +$PTNTHTM,14155,N,172,N,-35,N,13611,2449*15 +$HCXDR,A,172,D,PITCH,A,-37,D,ROLL,G,359,,MAGX,G,2433,,MAGY,G,-9009,,MAGZ*40 +$PTNTHTM,14330,N,172,N,-32,N,13647,2448*11 +$PTNTHTM,14239,N,171,N,-33,N,13612,2448*1B +$PTNTHTM,14182,N,174,N,-34,N,13581,2449*12 +$PTNTHTM,14256,N,174,N,-37,N,13602,2449*13 +$PTNTHTM,14139,N,178,N,-38,N,13568,2450*1D +$HCXDR,A,177,D,PITCH,A,-40,D,ROLL,G,358,,MAGX,G,2432,,MAGY,G,-8974,,MAGZ*47 +$PTNTHTM,14193,N,177,N,-40,N,13604,2450*14 +$PTNTHTM,14186,N,174,N,-42,N,13590,2451*1E +$PTNTHTM,14174,N,174,N,-40,N,13602,2451*19 +$PTNTHTM,14094,N,172,N,-40,N,13570,2452*15 +$PTNTHTM,14232,N,169,N,-42,N,13609,2452*1E +$HCXDR,A,169,D,PITCH,A,-42,D,ROLL,G,371,,MAGX,G,2430,,MAGY,G,-8925,,MAGZ*47 +$PTNTHTM,14134,N,165,N,-42,N,13570,2452*1A +$PTNTHTM,14225,N,165,N,-43,N,13632,2452*1D +$PTNTHTM,14042,N,169,N,-43,N,13588,2451*13 +$PTNTHTM,14222,N,170,N,-45,N,13646,2451*18 +$PTNTHTM,14174,N,170,N,-45,N,13640,2450*1F +$HCXDR,A,170,D,PITCH,A,-42,D,ROLL,G,341,,MAGX,G,2404,,MAGY,G,-8961,,MAGZ*4B +$PTNTHTM,14264,N,170,N,-42,N,13636,2449*13 +$PTNTHTM,14132,N,171,N,-42,N,13604,2448*12 +$PTNTHTM,14265,N,171,N,-38,N,13629,2448*11 +$PTNTHTM,14145,N,171,N,-38,N,13612,2447*17 +$PTNTHTM,14198,N,172,N,-38,N,13614,2447*12 +$HCXDR,A,172,D,PITCH,A,-34,D,ROLL,G,327,,MAGX,G,2389,,MAGY,G,-8997,,MAGZ*43 +$PTNTHTM,14184,N,172,N,-35,N,13612,2446*15 +$PTNTHTM,14187,N,174,N,-35,N,13589,2447*10 +$PTNTHTM,14257,N,174,N,-35,N,13603,2447*1F +$PTNTHTM,14161,N,178,N,-37,N,13575,2448*1A +$PTNTHTM,14302,N,177,N,-40,N,13608,2448*1B +$HCXDR,A,176,D,PITCH,A,-40,D,ROLL,G,388,,MAGX,G,2468,,MAGY,G,-9006,,MAGZ*49 diff --git a/test/daemon/tnt-revolution.log.chk b/test/daemon/tnt-revolution.log.chk new file mode 100644 index 0000000..5f0c15f --- /dev/null +++ b/test/daemon/tnt-revolution.log.chk @@ -0,0 +1,100 @@ +$PTNTHTM,14223,N,169,N,-43,N,13641,2454*15 +{"class":"ATT","tag":"PTNTHTM","heading":14223.00,"mag_st":"N","pitch":169.00,"pitch_st":"N","roll":-43.00,"roll_st":"N","dip":13641.000,"mag_x":2454.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14091,N,171,N,-43,N,13599,2454*11 +{"class":"ATT","tag":"PTNTHTM","heading":14091.00,"mag_st":"N","pitch":171.00,"pitch_st":"N","roll":-43.00,"roll_st":"N","dip":13599.000,"mag_x":2454.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14287,N,172,N,-39,N,13652,2452*18 +{"class":"ATT","tag":"PTNTHTM","heading":14287.00,"mag_st":"N","pitch":172.00,"pitch_st":"N","roll":-39.00,"roll_st":"N","dip":13652.000,"mag_x":2452.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14150,N,171,N,-40,N,13605,2452*1E +{"class":"ATT","tag":"PTNTHTM","heading":14150.00,"mag_st":"N","pitch":171.00,"pitch_st":"N","roll":-40.00,"roll_st":"N","dip":13605.000,"mag_x":2452.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14199,N,171,N,-40,N,13614,2452*1B +{"class":"ATT","tag":"PTNTHTM","heading":14199.00,"mag_st":"N","pitch":171.00,"pitch_st":"N","roll":-40.00,"roll_st":"N","dip":13614.000,"mag_x":2452.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14168,N,171,N,-37,N,13615,2451*17 +{"class":"ATT","tag":"PTNTHTM","heading":14168.00,"mag_st":"N","pitch":171.00,"pitch_st":"N","roll":-37.00,"roll_st":"N","dip":13615.000,"mag_x":2451.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14359,N,172,N,-33,N,13647,2450*16 +{"class":"ATT","tag":"PTNTHTM","heading":14359.00,"mag_st":"N","pitch":172.00,"pitch_st":"N","roll":-33.00,"roll_st":"N","dip":13647.000,"mag_x":2450.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14243,N,172,N,-33,N,13608,2450*17 +{"class":"ATT","tag":"PTNTHTM","heading":14243.00,"mag_st":"N","pitch":172.00,"pitch_st":"N","roll":-33.00,"roll_st":"N","dip":13608.000,"mag_x":2450.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14340,N,176,N,-37,N,13616,2451*1B +{"class":"ATT","tag":"PTNTHTM","heading":14340.00,"mag_st":"N","pitch":176.00,"pitch_st":"N","roll":-37.00,"roll_st":"N","dip":13616.000,"mag_x":2451.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14230,N,175,N,-37,N,13597,2451*14 +{"class":"ATT","tag":"PTNTHTM","heading":14230.00,"mag_st":"N","pitch":175.00,"pitch_st":"N","roll":-37.00,"roll_st":"N","dip":13597.000,"mag_x":2451.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14224,N,178,N,-42,N,13599,2452*13 +{"class":"ATT","tag":"PTNTHTM","heading":14224.00,"mag_st":"N","pitch":178.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13599.000,"mag_x":2452.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14156,N,179,N,-42,N,13600,2452*17 +{"class":"ATT","tag":"PTNTHTM","heading":14156.00,"mag_st":"N","pitch":179.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13600.000,"mag_x":2452.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14157,N,175,N,-42,N,13585,2454*12 +{"class":"ATT","tag":"PTNTHTM","heading":14157.00,"mag_st":"N","pitch":175.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13585.000,"mag_x":2454.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14159,N,175,N,-42,N,13598,2454*10 +{"class":"ATT","tag":"PTNTHTM","heading":14159.00,"mag_st":"N","pitch":175.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13598.000,"mag_x":2454.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14159,N,170,N,-40,N,13569,2455*18 +{"class":"ATT","tag":"PTNTHTM","heading":14159.00,"mag_st":"N","pitch":170.00,"pitch_st":"N","roll":-40.00,"roll_st":"N","dip":13569.000,"mag_x":2455.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14199,N,170,N,-40,N,13610,2454*18 +{"class":"ATT","tag":"PTNTHTM","heading":14199.00,"mag_st":"N","pitch":170.00,"pitch_st":"N","roll":-40.00,"roll_st":"N","dip":13610.000,"mag_x":2454.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14094,N,167,N,-40,N,13571,2455*17 +{"class":"ATT","tag":"PTNTHTM","heading":14094.00,"mag_st":"N","pitch":167.00,"pitch_st":"N","roll":-40.00,"roll_st":"N","dip":13571.000,"mag_x":2455.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14185,N,167,N,-43,N,13626,2454*15 +{"class":"ATT","tag":"PTNTHTM","heading":14185.00,"mag_st":"N","pitch":167.00,"pitch_st":"N","roll":-43.00,"roll_st":"N","dip":13626.000,"mag_x":2454.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14043,N,169,N,-42,N,13592,2454*1D +{"class":"ATT","tag":"PTNTHTM","heading":14043.00,"mag_st":"N","pitch":169.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13592.000,"mag_x":2454.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14236,N,169,N,-45,N,13644,2453*15 +{"class":"ATT","tag":"PTNTHTM","heading":14236.00,"mag_st":"N","pitch":169.00,"pitch_st":"N","roll":-45.00,"roll_st":"N","dip":13644.000,"mag_x":2453.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14061,N,172,N,-45,N,13599,2452*1D +{"class":"ATT","tag":"PTNTHTM","heading":14061.00,"mag_st":"N","pitch":172.00,"pitch_st":"N","roll":-45.00,"roll_st":"N","dip":13599.000,"mag_x":2452.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14299,N,171,N,-42,N,13652,2450*1A +{"class":"ATT","tag":"PTNTHTM","heading":14299.00,"mag_st":"N","pitch":171.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13652.000,"mag_x":2450.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14149,N,170,N,-43,N,13605,2450*16 +{"class":"ATT","tag":"PTNTHTM","heading":14149.00,"mag_st":"N","pitch":170.00,"pitch_st":"N","roll":-43.00,"roll_st":"N","dip":13605.000,"mag_x":2450.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14243,N,170,N,-39,N,13622,2450*17 +{"class":"ATT","tag":"PTNTHTM","heading":14243.00,"mag_st":"N","pitch":170.00,"pitch_st":"N","roll":-39.00,"roll_st":"N","dip":13622.000,"mag_x":2450.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14155,N,172,N,-35,N,13611,2449*15 +{"class":"ATT","tag":"PTNTHTM","heading":14155.00,"mag_st":"N","pitch":172.00,"pitch_st":"N","roll":-35.00,"roll_st":"N","dip":13611.000,"mag_x":2449.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14330,N,172,N,-32,N,13647,2448*11 +{"class":"ATT","tag":"PTNTHTM","heading":14330.00,"mag_st":"N","pitch":172.00,"pitch_st":"N","roll":-32.00,"roll_st":"N","dip":13647.000,"mag_x":2448.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14239,N,171,N,-33,N,13612,2448*1B +{"class":"ATT","tag":"PTNTHTM","heading":14239.00,"mag_st":"N","pitch":171.00,"pitch_st":"N","roll":-33.00,"roll_st":"N","dip":13612.000,"mag_x":2448.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14182,N,174,N,-34,N,13581,2449*12 +{"class":"ATT","tag":"PTNTHTM","heading":14182.00,"mag_st":"N","pitch":174.00,"pitch_st":"N","roll":-34.00,"roll_st":"N","dip":13581.000,"mag_x":2449.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14256,N,174,N,-37,N,13602,2449*13 +{"class":"ATT","tag":"PTNTHTM","heading":14256.00,"mag_st":"N","pitch":174.00,"pitch_st":"N","roll":-37.00,"roll_st":"N","dip":13602.000,"mag_x":2449.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14139,N,178,N,-38,N,13568,2450*1D +{"class":"ATT","tag":"PTNTHTM","heading":14139.00,"mag_st":"N","pitch":178.00,"pitch_st":"N","roll":-38.00,"roll_st":"N","dip":13568.000,"mag_x":2450.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14193,N,177,N,-40,N,13604,2450*14 +{"class":"ATT","tag":"PTNTHTM","heading":14193.00,"mag_st":"N","pitch":177.00,"pitch_st":"N","roll":-40.00,"roll_st":"N","dip":13604.000,"mag_x":2450.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14186,N,174,N,-42,N,13590,2451*1E +{"class":"ATT","tag":"PTNTHTM","heading":14186.00,"mag_st":"N","pitch":174.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13590.000,"mag_x":2451.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14174,N,174,N,-40,N,13602,2451*19 +{"class":"ATT","tag":"PTNTHTM","heading":14174.00,"mag_st":"N","pitch":174.00,"pitch_st":"N","roll":-40.00,"roll_st":"N","dip":13602.000,"mag_x":2451.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14094,N,172,N,-40,N,13570,2452*15 +{"class":"ATT","tag":"PTNTHTM","heading":14094.00,"mag_st":"N","pitch":172.00,"pitch_st":"N","roll":-40.00,"roll_st":"N","dip":13570.000,"mag_x":2452.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14232,N,169,N,-42,N,13609,2452*1E +{"class":"ATT","tag":"PTNTHTM","heading":14232.00,"mag_st":"N","pitch":169.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13609.000,"mag_x":2452.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14134,N,165,N,-42,N,13570,2452*1A +{"class":"ATT","tag":"PTNTHTM","heading":14134.00,"mag_st":"N","pitch":165.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13570.000,"mag_x":2452.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14225,N,165,N,-43,N,13632,2452*1D +{"class":"ATT","tag":"PTNTHTM","heading":14225.00,"mag_st":"N","pitch":165.00,"pitch_st":"N","roll":-43.00,"roll_st":"N","dip":13632.000,"mag_x":2452.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14042,N,169,N,-43,N,13588,2451*13 +{"class":"ATT","tag":"PTNTHTM","heading":14042.00,"mag_st":"N","pitch":169.00,"pitch_st":"N","roll":-43.00,"roll_st":"N","dip":13588.000,"mag_x":2451.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14222,N,170,N,-45,N,13646,2451*18 +{"class":"ATT","tag":"PTNTHTM","heading":14222.00,"mag_st":"N","pitch":170.00,"pitch_st":"N","roll":-45.00,"roll_st":"N","dip":13646.000,"mag_x":2451.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14174,N,170,N,-45,N,13640,2450*1F +{"class":"ATT","tag":"PTNTHTM","heading":14174.00,"mag_st":"N","pitch":170.00,"pitch_st":"N","roll":-45.00,"roll_st":"N","dip":13640.000,"mag_x":2450.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14264,N,170,N,-42,N,13636,2449*13 +{"class":"ATT","tag":"PTNTHTM","heading":14264.00,"mag_st":"N","pitch":170.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13636.000,"mag_x":2449.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14132,N,171,N,-42,N,13604,2448*12 +{"class":"ATT","tag":"PTNTHTM","heading":14132.00,"mag_st":"N","pitch":171.00,"pitch_st":"N","roll":-42.00,"roll_st":"N","dip":13604.000,"mag_x":2448.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14265,N,171,N,-38,N,13629,2448*11 +{"class":"ATT","tag":"PTNTHTM","heading":14265.00,"mag_st":"N","pitch":171.00,"pitch_st":"N","roll":-38.00,"roll_st":"N","dip":13629.000,"mag_x":2448.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14145,N,171,N,-38,N,13612,2447*17 +{"class":"ATT","tag":"PTNTHTM","heading":14145.00,"mag_st":"N","pitch":171.00,"pitch_st":"N","roll":-38.00,"roll_st":"N","dip":13612.000,"mag_x":2447.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14198,N,172,N,-38,N,13614,2447*12 +{"class":"ATT","tag":"PTNTHTM","heading":14198.00,"mag_st":"N","pitch":172.00,"pitch_st":"N","roll":-38.00,"roll_st":"N","dip":13614.000,"mag_x":2447.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14184,N,172,N,-35,N,13612,2446*15 +{"class":"ATT","tag":"PTNTHTM","heading":14184.00,"mag_st":"N","pitch":172.00,"pitch_st":"N","roll":-35.00,"roll_st":"N","dip":13612.000,"mag_x":2446.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14187,N,174,N,-35,N,13589,2447*10 +{"class":"ATT","tag":"PTNTHTM","heading":14187.00,"mag_st":"N","pitch":174.00,"pitch_st":"N","roll":-35.00,"roll_st":"N","dip":13589.000,"mag_x":2447.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14257,N,174,N,-35,N,13603,2447*1F +{"class":"ATT","tag":"PTNTHTM","heading":14257.00,"mag_st":"N","pitch":174.00,"pitch_st":"N","roll":-35.00,"roll_st":"N","dip":13603.000,"mag_x":2447.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14161,N,178,N,-37,N,13575,2448*1A +{"class":"ATT","tag":"PTNTHTM","heading":14161.00,"mag_st":"N","pitch":178.00,"pitch_st":"N","roll":-37.00,"roll_st":"N","dip":13575.000,"mag_x":2448.000,"temp":0.000,"depth":0.000} +$PTNTHTM,14302,N,177,N,-40,N,13608,2448*1B +{"class":"ATT","tag":"PTNTHTM","heading":14302.00,"mag_st":"N","pitch":177.00,"pitch_st":"N","roll":-40.00,"roll_st":"N","dip":13608.000,"mag_x":2448.000,"temp":0.000,"depth":0.000} diff --git a/test/daemon/tomtom-mkII.log b/test/daemon/tomtom-mkII.log new file mode 100644 index 0000000..452b650 --- /dev/null +++ b/test/daemon/tomtom-mkII.log @@ -0,0 +1,72 @@ +# Name: TomTom Mark II +# Chipset: Sirf-3 +# Cycle time: 1s +# Submitted-by: Jose Baars peut@peut.org +# Date: 20 June 2010 +# Location: Veldhoven, NL +$GPGGA,175736,5125.8714,N,00524.2350,E,1,04,3.40,60.28,M,46.999,M,,*79 +$GPRMC,175736,A,5125.8714,N,00524.2350,E,3.1865,276.241,200610,,*2A +$GPGSA,A,3,14,30,29,31,,,,,,,,,7.6,3.4,6.8*35 +$PGRME,0.00,M,0.00,M,29.40,M*21 +$GPGGA,175737,5125.8706,N,00524.2332,E,1,04,3.40,61.40,M,46.999,M,,*70 +$GPRMC,175737,A,5125.8706,N,00524.2332,E,2.5761,257.043,200610,,*21 +$GPGSA,A,3,14,30,29,31,,,,,,,,,7.6,3.4,6.8*35 +$PGRME,0.00,M,0.00,M,29.40,M*21 +$GPGGA,175738,5125.8703,N,00524.2323,E,1,03,2.20,60.56,M,46.999,M,,*7C +$GPRMC,175738,A,5125.8703,N,00524.2323,E,1.5881,253.161,200610,,*2C +$GPGSA,A,2,14,30,31,,,,,,,,,,7.6,2.2,6.8*38 +$PGRME,0.00,M,0.00,M,29.40,M*21 +$GPGGA,175739,5125.8701,N,00524.2297,E,1,03,2.20,59.61,M,46.999,M,,*7F +$GPRMC,175739,A,5125.8701,N,00524.2297,E,2.5365,244.610,200610,,*24 +$GPGSA,A,2,14,30,31,,,,,,,,,,7.6,2.2,6.8*38 +$PGRME,0.00,M,0.00,M,29.40,M*21 +$GPRMC,175740,V,5125.8697,N,00524.2288,E,2.5365,244.610,200610,,*3D +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175742,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3D +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175743,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3C +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175744,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3B +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175745,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3A +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175746,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*39 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175747,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*38 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175748,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*37 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175749,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*36 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPGSV,2,1,05,14,20,232,23,30,75,085,00,31,48,297,34,12,40,093,00*7E +$GPGSV,2,2,05,29,66,205,17*46 +$GPRMC,175750,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3E +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175751,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3F +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175752,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3C +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175753,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3D +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175754,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3A +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175755,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3B +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175756,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*38 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175757,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*39 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175758,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*36 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175759,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*37 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175800,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*34 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175801,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*35 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175802,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*36 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175803,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*37 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +r$GPRMC,175804,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*30 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 diff --git a/test/daemon/tomtom-mkII.log.chk b/test/daemon/tomtom-mkII.log.chk new file mode 100644 index 0000000..3dcd4a3 --- /dev/null +++ b/test/daemon/tomtom-mkII.log.chk @@ -0,0 +1,73 @@ +$GPGGA,175736,5125.8714,N,00524.2350,E,1,04,3.40,60.28,M,46.999,M,,*79 +{"class":"TPV","tag":"GGA","lat":51.431190000,"lon":5.403916667,"alt":60.280,"mode":3} +$GPRMC,175736,A,5125.8714,N,00524.2350,E,3.1865,276.241,200610,,*2A +{"class":"TPV","tag":"RMC","time":1277056656.000,"ept":0.005,"lat":51.431190000,"lon":5.403916667,"alt":60.280,"track":276.2410,"speed":1.639,"mode":3} +$GPGSA,A,3,14,30,29,31,,,,,,,,,7.6,3.4,6.8*35 +{"class":"TPV","tag":"GSA","time":1277056656.000,"ept":0.005,"lat":51.431190000,"lon":5.403916667,"alt":60.280,"epv":156.400,"track":276.2410,"speed":1.639,"climb":0.000,"mode":3} +$PGRME,0.00,M,0.00,M,29.40,M*21 +$GPGGA,175737,5125.8706,N,00524.2332,E,1,04,3.40,61.40,M,46.999,M,,*70 +$GPRMC,175737,A,5125.8706,N,00524.2332,E,2.5761,257.043,200610,,*21 +{"class":"TPV","tag":"RMC","time":1277056657.000,"ept":0.005,"lat":51.431176667,"lon":5.403886667,"alt":61.400,"epv":156.400,"track":257.0430,"speed":1.325,"climb":1.120,"mode":3} +$GPGSA,A,3,14,30,29,31,,,,,,,,,7.6,3.4,6.8*35 +$PGRME,0.00,M,0.00,M,29.40,M*21 +$GPGGA,175738,5125.8703,N,00524.2323,E,1,03,2.20,60.56,M,46.999,M,,*7C +$GPRMC,175738,A,5125.8703,N,00524.2323,E,1.5881,253.161,200610,,*2C +{"class":"TPV","tag":"RMC","time":1277056658.000,"ept":0.005,"lat":51.431171667,"lon":5.403871667,"alt":60.560,"epv":156.400,"track":253.1610,"speed":0.817,"climb":-0.840,"mode":3} +$GPGSA,A,2,14,30,31,,,,,,,,,,7.6,2.2,6.8*38 +$PGRME,0.00,M,0.00,M,29.40,M*21 +$GPGGA,175739,5125.8701,N,00524.2297,E,1,03,2.20,59.61,M,46.999,M,,*7F +$GPRMC,175739,A,5125.8701,N,00524.2297,E,2.5365,244.610,200610,,*24 +{"class":"TPV","tag":"RMC","time":1277056659.000,"ept":0.005,"lat":51.431168333,"lon":5.403828333,"alt":59.610,"epv":156.400,"track":244.6100,"speed":1.305,"climb":-0.950,"mode":3} +$GPGSA,A,2,14,30,31,,,,,,,,,,7.6,2.2,6.8*38 +$PGRME,0.00,M,0.00,M,29.40,M*21 +$GPRMC,175740,V,5125.8697,N,00524.2288,E,2.5365,244.610,200610,,*3D +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175742,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3D +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175743,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3C +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175744,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3B +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175745,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3A +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175746,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*39 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175747,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*38 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175748,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*37 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175749,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*36 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPGSV,2,1,05,14,20,232,23,30,75,085,00,31,48,297,34,12,40,093,00*7E +$GPGSV,2,2,05,29,66,205,17*46 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":14,"el":20,"az":232,"ss":23,"used":false},{"PRN":30,"el":75,"az":85,"ss":0,"used":false},{"PRN":31,"el":48,"az":297,"ss":34,"used":false},{"PRN":12,"el":40,"az":93,"ss":0,"used":false},{"PRN":29,"el":66,"az":205,"ss":17,"used":false}]} +$GPRMC,175750,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3E +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175751,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3F +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175752,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3C +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175753,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3D +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175754,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3A +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175755,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*3B +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175756,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*38 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175757,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*39 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175758,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*36 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175759,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*37 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175800,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*34 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175801,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*35 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175802,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*36 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175803,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*37 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 +$GPRMC,175804,V,5125.8697,N,00524.2288,E,0.0000,0.000,200610,,*30 +$GPGSA,A,1,,,,,,,,,,,,,,,,*32 diff --git a/test/daemon/trimble-lassen_iq-3dfix.log b/test/daemon/trimble-lassen_iq-3dfix.log new file mode 100644 index 0000000000000000000000000000000000000000..250099db3eab5845c180e17ba99baaa064f96655 GIT binary patch literal 7562 zcmb`LdvsG(7RH-4g}y|mKq<)MniMFn+5+WG&MuVF0P-pfOnI!PZJ>cR?WBRw2^euP zpjJ$m0}6H+85BX{00JWNP?og5L4&qbDA*;h7DR9c9Aj@pCmaD7VOBx100(<(3V@m^MqPG=7oUUSO6+_kmrNq2m0H-8Nxn&YhX6)pwbg9Hvyuh5t z=QavgcC)RhR5F#66e9Cdvsu1RCXJpn`A^1)VN|TVqLq+LSI^RPb3YL;#Z7YgCIzBEkHu|A3pYS>aCj>1QV&fuZVHyozwS(*LP204_kdTZcANMgdjy+A~i$n0ya4j}o({@yhqFwr-2di11 zD>RK15|;LbPh*;M#pLK(r%~df69bqh|1yF+uhfaSuw=wFD9i^O<>dTwfryJEj2Evk zE1vAnyy5djTx6!I8S3gY*tln+6|D%fTY8!8Js3;+x397TUnhy#rDYsBc0JsgmJ+azHrDhrT)bnW z@{*Avb=k&td|J>hJ$r%GY*{Kajo-$aek`=}d~zgMg&nGmh&$;`AkW4s5vSS+E#{Li z$@$qh5hvTIjK?bGS(vxO1`#LQC~~RWHH(c~cv8`P_Q0}loBWokW{o~&W(`@rNOGIm z&a&tD#CeZA8Hyk9!6E118Al=Q9OQ+!W_mq%E%}-Qe4-dg^RN{=dRvJ873@kZxoZtDYXCM8Mzg zuKdzppG}>4i(KhqXu7L1YU0B7?UCcXhM}QRzJCb(RLed$pu5o|JQyQ1bvXdDqGvSoro{=S zT+0M*3gYTooo2>sR{|zrUQgQbIi#C(kyX#JDHGtuy04HkinPPelWzJyS#?eqrC6f< z5tx07w0$2Y-K@W|>fCdRuGXze)5*{@wiBzVv5FM^mOx{n$J5C%Xp_+VmhiY!mrKa= z!X7bgza?CYTDO;+ZzT#%wuF~}Gb>`cGH(`;zSUZ`MDl5d6Ca*o#v|w&e|t}VhP0hG zlg>n}+Puc!jaA_~e>bYl{+l;*|0YL~Hl~tv^HW)M!Q5Zl^qYEsP0>0-Q>$LA=FG1< zrz%>XUz^_g=!PDsKiWi?tE5gvQ4rTV7l*gW8S&`RY$f- zwh(bAHoU`(n=dKjrDasLyWn>tAnW$=hQ=f5tfo;fGLwtTx6P{d@ht4&?c^|Mg{EeW zxcWKU$@Bbrk(rt`w8%a4$?5SwuyWSCr#aJo@df5xI7u-5YZo-b3EN0!Tm_`RxNH-J z)mMx1 zB0YJn)=0|!35|sw>uYrgP+3{j^}J{Ru6i@&j^ioGCQ5E?~O%A7tLA zlLb?*i`=`2I}!0MGme;{Xl{vDh+nvL5isphnAQl>Zs0#HH~zR_biW2hA22R~aXScx zd{hy=kS%b%>VWGB+!f%OgTT2ZzMA8sarHY4h8~QoAyIRXyFS}(M68l#iY`D0r2djM_lcOZ7lQJK}B;*qwp8Ma2ewD^|$%*$I%tYA<30_-rbL&5GIBzt=|vZnq7_S>Z2M1p-suxIWA zI|S@7u<=0pTD=8%`&!1=Er4ZIjcseVIATAm?e-5`DtnOfasrKo-55iTtm~p%)P)0a zr*|AB&r1J3qjnOs)(@T_XGMaDQ}-Y+-OgFeyPNlj+DY=s4so@mD_Q23-4rcgJQ+o|stI9FtEYA^|+-s6=JmxOg&AjiuBF2+fE&1$)xZ1IH zmboWY(cIE;{KYR^C5iCl8a#Obo{R{>lYp}dFKgX$vYP5){RgB!^^UNCp>J_Jx}|KvaD45+KaGD6Qk8wzaADmURy*h{clqA(XWwPo$y>-Vr?)7hT7JZx8TlM}misle{LsR$ zcP8hGXGEM@elXpSU1eTxju=lazr55St~Nr)GFLSz8u#?Nk*tru3{Sn3ph*>;ZpR(` zCfBNU@Z&7}_yhdFD_)B|1=|r?OxD$7z&=R{?S}Z+a=Qeqapg~7fCdZ@ivdu|77yT- z{Ogdr0E{zWv;|{&5DX=mHe$Aan+#ArKLb1%D2Bb{z6H1;Gwj8r;$g z0=MZJaL0k`09;-WIJaaFjMwVG_#BLQFy;lpK%uPl{zCaq2Hf7hUCFwy5cXc8gb6)- z_6EFa6o(tmEpJWbkA{jzPJYB2_#+POLVP5vHTvH$HU1U8IGkzMts+OhRm7=}IO5K{ zag{vF+6hg4#G!?^4=1OyP-yZaEVGuPj@^z5J(7xd-cb-JzY|vw+pk_#?OM-fd>dO{V>#8#xyE zzpa*gP{e%`rX^2Vqv$iW2f@@9tRScT-cyF$gJ8PbtY_Yzuwu*O73pP11AfR~3S~t7 E4P-q9H)tHb~*8iD(f07g+B0=`%*Aw-BIBqqTETEs_J zT;GUYwWE!wXca}QRu_Q;l&U-ljZW)ppVDeAy?|kPw zH@TMyRE%7s6jOkr$w8{tvBq;SNxmrxknjsQVGh+kL%u}e9{zetnEC?{* zn{v`LDx*=E?w^(?hMIbnfr`#i8Z(tthytGpvzTWjLnBwIg$k`E4A&wzf)E%8i&9X5 zBGC-U=4%y9buksEmgmW-bfub-%Jmv$_7o~!NG;TAr%(%&xhjQL2!{w~1jSG@gN35t z#U2yj=)_DYyg~(g0Dq-gU7lW*k!hs-6asj2fQU-Vqi{`g;u0b#onE_AslXN`@XV;x zYYdcJr&B`%2BngDA0tU)m8lf?R5LV&s z>b;2f)}Z-mSio(j1pk<3awL-_f-Y5O=4Z5=g!tfwpA9bVbs0>3uV9UiR$(foSz z)3_y>;df~wxc)C+6OU(UZ%AA|sCWf1g(0K0i6Xr~H6%i*_=8Rz(#NG<}j|ML+Y-_4*z;I1a9#dz8(?;cxfgg78!x58f5U{ElAc zG6x5^0r4y<3xW5ax(io7?b5do&n*Im;_^j9*&L=W74|>%fhxxg5$Un93`avb zR34us!pi)gN8Itj1_-zEp*l9l#?Bug{MH|7`zI%8>$YxgWAU+mFBtyce?JFfd3t&u z@YW~3s{)G?fl1}^hZnH9Gko4F*(T&u_gBNdwKn7u z#S1|(p*}nR*2K%^y)_r(r|=}brvK$m=n2;Eo}#WQ`0OZr-nySNYyW(u$089Ka4N%zNu0>CM{4=FrvvdeiQy+dc$+>3hL-uxVGv+6qxmxiPM+ zDpqET;Bochr)-Y;ntW25e>Bwd*Mr3MgKzt;y-B?N>Ri-6?D`lst-i}W7xl2-t6px| zpiqCJ2eCQomJOuVTpsHAq?@?LoZ#s1-X9-;x}RikBJMQiMz6Kb=5oeC*C%9dwAnf z_y&ovaP{NOZ0>}9KHAoTYY#b;1b11MOOKbJKE(cb?Dz0dj&N}G3lrHKb*n!yw=E9! zdPhoJUnX9ciKZeuc#EJDe%zRey9E#C=%({+d8kX=Dg>a%y2qi;9}{%b z2fhF!Q@OgypUs`nkKLHm%&c8`F&lJQIdga0(y^%QTF*RS3b}j{oW@L!{Lb~nvZMUX z-sI{yi$5Dx&G7WaqSwHOzs7$HTJ~>s>FSvaiixWqhbtA6w~8C%mLVfg~N)AUWGLntHjG6!KHB6dN#+l?mvK^5usl1mk_t} z2l}?vba~IG5vUJ)eXJVv2gMZXV@K;2w?~2EK)w3+pyxH>&dN*e5rvZ8P4Lyl53T&E-h=AVgSpM4xeWc75#bee!wZs~xEEb9f{Ro%BJ1{CH2fc3o3{n@J z7V0&+nz(f{Hz9Dq|1aZBj--$as1JGEI33nr;etEUTw0O*eY+GC3U%IF4@qySip`zS zpP&2aZ>YN`WsL^?RPH|1(|?;I>4AYp5w3m^?rWJGUytc`;B}Smr0#4`sMq+rWN=_l z-;p$ru$|OmVV4Q#;WBRivMCn}PYQY>=pg{7atoKj|36HQZ4IE$cG>d-=u2Mk7Ql_0 NxpHqI=uN+R{1=Stvkd?M literal 0 HcmV?d00001 diff --git a/test/daemon/trimble-lassen_iq-playacar.log.chk b/test/daemon/trimble-lassen_iq-playacar.log.chk new file mode 100644 index 0000000..c52add2 --- /dev/null +++ b/test/daemon/trimble-lassen_iq-playacar.log.chk @@ -0,0 +1,80 @@ +$GPRMC,000000,V,2037.7075,N,08704.0535,W,0.0000,0.000,000000,,*23 +{"class":"TPV","tag":"ID84","mode":0} +$GPRMC,000000,V,2037.7075,N,08704.0535,W,0.0000,0.000,000000,,*23 +{"class":"TPV","tag":"ID84","mode":0} +$GPRMC,000000,V,2037.7075,N,08704.0535,W,0.0000,0.000,000000,,*23 +{"class":"TPV","tag":"ID84","mode":0} +$GPRMC,000000,V,2037.7075,N,08704.0535,W,0.0000,0.000,000000,,*23 +{"class":"TPV","tag":"ID84","mode":0} +$GPRMC,040938,A,2037.7075,N,08704.0535,W,0.0000,0.000,221206,,*37 +{"class":"TPV","tag":"ID84","time":1166760578.000,"ept":0.005,"mode":0} +$GPRMC,040939,A,2037.7075,N,08704.0535,W,0.0000,0.000,221206,,*36 +{"class":"TPV","tag":"ID84","time":1166760579.000,"ept":0.005,"mode":0} +$GPRMC,040940,A,2037.7075,N,08704.0535,W,0.0000,0.000,221206,,*38 +{"class":"TPV","tag":"ID84","time":1166760580.000,"ept":0.005,"mode":0} +$GPRMC,040941,A,2037.7075,N,08704.0535,W,0.0000,0.000,221206,,*39 +{"class":"TPV","tag":"ID84","time":1166760581.000,"ept":0.005,"mode":0} +$GPRMC,040942,A,2037.7075,N,08704.0535,W,0.0000,0.000,221206,,*3A +{"class":"TPV","tag":"ID84","time":1166760582.000,"ept":0.005,"mode":0} +$GPRMC,040943,A,2037.7075,N,08704.0535,W,0.0000,0.000,221206,,*3B +{"class":"TPV","tag":"ID84","time":1166760583.000,"ept":0.005,"mode":0} +$GPRMC,040944,A,2037.7075,N,08704.0535,W,0.0000,0.000,221206,,*3C +{"class":"TPV","tag":"ID84","time":1166760584.000,"ept":0.005,"mode":0} +$GPRMC,040945,A,2037.7075,N,08704.0535,W,0.0000,0.000,221206,,*3D +{"class":"TPV","tag":"ID84","time":1166760585.000,"ept":0.005,"mode":0} +$GPRMC,040946,A,2037.7075,N,08704.0535,W,0.0000,0.000,221206,,*3E +{"class":"TPV","tag":"ID84","time":1166760586.000,"ept":0.005,"mode":0} +$GPRMC,040947,A,2037.7076,N,08704.0535,W,0.0000,0.000,221206,,*3C +{"class":"TPV","tag":"ID84","time":1166760587.000,"ept":0.005,"mode":0} +$GPRMC,040948,A,2037.7076,N,08704.0535,W,0.0000,0.000,221206,,*33 +{"class":"TPV","tag":"ID84","time":1166760588.000,"ept":0.005,"mode":0} +$GPRMC,040949,A,2037.7076,N,08704.0535,W,0.0000,0.000,221206,,*32 +{"class":"TPV","tag":"ID84","time":1166760589.000,"ept":0.005,"mode":0} +$GPRMC,040950,A,2037.7077,N,08704.0534,W,0.0000,0.000,221206,,*3A +{"class":"TPV","tag":"ID84","time":1166760590.000,"ept":0.005,"mode":0} +$GPRMC,040951,A,2037.7077,N,08704.0534,W,0.0000,0.000,221206,,*3B +{"class":"TPV","tag":"ID84","time":1166760591.000,"ept":0.005,"mode":0} +$GPRMC,040952,A,2037.7076,N,08704.0535,W,0.0000,0.000,221206,,*38 +{"class":"TPV","tag":"ID84","time":1166760592.000,"ept":0.005,"mode":0} +$GPRMC,040953,A,2037.7059,N,08704.0550,W,0.0000,0.000,221206,,*37 +{"class":"TPV","tag":"ID84","time":1166760593.000,"ept":0.005,"mode":0} +$GPRMC,040954,A,2037.7053,N,08704.0556,W,0.0000,0.000,221206,,*3C +{"class":"TPV","tag":"ID84","time":1166760594.000,"ept":0.005,"mode":0} +$GPRMC,040955,A,2037.7051,N,08704.0558,W,0.0000,0.000,221206,,*31 +{"class":"TPV","tag":"ID84","time":1166760595.000,"ept":0.005,"mode":0} +$GPRMC,040956,A,2037.7049,N,08704.0559,W,0.0000,0.000,221206,,*3A +{"class":"TPV","tag":"ID84","time":1166760596.000,"ept":0.005,"mode":0} +$GPRMC,040957,A,2037.7048,N,08704.0560,W,0.0000,0.000,221206,,*30 +{"class":"TPV","tag":"ID84","time":1166760597.000,"ept":0.005,"mode":0} +$GPRMC,040958,A,2037.7047,N,08704.0561,W,0.0000,0.000,221206,,*31 +{"class":"TPV","tag":"ID84","time":1166760598.000,"ept":0.005,"mode":0} +$GPRMC,040959,A,2037.7047,N,08704.0561,W,0.0000,0.000,221206,,*30 +{"class":"TPV","tag":"ID84","time":1166760599.000,"ept":0.005,"mode":0} +$GPRMC,041000,A,2037.7046,N,08704.0562,W,0.0000,0.000,221206,,*36 +{"class":"TPV","tag":"ID84","time":1166760600.000,"ept":0.005,"mode":0} +$GPRMC,041001,A,2037.7046,N,08704.0562,W,0.0000,0.000,221206,,*37 +{"class":"TPV","tag":"ID84","time":1166760601.000,"ept":0.005,"mode":0} +$GPRMC,041002,A,2037.7046,N,08704.0562,W,0.0000,0.000,221206,,*34 +{"class":"TPV","tag":"ID84","time":1166760602.000,"ept":0.005,"mode":0} +$GPRMC,041003,A,2037.7046,N,08704.0563,W,0.0000,0.000,221206,,*34 +{"class":"TPV","tag":"ID84","time":1166760603.000,"ept":0.005,"mode":0} +$GPRMC,041004,A,2037.7046,N,08704.0563,W,0.0000,0.000,221206,,*33 +{"class":"TPV","tag":"ID84","time":1166760604.000,"ept":0.005,"mode":0} +$GPRMC,041005,A,2037.7046,N,08704.0563,W,0.0000,0.000,221206,,*32 +{"class":"TPV","tag":"ID84","time":1166760605.000,"ept":0.005,"mode":0} +$GPRMC,041006,A,2037.7046,N,08704.0563,W,0.0000,0.000,221206,,*31 +{"class":"TPV","tag":"ID84","time":1166760606.000,"ept":0.005,"mode":0} +$GPRMC,041007,A,2037.7046,N,08704.0562,W,0.0000,0.000,221206,,*31 +{"class":"TPV","tag":"ID84","time":1166760607.000,"ept":0.005,"mode":0} +$GPRMC,041008,A,2037.7054,N,08704.0557,W,0.0000,0.000,221206,,*3B +{"class":"TPV","tag":"ID84","time":1166760608.000,"ept":0.005,"mode":0} +$GPRMC,041009,A,2037.7055,N,08704.0557,W,0.0000,0.000,221206,,*3B +{"class":"TPV","tag":"ID84","time":1166760609.000,"ept":0.005,"mode":0} +$GPRMC,041010,A,2037.7055,N,08704.0556,W,0.0000,0.000,221206,,*32 +{"class":"TPV","tag":"ID84","time":1166760610.000,"ept":0.005,"mode":0} +$GPRMC,041011,A,2037.7056,N,08704.0556,W,0.0000,0.000,221206,,*30 +{"class":"TPV","tag":"ID84","time":1166760611.000,"ept":0.005,"mode":0} +$GPRMC,041012,A,2037.7057,N,08704.0555,W,0.0000,0.000,221206,,*31 +{"class":"TPV","tag":"ID84","time":1166760612.000,"ept":0.005,"mode":0} +$GPRMC,041013,A,2037.7058,N,08704.0555,W,0.0000,0.000,221206,,*3F +{"class":"TPV","tag":"ID84","time":1166760613.000,"ept":0.005,"mode":0} diff --git a/test/daemon/trimble-lassen_iq.log b/test/daemon/trimble-lassen_iq.log new file mode 100644 index 0000000000000000000000000000000000000000..bea0d0197733ac41d45231ec7f74a1c24e0c91d0 GIT binary patch literal 10333 zcmb_i30M?Yx-GyBYV)r!6=zQM8t^1?)$e$T#$B+dlqO>Q0T^{aUCOzIvP#N zZCs| z60N8Z86_Ib)5OS#h}ZG6L1v?T^%ya3Lb};xHJidjeOgko#hMr<#wMB)CnSc8J-UbY zFocQSy5a9pej!L3k%Cv8n2I-#zhliAGcBo;QmkUA@ii3g79l3h6lpR2h79j3W?0OV zla2J=`ru#IWJ`Lcn3$1~hLvX~C(Gx_O0k27j2U3)C#IU@&nBd1S}mzbS+X}4v)L+6 zG+V?8$yU6h%y6vYh4c|%x;p|wMmC4=i7$a~o;twWFIe+}&kJt~0{)C2D|q3rTyOlL zkK6d6U(?z8_hf`J&wl_R1}_L7Tm`yUGFv6mnV zjSmj>YNNm5#B|xU|AJOA%>@_c9pTlcPk;+smRm#048s`qU(s%w?el&CY3m85sp*fJ zcU-)hT3;~!VqrYLA*k8WRZB+Jb+V~TFvFUUMom{Oq}$JaV6UliY0|qp6AU47_aS`f z8{j)>D!aSiM$n&~yA*$%{?W6KoPZFW1;YEKg74UDcb&$O@$Ilcdc?sr5jHac>ce^xp~g>eFuC?mGz~Jv%_S z_B8k=Tyyti#{vlHYJ>17Z}0^NLtHtecCOh5AunHn@Rvt}@2jW1{Q{h!lZ}xJeX>F~ zy|fo89*aZU(3mGH(3o1tSvY{*pd83LYAEt@mR^EZudQG_ZW>}sD=w3=i5iA+(@?Yh z&8Z-LDlkoM8uF^^ZD71!&UmtEq0Z}(jPR|*cJV!iann#U@+|@E2fbXH`nY_b+l_>) zaW|+>+367C9|GYmZ-cLD9P{b7k@2#FO|Y{3j=Oc!dmbRgN$<1DlqroEI(QLsEGOCB z$_}1&@p5XvfL0xcGM?;UTNk!;&gY~o{WFFs4pPk^-|s;BES_mn2jwYEYpLF~0F3_} z!gz{I(Drf?$n|p!SQcV#loB0~UxEH7y6!SkIm9thf zUP%+xtTr?St+jqf@@ zP>;-T*U!Enx&tOYzxl?@HYl=8+Q}jrFUUYn4q}mqTY$Z?R*4R6W%Nk6l#S-?Li1J% z>h}hFXr8wgws?Woe|LXq5;0O48M<)OBjIWaieElPf(Cmqfa#&?Dh?G-~ujjkSV0CEg>AO->0R;jV}pZ==Q~K|Oh~2O4ZWjD^jg z{2exLS}jN1=fO0Wk$ex4U${;C?W$U6r}~AZf;M_*LJPO)vWA#QagNfYc%v`eh6!B) zIqm%!51X5FUx%8y+#}`CO0Db#cnXmh^ie2CRqGj#rx1AuH|_=Fwc2JMo^ouHr@oE z)4(M0J*M&GENXm;8jA(B8R!4+*1#sX*|HioPhF?=U-ugLob92^hCMEEgHVOyM^XGA zf_iH5A0uAJ#G7nE@rx*aSx{T>lE1rhTuhIyRTfj{0_&E%V?=vq!x(7SVkAp~oIIRC zarwuH&U&hl6fZJj6%BghG1?mkLr#;ajK`CQyu6mTpp`E$p4=N%E={S|I#RZB2g7(O zQ8Q@!P>>EbW14a*@kF_ngQHr4@l*xl$-NO5S&9+!rf$R*m(DPrO2oPcRe^o)Y$cT+ z;92xAv{;Is-YJdm?klJ>Z+qaWBr1chn$f9s9|1MO1a+3L2O5~Dq6bw_bpN2%e@OuN zEDBW;;PrvAa25(;wByLu?J^SQ?cj)%z6Q)eApPl}fz)G$Pjo*1Ggkp0tj#^WJEUfuxQ zoB2FoJRTy%K6*TglzptUC>|oz3_5WJq?!>-leaeH9c+CXjK>uo4-xXri(e+TFl#ltl>=pDT=tPi2B}731=x+r2TPUb!Z1uoj*YkS*lh6jUQxZqB!4m}(k4Evm zf_kRO196(Jd3~TLudlOT!G}t^)-dsq8z>Ga{*9oXg(I!r18!IyXHTW*@7UO z_PbUN2>kUOmJ>O%b=Xi4(`9b9k>Zcj@MfNFe29^fqUn%byNU6FLtU>uC@-(*0jQod zXPA;%ihZ zg(yBA#c{j-*M)zK_#r0VGXupFQCu&m=d|=p+P5WenpfM6CO=c(9kVmt&H+6VIZDAvP4PGNDzo1oitk z(|G@Rj#ZMF=adi(1M5*^25M{&)N`MDHhhi-wg~%-C19Vv#F>Y+v*}v}Z0*h+k|h4X zE@7y{OU%JbY{g5g^Qg>Un8vU}sF95t6{vCF0}Xv#!IVV})(5wUq;=JP|6(8nI(oAq zQx@KWw5~eKw!@^jWB^vtpoyh*B_;ORkZt>h@pycYH!rjqsP6hOj7J1{!EwDo`id=t zZjB0g2Q-CXJcvt)^LjiY$TLR+DLAb>i|~jb)_sQt?Ei>!T~87}VZM#rj=trgZ^s06 z_8<>@lf-zYF?J1VEI^I(sIk!_4fYgmcqbb*7NW*Y)Oc#A_&Z`2R0sCkKHZJms=fOL!y(0cO6Q4K)#Xl^K@6im! zb372ox}ffSTCV;GMRV%@)f73_NkDG{Q(IC>Z+N237} z8qgLE_|gLdsJr{dLg8NAZ&{6$FDx#7iv4OLP#_xlcU+2iyG@t1K+yj9`Hbe+NEm) zg<5|(j9y<~b=k#VwiQ%_>ZZ;ykm5=lhlVYwB9xST@&jZ~{+8u}=Lvc9zL*25E7KUp z^Mt(MH6uVeoyjnsC*MNA12t+70cx2FGaacC^re^ zCVC);@7$y3XOqhPEg^VI4B6Um3LVVmxIDUzrsKLU<8wlak4$3@^6uccPD(bNhwQ%F z*r@Q)MBe-$3#h*9!Z1FX$P2Eug7nQnhVeZJ^7eZV1mjNnY}=qaAkXxzl@w&quId_1 zws%1+O1Bs6yQaG^S2J_-EWNMZHt!|9E$@`}@4fHB_VY1#zw~y06X1)mt=(;H-K|3q z`28AIv$9V^OqUURpA?^ZiPfcegcy3{2iaYf#ar=+^5&174yvy&F->_7*A}}Z#g?4F zJ=}#trm6TxHG_Zp5u~%N84vw)z7V9ms(rCwEZxI+%50!KQ)LJ#8143Y+2tR_qTbbk zeJ8dQ*;_Q_lkj`^Z>x6I=WoJ}qQl&+#sPhtEs}qu^QI5|+8R|hNq6yIv38Xq9d-!Q zxk_Q!A$?(3u6Fg?k74KTlg|U(2BXg-?WJo)5P0^_%m8^X>Zx&k9_h?Si%IdhXWI{A zq{P-4vIAE#9v=+k&0li`RLB3uFg_TFEm`JA%C3%Prt-l+P0gRSf%Kh`@ihHikBYRG zs+mP#EE&QuJ{ZU|ZC*_Z2tGGE4Uf`0hMv+px*j3fcQkM~E*c#{3)w3gga>=+9bxq( z`)&{%zLn>M)BnTg1J3CkolnSeM^+R%&v&zN3ejFk`56LFzRSwvnVv#)<~BM~e03SS zWuECN_*yW(4CdacW;|{q^5)mC2Gy6t7{+ZxY)RJ@r0i}e)8sayrbdrnnOwNTc(PUW z)t?P9Q=XX=v}?t9%}2AmBNnwI5$t6zy4g6ezupn5!~5O#dn5~vij3ZQ?`+Au8>DGN%KLfBaFve1M(`5MS$@W<*h8Y z7$$NJsYJ6^pk8~s(kw%oDCK6i7hyj**A z!Uqs|$ik}Rj+K||OdV9D_`W}@ggaJVPD(Z`fw^l}F&+;d@)k@>098dJ^B1wjrOU|< zVH?xrj-jR|?*>ShKW3WTG2~S)7!1Y&eCTwJp6nRLH_nDU)9|lI{*9-VE`pnlm#M$zUu3hUE(Z)XK!=w$< zJKA@US;w_>m8WZbJG>`)#M!QBwAaqp${H$@-Hp zcg#X&9Ul(lEjaZlsCFqs#RH7k;-T4Ohbj;+FR$Z#I8alwD-EP;eoT`O2l6V#8ZfSp zWIR3`$TLNJO7g3X4C4VttjDV=uy17(4efpWwPG*#srMqiquu*XpKjgbLliwj?|3my z{`|!9vH$sV?&~JMUE1qk*Fxal8SGw^WePD}+QV_Aq=oVzt;8HLQnGFp%nes|!ism4 zx45;I>}c~PyHCYC%F}%FCy;K8Vb@cZBFfwM{Twi^R{pb=;vMCg0{uyTNo%I5ct^1w eai4*`WQR+WrZA>j?+Dl2lpZ`CJpZG)o literal 0 HcmV?d00001 diff --git a/test/daemon/trimble-lassen_iq.log.chk b/test/daemon/trimble-lassen_iq.log.chk new file mode 100644 index 0000000..c2fbbbf --- /dev/null +++ b/test/daemon/trimble-lassen_iq.log.chk @@ -0,0 +1,260 @@ +$GPGSV,3,1,12,26,06,138,00,24,14,077,34,00,00,000,00,00,00,000,00*74 +$GPGSV,3,2,12,06,77,232,26,29,14,126,29,02,16,079,38,21,35,257,26*7B +$GPGSV,3,3,12,00,00,000,00,30,22,204,32,10,54,073,41,07,40,297,29*7B +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":2.72,"tdop":2.15,"hdop":2.55,"gdop":4.30,"pdop":3.73,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":34,"used":true},{"PRN":6,"el":77,"az":232,"ss":26,"used":false},{"PRN":29,"el":14,"az":126,"ss":29,"used":true},{"PRN":2,"el":16,"az":79,"ss":38,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGSV,3,1,12,26,06,138,00,24,14,077,32,00,00,000,00,00,00,000,00*72 +$GPGSV,3,2,12,06,77,232,26,29,14,126,28,02,16,079,38,21,35,257,26*7A +$GPGSV,3,3,12,00,00,000,00,30,22,204,32,10,54,072,42,07,40,297,29*79 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":2.72,"tdop":2.14,"hdop":2.55,"gdop":4.30,"pdop":3.73,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":32,"used":true},{"PRN":6,"el":77,"az":232,"ss":26,"used":false},{"PRN":29,"el":14,"az":126,"ss":28,"used":true},{"PRN":2,"el":16,"az":79,"ss":38,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGSV,3,1,12,26,06,138,00,24,14,077,33,00,00,000,00,00,00,000,00*73 +$GPGSV,3,2,12,06,77,232,26,29,15,126,27,02,16,079,37,21,35,257,26*7B +$GPGSV,3,3,12,00,00,000,00,30,22,204,30,10,54,072,42,07,40,297,29*7B +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":2.72,"tdop":2.14,"hdop":2.55,"gdop":4.30,"pdop":3.73,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":33,"used":true},{"PRN":6,"el":77,"az":232,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":27,"used":true},{"PRN":2,"el":16,"az":79,"ss":37,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGSV,3,1,12,26,06,138,00,24,14,077,33,00,00,000,00,00,00,000,00*73 +$GPGSV,3,2,12,06,77,232,26,29,15,126,28,02,16,079,37,21,35,257,26*74 +$GPGSV,3,3,12,00,00,000,00,30,22,204,32,10,54,072,42,07,40,297,29*79 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":2.72,"tdop":2.14,"hdop":2.55,"gdop":4.29,"pdop":3.72,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":33,"used":true},{"PRN":6,"el":77,"az":232,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":28,"used":true},{"PRN":2,"el":16,"az":79,"ss":37,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGGA,012446,5332.2649,N,11329.5955,W,1,04,2.55,958.55,M,-19.816,M,,*77 +$GPRMC,012446,A,5332.2649,N,11329.5955,W,0.0000,0.000,261106,,*32 +$GPGSA,A,2,00,00,00,00,00,,,,,,,,3.7,2.5,2.7*35 +{"class":"TPV","tag":"ID8f20","time":1164504286.000,"ept":0.005,"lat":53.537748090,"lon":-113.493257926,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"mode":2} +$GPGGA,012447,5332.2652,N,11329.5949,W,1,04,2.55,959.45,M,-19.816,M,,*71 +$GPRMC,012447,A,5332.2652,N,11329.5949,W,0.0000,0.000,261106,,*34 +$GPGSA,A,2,00,00,00,00,00,,,,,,,,3.7,2.5,2.7*35 +{"class":"TPV","tag":"ID8f20","time":1164504287.000,"ept":0.005,"lat":53.537752616,"lon":-113.493247951,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012448,5332.2654,N,11329.5943,W,1,04,5.26,960.35,M,-19.817,M,,*7D +$GPRMC,012448,A,5332.2654,N,11329.5943,W,0.0000,0.000,261106,,*37 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.3,5.3,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504288.000,"ept":0.005,"lat":53.537757142,"lon":-113.493238060,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012449,5332.2657,N,11329.5937,W,1,04,5.26,961.19,M,-19.817,M,,*73 +$GPRMC,012449,A,5332.2657,N,11329.5937,W,0.0000,0.000,261106,,*36 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.3,5.3,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504289.000,"ept":0.005,"lat":53.537761333,"lon":-113.493228840,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGSV,3,1,12,26,06,138,00,24,14,077,30,00,00,000,00,00,00,000,00*70 +$GPGSV,3,2,12,06,77,231,26,29,15,126,27,02,16,079,37,21,35,257,26*78 +$GPGSV,3,3,12,00,00,000,00,30,22,204,33,10,54,072,42,07,40,297,29*78 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":0.04,"tdop":2.07,"hdop":5.26,"gdop":5.65,"pdop":5.26,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":30,"used":true},{"PRN":6,"el":77,"az":231,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":27,"used":false},{"PRN":2,"el":16,"az":79,"ss":37,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGGA,012450,5332.2659,N,11329.5932,W,1,04,5.26,961.98,M,-19.817,M,,*79 +$GPRMC,012450,A,5332.2659,N,11329.5932,W,0.0000,0.000,261106,,*35 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.3,5.3,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504290.000,"ept":0.005,"lat":53.537765356,"lon":-113.493220207,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012451,5332.2662,N,11329.5927,W,1,04,5.25,962.71,M,-19.817,M,,*73 +$GPRMC,012451,A,5332.2662,N,11329.5927,W,0.0000,0.000,261106,,*38 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.3,5.3,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504291.000,"ept":0.005,"lat":53.537769212,"lon":-113.493212244,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012452,5332.2664,N,11329.5923,W,1,04,5.25,963.37,M,-19.817,M,,*71 +$GPRMC,012452,A,5332.2664,N,11329.5923,W,0.0000,0.000,261106,,*39 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.3,5.3,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504292.000,"ept":0.005,"lat":53.537772733,"lon":-113.493205287,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012453,5332.2666,N,11329.5919,W,1,04,5.25,964.02,M,-19.817,M,,*7A +$GPRMC,012453,A,5332.2666,N,11329.5919,W,0.0000,0.000,261106,,*33 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.3,5.3,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504293.000,"ept":0.005,"lat":53.537776337,"lon":-113.493198330,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012454,5332.2668,N,11329.5915,W,1,04,5.25,964.60,M,-19.817,M,,*7B +$GPRMC,012454,A,5332.2668,N,11329.5915,W,0.0000,0.000,261106,,*36 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.3,5.3,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504294.000,"ept":0.005,"lat":53.537779522,"lon":-113.493192295,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGSV,3,1,12,26,06,138,00,24,14,077,30,00,00,000,00,00,00,000,00*70 +$GPGSV,3,2,12,06,77,231,26,29,15,126,26,02,16,079,37,21,35,257,26*79 +$GPGSV,3,3,12,00,00,000,00,30,22,204,33,10,54,072,42,07,40,297,29*78 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":0.04,"tdop":2.06,"hdop":5.24,"gdop":5.63,"pdop":5.24,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":30,"used":true},{"PRN":6,"el":77,"az":231,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":79,"ss":37,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGGA,012455,5332.2669,N,11329.5912,W,1,04,5.24,965.11,M,-19.817,M,,*7A +$GPRMC,012455,A,5332.2669,N,11329.5912,W,0.0000,0.000,261106,,*31 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504295.000,"ept":0.005,"lat":53.537782372,"lon":-113.493187015,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012456,5332.2671,N,11329.5909,W,1,04,5.24,965.56,M,-19.817,M,,*79 +$GPRMC,012456,A,5332.2671,N,11329.5909,W,0.0000,0.000,261106,,*31 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504296.000,"ept":0.005,"lat":53.537784803,"lon":-113.493182237,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012457,5332.2672,N,11329.5907,W,1,04,5.24,965.98,M,-19.817,M,,*77 +$GPRMC,012457,A,5332.2672,N,11329.5907,W,0.0000,0.000,261106,,*3D +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504297.000,"ept":0.005,"lat":53.537786898,"lon":-113.493178046,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012458,5332.2673,N,11329.5905,W,1,04,5.23,966.35,M,-19.817,M,,*78 +$GPRMC,012458,A,5332.2673,N,11329.5905,W,0.0000,0.000,261106,,*31 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504298.000,"ept":0.005,"lat":53.537788742,"lon":-113.493174190,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012459,5332.2674,N,11329.5902,W,1,04,5.23,966.69,M,-19.817,M,,*70 +$GPRMC,012459,A,5332.2674,N,11329.5902,W,0.0000,0.000,261106,,*30 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504299.000,"ept":0.005,"lat":53.537790335,"lon":-113.493170754,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGSV,3,1,12,26,06,138,00,24,14,077,29,00,00,000,00,00,00,000,00*78 +$GPGSV,3,2,12,06,77,231,26,29,15,126,26,02,16,079,35,21,35,257,26*7B +$GPGSV,3,3,12,00,00,000,00,30,22,204,32,10,54,072,43,07,40,297,29*78 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":0.04,"tdop":2.06,"hdop":5.23,"gdop":5.62,"pdop":5.23,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":29,"used":true},{"PRN":6,"el":77,"az":231,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":79,"ss":35,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGGA,012500,5332.2675,N,11329.5900,W,1,04,5.23,967.00,M,-19.817,M,,*70 +$GPRMC,012500,A,5332.2675,N,11329.5900,W,0.0000,0.000,261106,,*3E +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504300.000,"ept":0.005,"lat":53.537791843,"lon":-113.493167485,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":78.48,"mode":2} +$GPGGA,012501,5332.2676,N,11329.5899,W,1,04,5.23,967.28,M,-19.817,M,,*79 +$GPRMC,012501,A,5332.2676,N,11329.5899,W,0.0000,0.000,261106,,*3D +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504301.000,"ept":0.005,"lat":53.537793184,"lon":-113.493164551,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012503,5332.2677,N,11329.5896,W,1,04,5.22,967.78,M,-19.817,M,,*71 +$GPRMC,012503,A,5332.2677,N,11329.5896,W,0.0000,0.000,261106,,*31 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504303.000,"ept":0.005,"lat":53.537795448,"lon":-113.493159187,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":21.59,"mode":2} +$GPGGA,012504,5332.2678,N,11329.5894,W,1,04,5.22,968.01,M,-19.817,M,,*7A +$GPRMC,012504,A,5332.2678,N,11329.5894,W,0.0000,0.000,261106,,*3B +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504304.000,"ept":0.005,"lat":53.537796370,"lon":-113.493156756,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGSV,3,1,12,26,06,138,00,24,14,077,29,00,00,000,00,00,00,000,00*78 +$GPGSV,3,2,12,06,77,231,26,29,15,126,26,02,16,080,35,21,35,257,26*7D +$GPGSV,3,3,12,00,00,000,00,30,22,204,33,10,54,072,43,07,40,297,29*79 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":0.04,"tdop":2.05,"hdop":5.21,"gdop":5.60,"pdop":5.21,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":29,"used":true},{"PRN":6,"el":77,"az":231,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":35,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGGA,012505,5332.2678,N,11329.5893,W,1,04,5.21,968.21,M,-19.817,M,,*7D +$GPRMC,012505,A,5332.2678,N,11329.5893,W,0.0000,0.000,261106,,*3D +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504305.000,"ept":0.005,"lat":53.537797208,"lon":-113.493154493,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012506,5332.2679,N,11329.5891,W,1,04,5.21,968.41,M,-19.817,M,,*7B +$GPRMC,012506,A,5332.2679,N,11329.5891,W,0.0000,0.000,261106,,*3D +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504306.000,"ept":0.005,"lat":53.537797878,"lon":-113.493152397,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":89.89,"mode":2} +$GPGGA,012507,5332.2679,N,11329.5890,W,1,04,5.20,968.59,M,-19.817,M,,*73 +$GPRMC,012507,A,5332.2679,N,11329.5890,W,0.0000,0.000,261106,,*3D +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504307.000,"ept":0.005,"lat":53.537798549,"lon":-113.493150386,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012508,5332.2680,N,11329.5889,W,1,04,5.20,968.75,M,-19.817,M,,*7C +$GPRMC,012508,A,5332.2680,N,11329.5889,W,0.0000,0.000,261106,,*3C +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504308.000,"ept":0.005,"lat":53.537799219,"lon":-113.493148458,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012509,5332.2680,N,11329.5888,W,1,04,5.20,968.91,M,-19.817,M,,*76 +$GPRMC,012509,A,5332.2680,N,11329.5888,W,0.0000,0.000,261106,,*3C +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504309.000,"ept":0.005,"lat":53.537799806,"lon":-113.493146530,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGSV,3,1,12,26,06,138,00,24,14,077,28,00,00,000,00,00,00,000,00*79 +$GPGSV,3,2,12,06,77,231,26,29,15,126,26,02,16,080,35,21,35,257,26*7D +$GPGSV,3,3,12,00,00,000,00,30,22,204,30,10,54,072,44,07,40,297,29*7D +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":0.04,"tdop":2.05,"hdop":5.20,"gdop":5.59,"pdop":5.20,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":28,"used":true},{"PRN":6,"el":77,"az":231,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":35,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGGA,012510,5332.2680,N,11329.5887,W,1,04,5.20,969.06,M,-19.817,M,,*7E +$GPRMC,012510,A,5332.2680,N,11329.5887,W,0.0000,0.000,261106,,*3B +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504310.000,"ept":0.005,"lat":53.537800393,"lon":-113.493144770,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012511,5332.2681,N,11329.5886,W,1,04,5.19,969.20,M,-19.817,M,,*71 +$GPRMC,012511,A,5332.2681,N,11329.5886,W,0.0000,0.000,261106,,*3A +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504311.000,"ept":0.005,"lat":53.537800896,"lon":-113.493143010,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012512,5332.2681,N,11329.5885,W,1,04,5.19,969.33,M,-19.817,M,,*73 +$GPRMC,012512,A,5332.2681,N,11329.5885,W,0.0000,0.000,261106,,*3A +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504312.000,"ept":0.005,"lat":53.537801315,"lon":-113.493141333,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012513,5332.2681,N,11329.5884,W,1,04,5.18,969.46,M,-19.817,M,,*70 +$GPRMC,012513,A,5332.2681,N,11329.5884,W,0.0000,0.000,261106,,*3A +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504313.000,"ept":0.005,"lat":53.537801650,"lon":-113.493139657,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012514,5332.2681,N,11329.5883,W,1,04,5.18,969.57,M,-19.817,M,,*70 +$GPRMC,012514,A,5332.2681,N,11329.5883,W,0.0000,0.000,261106,,*3A +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504314.000,"ept":0.005,"lat":53.537802069,"lon":-113.493138064,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGSV,3,1,12,26,06,138,00,24,14,077,30,00,00,000,00,00,00,000,00*70 +$GPGSV,3,2,12,06,77,231,26,29,15,126,26,02,16,080,35,21,35,257,26*7D +$GPGSV,3,3,12,00,00,000,00,30,22,204,30,10,54,072,45,07,40,297,29*7C +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":0.04,"tdop":2.04,"hdop":5.18,"gdop":5.57,"pdop":5.18,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":30,"used":true},{"PRN":6,"el":77,"az":231,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":35,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGGA,012515,5332.2681,N,11329.5882,W,1,04,5.18,969.68,M,-19.817,M,,*7C +$GPRMC,012515,A,5332.2681,N,11329.5882,W,0.0000,0.000,261106,,*3A +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504315.000,"ept":0.005,"lat":53.537802405,"lon":-113.493136556,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012517,5332.2682,N,11329.5880,W,1,04,5.18,969.89,M,-19.817,M,,*70 +$GPRMC,012517,A,5332.2682,N,11329.5880,W,0.0000,0.000,261106,,*39 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504317.000,"ept":0.005,"lat":53.537803243,"lon":-113.493133622,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":21.59,"mode":2} +$GPGGA,012518,5332.2682,N,11329.5879,W,1,04,5.17,969.99,M,-19.817,M,,*77 +$GPRMC,012518,A,5332.2682,N,11329.5879,W,0.0000,0.000,261106,,*30 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504318.000,"ept":0.005,"lat":53.537803662,"lon":-113.493132281,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012519,5332.2682,N,11329.5879,W,1,04,5.17,970.08,M,-19.817,M,,*76 +$GPRMC,012519,A,5332.2682,N,11329.5879,W,0.0000,0.000,261106,,*31 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504319.000,"ept":0.005,"lat":53.537803913,"lon":-113.493131024,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGSV,3,1,12,26,06,138,00,24,14,077,29,00,00,000,00,00,00,000,00*78 +$GPGSV,3,2,12,06,77,230,26,29,15,126,26,02,16,080,35,21,35,257,26*7C +$GPGSV,3,3,12,00,00,000,00,30,22,204,30,10,54,072,45,07,40,297,29*7C +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":0.04,"tdop":2.04,"hdop":5.17,"gdop":5.56,"pdop":5.17,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":29,"used":true},{"PRN":6,"el":77,"az":230,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":35,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGGA,012520,5332.2682,N,11329.5878,W,1,04,5.17,970.16,M,-19.817,M,,*72 +$GPRMC,012520,A,5332.2682,N,11329.5878,W,0.0000,0.000,261106,,*3A +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504320.000,"ept":0.005,"lat":53.537804165,"lon":-113.493129682,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":77.38,"mode":2} +$GPGGA,012521,5332.2683,N,11329.5877,W,1,04,5.17,970.25,M,-19.817,M,,*7D +$GPRMC,012521,A,5332.2683,N,11329.5877,W,0.0000,0.000,261106,,*35 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504321.000,"ept":0.005,"lat":53.537804416,"lon":-113.493128425,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012522,5332.2683,N,11329.5876,W,1,04,5.17,970.33,M,-19.817,M,,*78 +$GPRMC,012522,A,5332.2683,N,11329.5876,W,0.0000,0.000,261106,,*37 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504322.000,"ept":0.005,"lat":53.537804584,"lon":-113.493127252,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012523,5332.2683,N,11329.5876,W,1,04,5.16,970.40,M,-19.817,M,,*7C +$GPRMC,012523,A,5332.2683,N,11329.5876,W,0.0000,0.000,261106,,*36 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504323.000,"ept":0.005,"lat":53.537804835,"lon":-113.493125994,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012524,5332.2683,N,11329.5875,W,1,04,5.15,970.47,M,-19.817,M,,*7C +$GPRMC,012524,A,5332.2683,N,11329.5875,W,0.0000,0.000,261106,,*32 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504324.000,"ept":0.005,"lat":53.537805003,"lon":-113.493124821,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGSV,3,1,12,26,06,138,00,24,14,077,29,00,00,000,00,00,00,000,00*78 +$GPGSV,3,2,12,06,77,230,26,29,15,126,26,02,16,080,35,21,35,257,26*7C +$GPGSV,3,3,12,00,00,000,00,30,22,204,29,10,54,072,44,07,40,297,29*75 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":0.04,"tdop":2.04,"hdop":5.15,"gdop":5.54,"pdop":5.15,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":29,"used":true},{"PRN":6,"el":77,"az":230,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":35,"used":true},{"PRN":21,"el":35,"az":257,"ss":26,"used":false}]} +$GPGGA,012525,5332.2683,N,11329.5874,W,1,04,5.15,970.54,M,-19.817,M,,*7E +$GPRMC,012525,A,5332.2683,N,11329.5874,W,0.0000,0.000,261106,,*32 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.2,5.2,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504325.000,"ept":0.005,"lat":53.537805171,"lon":-113.493123648,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":85.29,"mode":2} +$GPGGA,012526,5332.2683,N,11329.5874,W,1,04,5.15,970.61,M,-19.817,M,,*7B +$GPRMC,012526,A,5332.2683,N,11329.5874,W,0.0000,0.000,261106,,*31 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.1,5.1,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504326.000,"ept":0.005,"lat":53.537805422,"lon":-113.493122558,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012527,5332.2683,N,11329.5873,W,1,04,5.15,970.67,M,-19.817,M,,*7B +$GPRMC,012527,A,5332.2683,N,11329.5873,W,0.0000,0.000,261106,,*37 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.1,5.1,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504327.000,"ept":0.005,"lat":53.537805590,"lon":-113.493121468,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012528,5332.2684,N,11329.5872,W,1,04,5.15,970.74,M,-19.817,M,,*70 +$GPRMC,012528,A,5332.2684,N,11329.5872,W,0.0000,0.000,261106,,*3E +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.1,5.1,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504328.000,"ept":0.005,"lat":53.537805841,"lon":-113.493120462,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012529,5332.2684,N,11329.5872,W,1,04,5.15,970.79,M,-19.817,M,,*7C +$GPRMC,012529,A,5332.2684,N,11329.5872,W,0.0000,0.000,261106,,*3F +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.1,5.1,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504329.000,"ept":0.005,"lat":53.537806093,"lon":-113.493119457,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGSV,3,1,12,26,06,138,00,24,14,077,30,00,00,000,00,00,00,000,00*70 +$GPGSV,3,2,12,06,77,230,26,29,15,126,26,02,16,080,35,21,35,258,26*73 +$GPGSV,3,3,12,00,00,000,00,30,22,204,29,10,53,072,44,07,40,297,29*72 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":0.04,"tdop":2.03,"hdop":5.13,"gdop":5.52,"pdop":5.13,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":14,"az":77,"ss":30,"used":true},{"PRN":6,"el":77,"az":230,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":35,"used":true},{"PRN":21,"el":35,"az":258,"ss":26,"used":false}]} +$GPGGA,012530,5332.2684,N,11329.5871,W,1,04,5.13,970.85,M,-19.817,M,,*72 +$GPRMC,012530,A,5332.2684,N,11329.5871,W,0.0000,0.000,261106,,*34 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.1,5.1,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504330.000,"ept":0.005,"lat":53.537806344,"lon":-113.493118535,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012531,5332.2684,N,11329.5871,W,1,04,5.13,970.91,M,-19.817,M,,*76 +$GPRMC,012531,A,5332.2684,N,11329.5871,W,0.0000,0.000,261106,,*35 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.1,5.1,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504331.000,"ept":0.005,"lat":53.537806512,"lon":-113.493117613,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGGA,012532,5332.2684,N,11329.5870,W,1,04,5.13,970.96,M,-19.817,M,,*73 +$GPRMC,012532,A,5332.2684,N,11329.5870,W,0.0000,0.000,261106,,*37 +$GPGSA,A,2,00,00,00,00,,,,,,,,,5.1,5.1,0.0*33 +{"class":"TPV","tag":"ID8f20","time":1164504332.000,"ept":0.005,"lat":53.537806763,"lon":-113.493116691,"epx":21.594,"epy":14.695,"track":0.0000,"speed":0.000,"eps":43.19,"mode":2} +$GPGSV,3,1,12,26,06,138,00,24,13,077,30,00,00,000,00,00,00,000,00*77 +$GPGSV,3,2,12,06,77,230,26,29,15,126,26,02,16,080,35,21,35,258,26*73 +$GPGSV,3,3,12,00,00,000,00,30,22,204,30,10,53,072,44,07,40,297,30*72 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":2.46,"tdop":1.35,"hdop":1.50,"gdop":3.19,"pdop":2.88,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":13,"az":77,"ss":30,"used":true},{"PRN":6,"el":77,"az":230,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":35,"used":true},{"PRN":21,"el":35,"az":258,"ss":26,"used":false}]} +$GPGSV,3,1,12,26,06,138,00,24,13,077,30,00,00,000,00,00,00,000,00*77 +$GPGSV,3,2,12,06,77,230,26,29,15,126,26,02,16,080,37,21,35,258,26*71 +$GPGSV,3,3,12,00,00,000,00,30,22,204,26,10,53,072,44,07,40,297,30*75 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":0.07,"tdop":5.53,"hdop":20.19,"gdop":20.93,"pdop":20.19,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":13,"az":77,"ss":30,"used":true},{"PRN":6,"el":77,"az":230,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":37,"used":true},{"PRN":21,"el":35,"az":258,"ss":26,"used":false}]} +$GPGSV,3,1,12,26,06,138,00,24,13,077,30,00,00,000,00,00,00,000,00*77 +$GPGSV,3,2,12,06,77,229,26,29,15,126,26,02,16,080,37,21,35,258,26*79 +$GPGSV,3,3,12,00,00,000,00,30,22,204,26,10,53,072,43,07,40,297,26*75 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":1.01,"tdop":6.33,"hdop":30.52,"gdop":31.19,"pdop":30.54,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":13,"az":77,"ss":30,"used":true},{"PRN":6,"el":77,"az":229,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":37,"used":true},{"PRN":21,"el":35,"az":258,"ss":26,"used":false}]} +$GPGSV,3,1,12,26,06,138,00,24,13,077,30,00,00,000,00,00,00,000,00*77 +$GPGSV,3,2,12,06,77,229,26,29,15,126,26,02,16,080,37,21,35,258,29*76 +$GPGSV,3,3,12,00,00,000,00,30,21,204,26,10,53,072,43,07,40,297,26*76 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":1.01,"tdop":6.37,"hdop":30.52,"gdop":31.20,"pdop":30.54,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":13,"az":77,"ss":30,"used":true},{"PRN":6,"el":77,"az":229,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":37,"used":true},{"PRN":21,"el":35,"az":258,"ss":29,"used":false}]} +$GPGSV,3,1,12,26,06,138,00,24,13,077,30,00,00,000,00,00,00,000,00*77 +$GPGSV,3,2,12,06,77,229,26,29,15,126,26,02,16,080,37,21,35,258,29*76 +$GPGSV,3,3,12,00,00,000,00,30,21,204,26,10,53,072,42,07,40,297,26*77 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":1.01,"tdop":6.41,"hdop":30.52,"gdop":31.20,"pdop":30.54,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":13,"az":77,"ss":30,"used":true},{"PRN":6,"el":77,"az":229,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":37,"used":true},{"PRN":21,"el":35,"az":258,"ss":29,"used":false}]} +$GPGSV,3,1,12,26,06,138,00,24,13,077,31,00,00,000,00,00,00,000,00*76 +$GPGSV,3,2,12,06,77,229,26,29,15,126,26,02,16,080,37,21,36,258,29*75 +$GPGSV,3,3,12,00,00,000,00,30,21,204,26,10,53,072,42,07,41,297,26*76 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":1.01,"tdop":6.48,"hdop":30.51,"gdop":31.21,"pdop":30.53,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":13,"az":77,"ss":31,"used":true},{"PRN":6,"el":77,"az":229,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":37,"used":true},{"PRN":21,"el":36,"az":258,"ss":29,"used":false}]} +$GPGSV,3,1,12,26,06,138,00,24,13,077,31,00,00,000,00,00,00,000,00*76 +$GPGSV,3,2,12,06,77,228,26,29,15,126,26,02,16,080,37,21,36,258,29*74 +$GPGSV,3,3,12,00,00,000,00,30,21,204,26,10,53,071,42,07,41,297,26*75 +{"class":"SKY","tag":"ID5c","xdop":1.44,"ydop":0.98,"vdop":1.01,"tdop":6.52,"hdop":30.51,"gdop":31.22,"pdop":30.53,"satellites":[{"PRN":26,"el":6,"az":138,"ss":0,"used":false},{"PRN":24,"el":13,"az":77,"ss":31,"used":true},{"PRN":6,"el":77,"az":228,"ss":26,"used":false},{"PRN":29,"el":15,"az":126,"ss":26,"used":false},{"PRN":2,"el":16,"az":80,"ss":37,"used":true},{"PRN":21,"el":36,"az":258,"ss":29,"used":false}]} diff --git a/test/daemon/uBlox-aek-4t.log b/test/daemon/uBlox-aek-4t.log new file mode 100644 index 0000000000000000000000000000000000000000..6d93fc465b3bfdbdff11e869b58d41075c471500 GIT binary patch literal 14729 zcmeI(cT^PD9tZHd%Py-(6G1u*K}8gBSrH6sa6vRiV*%`%4In5gML@(}qT(~Q`0R>? z*q+f?5==yW_7=ObMPqN##E24%1B;8+&lNOv!CB@?~MLj zhs5-hNKT)To0y%J!-a7PY3XSh{kYh?#6d$6bJH?2xOQo|Tz!3PyWp^dKpTH9rhi&i zPD-vx8x+P5NlH)4%}wbWoHQ&FhfrVbhNR^7PvM#;({CXIh2L8COHWK26q1~o{vKMj zO3cN%b&a`JDao8ptBpWe`^;qFw2@q=L5af>xxOibxR}K3^puPs?!%P)wB*bX92yed zxI?3+5h2=$ZZ`gCmCzq2OidejrzH&${wCR( znYmnQW;TYGiwWg~U=*8@R7wvvBsghMWCG>c_=&4dgxyO9&0oS#EM>1U2zu?c2t1O`F6<1c%4!LW3hh zwb8*^U4$+;OxG$VpdOA<*|O-i@d=S!R$@+0N?*>M+PTmK;=6Q;jqBP%AH(5K*r`=! zJooSjRoV)b3HpRC@hv*G+wkvANlM3q%-;E#>Kk=6wsXMF?gg0(^b?aCu21WoqYr9n z73-kk*!aeNRwI8}tZ%-l@013Qhv@rUXs}nQ@nwG9XU@LdwNO9LJ*>ZLmpuKNd&Bnn zXmsp9ch@wxT~er@J-At9?5BD9B@L$SRcq?A(Ec%tdS5TpFZiL?#poS*`V|T5_S$L! zS+{OaJi1pa)DP5Uxyyr%VItyOMTlV)#9vQs#+_pd!w(J{B<8T&?U#hT(hP;!w9ah?v16^0w^ zSeY`b2XoO`8QLpOKU5h8uxDlJ!RMKi&N?eh5gw|U!PpAEnjwl+lvN+Rj;VDvSse4# z)i8X;ww2jtea{?qb_Qp5sm$JRj@>MC$ePAtbdH8Lit@6WhUx5TnNt?e+;z1KZ57+g zoDF$scS-vlgZJ4kfE^J2#+mXU{l&~EwY{v-OvBGwoupKXK zKM}SQgzZFOJ4x6URQ81vur-<-Vy8S z?0UdYd%^Q`OmB?LwFc_62ZeTyC}SSB3KpG9draYgD?DZz`vS94x?#*g-G#YWDIGMv zEy_2a|o@ zJ(y4EW??>2(PE7~(}sAM9OFQ5f%I}y%6p6{YZ>=_oQ?Zx7vsKdZR5U^t8w3^nsMKy zx^ch2;z@qf+c06N;Xb{vORZ)7we$xAF~=l zS&sSTUJSbrWqtBkdw(cV`nsNmey)G=j3TPD;vtQo4NtlwCOLiRUgTyRC(}vUfUn6&Um?-Ow^UKQaG*Na5%Bxa#zoe}D|EcVm2bd3(rTG|@C8>?`ialpfc)nx~KPK_rd0U^a{Cy(57dLOYvY;YS*~^}ivX}k0#6nqRlJ(aS zP_`_dl=Wlduk=a!49YIIop3u6%8oosxvU@aYkB7E3n=^Lxj=0rDEp2|Qg&SQltxfC z=-=(UKZdeljU;8;{}C}6%APFsx9JOIZw`}`J(nMvmUEwrjEA0lV^rsH`~8x5~c0vY|8Z zxqz})aHWicDU{3BK`u+m{!oRoGd@FGC`)b4m94%4HBgpnWMwb^=E{0Tqa4Z_&n7B6 zx+lt^ER~b8EqBPudT3G;PzPnHE(-ciH_2tydelK#sf z9nLQ+TVkSYUzAs+?3p*rWeqzqA1Eu#^<^%b`;Sp}{A!FJ%F_5NSN00zv!pD^Dl1Dl zs3m2c@Gi*8Qa@EGdlSdV%F>lpxw5moWMw1zr^egv0 z{m6%YwVOfN{xv0K1D7_^L)mSU@6Anzvfs+eUR|MD0%cp*Sh6w~%B~ql$~Iu#JX^Q8 zpefXM9C5+!fm@#b^3SAf1GYN(T+bm;cC@ZX-%U{VPAuiJK`$rMw_QPG5GnhSsO;Qq zQCaqzsBA30vCxWvb6Zhaah`9LeSKxUt?;>kvIlUbl#AaGUMhRC3S~>%p)Hi9w&p7a ze~^AqmTF{W_dj%Hx-U@9g<+RtCfs15eFCtoMMSWsD+UKGC`-9)YZGM;nkf4a89gc604oNcOUgFDia|S!>s87IVa4FbH&k{x zt+YT{nvXG;{pTo~5sUFdSsH)k%3gzfmXsw~Wo3WCz9nU8DMVJ5`l(9Ut2jnhmKGZ; zS9UleoS4hDu+3hm*mXa+^Pjiuf-V;NboaZVih59Uto84i#|uj5x}zIbjGUoqLs8jv z{*tm6X8Nf}*)iE$)KGS2Bq{65#vd-klDpR|Uu zhioKey9_)P2W2-q)Mg`~tj?Zt*#H(gvhesfQ1-lUbn}T&);(LwWnHVa-2i3J{|W%7C``@sYATz2}NeY0#|uFJYx4cRR!d*^|uY|<7nmpwQ~ zR92klTV-Eg+3G{_xq!0kaiydJILc+~BA0bVE_5#*>YyyuSyI*) z%BmpfU)NXJG09~cq5M_K(z@)~SFIRKs(M}aKr-e7WobS} zW&hqQ29r$IWy{hqeke=huUy$1kk68`B&)0}ebcw3EG;a{%2Gd7DSHve$jU0w)?C?1 zChM{p<)X3*ha=XX@?VB{GH+#5mTJ|6ZMf~m*w+e{nlY9yn*EHgd%%{BbaP?OtHc&o zO1Z@xWjOP{+k`FBr7%^wf^D0U&x+2uuyI}Ngce1}^+|G-kKAI?vjmp1L(AsOzs;*V zSMWU=bznvLwOO+QJ2nRA*t|t-p;pT+a-Q~Q`So?Ia6|}GWjy1L_3p`vcGYJ628bTE!*t2 zl2;wC$@V|~lrLK4!1hFmEnawtEwF~oYxZN68h>T!WwNTjYxO+(le5LhuUg>_3f(E3 z8z4obA6$Fh$XK9{x_F}aUauT|NDxINA2vSXcFsmbq}hpQ2FD{Jg-xM|ggb@B9ZP}` zk)D+pF2^AvZItu=IWzM6A|icu_(9raL?r(jQbY<{vgmt6B&~h>vvUxUGCr0f(wgLM zlMs;-?xu%sKtvk2k0MfiwmR*LM=6L%nJoRQ)rd$_GtKkfHoKO#N)6^0-p&BK*)9*caY5$RYJ5oyCOXp4wM zZOtRn(L~fBB2kSTk>);iW!HzJ91+QQHZdXqKQYKM|EJ-zDb# z?;aDC73cX@+1FS0ngO2+C_4sMO8Xk3vh|SnyCLsCT7|N;e9;!lQd@InOCF&H%2JK2 z?C2M+Y|C|&Ls{e5L}jgL1qI4dIVoG?ds$f@P3fPggR)eY`?XQo6bN{So?n2nRA)h1 zwKtUAU_n_QC>vp-?6)S$w!r!2)s=slDBB(7RVjP&4VBIM0rP>fG@pN>vWIZ*jFhGE zSFY^OaLSUhB&)0}7W!C-h37Hoo~fMoQ$JNHy9dX}%JSH+Jn!$o$;v)oYJ=x77+Z?x zF&;$G^BBH(9>a>!^BA{19E9gF1|eq{86hg0+DKFuLla)_`b{3W1SC1w3;??btDBJtb-A@XkY?lMHx?)_z zE*-wC-B(a{Zx2yfYdqaXcM3m$E-D-6CFZhMm7=oZJl`t&`pO#ON}8+A~Y>XaLdcM55BrN<@IL0PJ^psb3Nor;{~FRLpmZzwzMnK750WuojLoL^RU zqNHp9a@mC_uS(gYZ>a1sy3+<_X+B0}UH{g13Qbp6j^eu|DNEz8T-m$O4$7K5p(Z}{ zMjXk?sH_oAuWgLD?08vR*Hh?X&V(jX_ZM3x%ZY=NFds zg0h7t)-KG0vQc9sWv|`uzW~Zkzm&Lk1C(tkJX?%4Y_^iOxlyQ}vO&M(0FOWNRb0cAVlN(lv2rpg|MvhHxk^kw>N@tLz|3uURT zc`o}IJ;erPsYX_|gW8P^EJit$HJ(jWb{|#)Nm(iTvK1!EQa@EG`>lzxKIpUZTvq8XEBjr|)Og>I zSt(;zS)<17#P+uWdC8%8n{9Uooh8u+@lkC>z2D z;MrmitJS%pvRNuo*-rJuTz1!XQCV@GZdP3ROh|7Of)(g38yos_CO_c40^UKPvFj4k4%3q}{t;=qg zl=b*OpDq6A2IhlYmgZwrcK+Wwmo@z#93Hq!Mat6nD_8dWN|Ys8Wo2!!Z%NrFCdyJj zRVll{L|H%dX|Am4|KPZkA}ia}J$2zWU!{618>?JCy7RbF{&|t_SjBIKa^I_tGd)M6 N8&(H7!%uED{{xV!U?u +# Date: 11 Dec 2006 +# Location: Ä°zmir, TR, 38N27E +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$GPZDA,175503.00,11,12,2006,00,00*64 +$GPRMC,175504.00,A,3825.60966,N,02708.53787,E,0.142,113.02,111206,,,A*6F +$GPVTG,113.02,T,,M,0.142,N,0.263,K,A*3C +$GPGGA,175504.00,3825.60966,N,02708.53787,E,1,07,1.24,58.1,M,37.7,M,,*61 +$GPGSA,A,3,19,11,25,14,01,31,22,,,,,,1.99,1.24,1.55*0C +$GPGSV,3,1,10,19,62,212,26,11,40,306,25,03,35,184,,20,16,253,*7C +$GPGSV,3,2,10,28,05,310,,25,06,146,43,14,54,071,44,01,53,162,44*71 +$GPGSV,3,3,10,31,05,137,41,22,28,055,35*73 +$GPGLL,3825.60966,N,02708.53787,E,175504.00,A,A*6B +$GPZDA,175504.00,11,12,2006,00,00*63 +$GPRMC,175505.00,A,3825.60968,N,02708.53789,E,0.106,112.88,111206,,,A*6D +$GPVTG,112.88,T,,M,0.106,N,0.196,K,A*36 +$GPGGA,175505.00,3825.60968,N,02708.53789,E,1,07,1.24,58.1,M,37.7,M,,*60 +$GPGSA,A,3,19,11,25,14,01,31,22,,,,,,1.99,1.24,1.55*0C +$GPGSV,3,1,10,19,62,212,26,11,40,306,24,03,35,184,,20,16,253,*7D +$GPGSV,3,2,10,28,05,310,,25,06,146,43,14,54,071,44,01,53,162,44*71 +$GPGSV,3,3,10,31,05,137,41,22,28,055,36*70 +$GPGLL,3825.60968,N,02708.53789,E,175505.00,A,A*6A +$GPZDA,175505.00,11,12,2006,00,00*62 +$GPRMC,175506.00,A,3825.60969,N,02708.53794,E,0.074,112.93,111206,,,A*6D +$GPVTG,112.93,T,,M,0.074,N,0.137,K,A*33 +$GPGGA,175506.00,3825.60969,N,02708.53794,E,1,07,1.24,58.2,M,37.7,M,,*6D +$GPGSA,A,3,19,11,25,14,01,31,22,,,,,,1.99,1.24,1.55*0C +$GPGSV,3,1,10,19,62,212,27,11,40,306,22,03,35,184,,20,16,253,*7A +$GPGSV,3,2,10,28,05,310,,25,06,146,43,14,54,071,44,01,53,162,44*71 +$GPGSV,3,3,10,31,05,137,42,22,28,055,36*73 +$GPGLL,3825.60969,N,02708.53794,E,175506.00,A,A*64 diff --git a/test/daemon/uBlox-lea-4s.log.chk b/test/daemon/uBlox-lea-4s.log.chk new file mode 100644 index 0000000..d9998ea --- /dev/null +++ b/test/daemon/uBlox-lea-4s.log.chk @@ -0,0 +1,36 @@ +$GPZDA,175503.00,11,12,2006,00,00*64 +$GPRMC,175504.00,A,3825.60966,N,02708.53787,E,0.142,113.02,111206,,,A*6F +{"class":"TPV","tag":"RMC","time":1165859704.000,"ept":0.005,"lat":38.426827667,"lon":27.142297833,"track":113.0200,"speed":0.073,"mode":2} +$GPVTG,113.02,T,,M,0.142,N,0.263,K,A*3C +$GPGGA,175504.00,3825.60966,N,02708.53787,E,1,07,1.24,58.1,M,37.7,M,,*61 +{"class":"TPV","tag":"GGA","time":1165859704.000,"ept":0.005,"lat":38.426827667,"lon":27.142297833,"alt":58.100,"track":113.0200,"speed":0.073,"mode":3} +$GPGSA,A,3,19,11,25,14,01,31,22,,,,,,1.99,1.24,1.55*0C +{"class":"TPV","tag":"GSA","time":1165859704.000,"ept":0.005,"lat":38.426827667,"lon":27.142297833,"alt":58.100,"epv":35.650,"track":113.0200,"speed":0.073,"climb":0.000,"mode":3} +$GPGSV,3,1,10,19,62,212,26,11,40,306,25,03,35,184,,20,16,253,*7C +$GPGSV,3,2,10,28,05,310,,25,06,146,43,14,54,071,44,01,53,162,44*71 +$GPGSV,3,3,10,31,05,137,41,22,28,055,35*73 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":0.78,"vdop":1.29,"tdop":0.81,"hdop":1.10,"gdop":1.88,"pdop":1.70,"satellites":[{"PRN":19,"el":62,"az":212,"ss":26,"used":true},{"PRN":11,"el":40,"az":306,"ss":25,"used":true},{"PRN":3,"el":35,"az":184,"ss":0,"used":false},{"PRN":20,"el":16,"az":253,"ss":0,"used":false},{"PRN":28,"el":5,"az":310,"ss":0,"used":false},{"PRN":25,"el":6,"az":146,"ss":43,"used":true},{"PRN":14,"el":54,"az":71,"ss":44,"used":true},{"PRN":1,"el":53,"az":162,"ss":44,"used":true},{"PRN":31,"el":5,"az":137,"ss":41,"used":true},{"PRN":22,"el":28,"az":55,"ss":35,"used":true}]} +$GPGLL,3825.60966,N,02708.53787,E,175504.00,A,A*6B +{"class":"TPV","tag":"GLL","time":1165859704.000,"ept":0.005,"lat":38.426827667,"lon":27.142297833,"alt":58.100,"epx":11.706,"epy":11.682,"epv":35.650,"track":113.0200,"speed":0.073,"climb":0.000,"mode":3} +$GPZDA,175504.00,11,12,2006,00,00*63 +$GPRMC,175505.00,A,3825.60968,N,02708.53789,E,0.106,112.88,111206,,,A*6D +$GPVTG,112.88,T,,M,0.106,N,0.196,K,A*36 +$GPGGA,175505.00,3825.60968,N,02708.53789,E,1,07,1.24,58.1,M,37.7,M,,*60 +$GPGSA,A,3,19,11,25,14,01,31,22,,,,,,1.99,1.24,1.55*0C +$GPGSV,3,1,10,19,62,212,26,11,40,306,24,03,35,184,,20,16,253,*7D +$GPGSV,3,2,10,28,05,310,,25,06,146,43,14,54,071,44,01,53,162,44*71 +$GPGSV,3,3,10,31,05,137,41,22,28,055,36*70 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":0.78,"vdop":1.29,"tdop":0.81,"hdop":1.10,"gdop":1.88,"pdop":1.70,"satellites":[{"PRN":19,"el":62,"az":212,"ss":26,"used":true},{"PRN":11,"el":40,"az":306,"ss":24,"used":true},{"PRN":3,"el":35,"az":184,"ss":0,"used":false},{"PRN":20,"el":16,"az":253,"ss":0,"used":false},{"PRN":28,"el":5,"az":310,"ss":0,"used":false},{"PRN":25,"el":6,"az":146,"ss":43,"used":true},{"PRN":14,"el":54,"az":71,"ss":44,"used":true},{"PRN":1,"el":53,"az":162,"ss":44,"used":true},{"PRN":31,"el":5,"az":137,"ss":41,"used":true},{"PRN":22,"el":28,"az":55,"ss":36,"used":true}]} +$GPGLL,3825.60968,N,02708.53789,E,175505.00,A,A*6A +{"class":"TPV","tag":"GLL","time":1165859705.000,"ept":0.005,"lat":38.426828000,"lon":27.142298167,"alt":58.100,"epx":11.706,"epy":11.682,"epv":29.636,"track":112.8800,"speed":0.055,"climb":0.000,"eps":23.41,"mode":3} +$GPZDA,175505.00,11,12,2006,00,00*62 +$GPRMC,175506.00,A,3825.60969,N,02708.53794,E,0.074,112.93,111206,,,A*6D +$GPVTG,112.93,T,,M,0.074,N,0.137,K,A*33 +$GPGGA,175506.00,3825.60969,N,02708.53794,E,1,07,1.24,58.2,M,37.7,M,,*6D +$GPGSA,A,3,19,11,25,14,01,31,22,,,,,,1.99,1.24,1.55*0C +$GPGSV,3,1,10,19,62,212,27,11,40,306,22,03,35,184,,20,16,253,*7A +$GPGSV,3,2,10,28,05,310,,25,06,146,43,14,54,071,44,01,53,162,44*71 +$GPGSV,3,3,10,31,05,137,42,22,28,055,36*73 +{"class":"SKY","tag":"GSV","xdop":0.78,"ydop":0.78,"vdop":1.29,"tdop":0.81,"hdop":1.10,"gdop":1.88,"pdop":1.70,"satellites":[{"PRN":19,"el":62,"az":212,"ss":27,"used":true},{"PRN":11,"el":40,"az":306,"ss":22,"used":true},{"PRN":3,"el":35,"az":184,"ss":0,"used":false},{"PRN":20,"el":16,"az":253,"ss":0,"used":false},{"PRN":28,"el":5,"az":310,"ss":0,"used":false},{"PRN":25,"el":6,"az":146,"ss":43,"used":true},{"PRN":14,"el":54,"az":71,"ss":44,"used":true},{"PRN":1,"el":53,"az":162,"ss":44,"used":true},{"PRN":31,"el":5,"az":137,"ss":42,"used":true},{"PRN":22,"el":28,"az":55,"ss":36,"used":true}]} +$GPGLL,3825.60969,N,02708.53794,E,175506.00,A,A*64 +{"class":"TPV","tag":"GLL","time":1165859706.000,"ept":0.005,"lat":38.426828167,"lon":27.142299000,"alt":58.200,"epx":11.706,"epy":11.682,"epv":29.636,"track":112.9300,"speed":0.038,"climb":0.000,"eps":23.41,"mode":3} diff --git a/test/daemon/uBlox-lea-4t.log b/test/daemon/uBlox-lea-4t.log new file mode 100644 index 0000000000000000000000000000000000000000..0c42dbaf2c87248dceced05b001827d3b5cffb02 GIT binary patch literal 32600 zcmeI*2T&AA`#5` zXU;ii&v2e%MqvNnXM4uo;naJ1>-Sdut#Yew5Bu5PnQ3-EPfvHx;AZNk3hx;mr|J>i zySobiuiGyssekk@J>ymGQRP)WUfy1+u1Tu+p50XqLR;2T#q{sjt9w*DYSqEN;=A|n z6Q}AD6Vp2>NEO$;yY_Y3cdFYwv~8ni4OG#6wPoF+#ER%&FiT`>-B4?Y8lq7B)!5+`-*UNc&nB*nm5Uqxvi^#rKN1s(%Z#f7!_fqUbap5 zJ&>xt+IE|*k&SD-+O_o2I(AA=HsQ{y`a@== zsUMtgQ&p*nSK9{n47N~|GVqBBJh1z0nmQ)vA zh9%`_N79WJlTk?4pq;*xhW4m{{iS zV;N&7bMh$`*^+I~wu-rilH!qdWG}NzM0&_JWLw9SkTvqLiM_{6d~73|$j)Wk#dczW zKK79jGM4QS6M@$|Mg}lNwo_y!c0Idf%rcaeiafyHW;;i|We>Aek)PO}>_lhU|0M16 zAno&D?eh@r^HA;cFzxej?ehrj^GNM;vi5nD_Ib4Sd5rdXtoC`F_BloSJYM@eLHm3R zEhtm?G5W+!dSSrOs`G0nXx=ZFSN-`37FWvMK>S_t|6AdI*^C*p!!xX=Ttr<%D{Wmn zSvH%*F0nY)l~rfg(h!kbY9sRbjI}XktmX*D?8l;9#mo8DER<$=M|nMzyOhwrp8kE- z(~4bF%A88LRaEA6Ma-4Q;)~~L-sWgD^qRgh#(F3a^E#@nhffD%*5(SAMkQn|@uSSn zT1$K0LSCKQ+qtM>hK7?)>`j1cG@lS z0t>z0j@6fM4`U8EHt|tX*e3nkQX!TyrcmmBHZ|7$EH}~pY=hsM_%JRa{=}Fg{Q`uC z(p>xr@1KtS_c7D%zgRlDF*hxBrC{3OKg!Esnt2^n@}G0#)Xn#kX)1%ttVr2FnAY2~ z{*@9iZFV!kw3&~p)`3M$BWjx7$d6Z_C?lA*(`r>enAUpHk+??{2dHm*3Z@N<-BBB+ z6|Xe8OmUdDCP^@D>|as4@IIP@=X(3Wv@*S-xoKv{X2!v^-|Ej#GKXoy2f#EKn-!B} z^b1V$=-_MV0n_>#lWFC|!(!K4o;wf()0#Jznl^cR=AG(fT5G9k+5P0>H^a1*u4I~n zyzwb++MhApw7@Iew4VF8X}rCDnzme1Sktzx$EOgcQ47v}%}w)%X_H{uewe1x`_|B} zQ{S|9Em0SyQC+ENnUxWNX%rDnD?6I8*Dp~H({x+orm;Uz4%4WdzAiU?Mbj!NKhHr7 zrctbCQJrbO;=5h5Jz_A8Vxnm(nAQsKA(}Q!&$OI;ooNm9OzVjE5=|S-O;eC*Tfbsj zIhgkBzckI^UrgKG0>=Z>=y-la({cl`|1gdApFS=0h-uAD8@X0A&1Bc<{i*7`6Pi08 zhG`>;Hs+?iS~kZYrd`SmTv;5Zo$V}`c425`V_0;5!pJKdVA|g~zXV$tIm>;944qLL zrv1I{d4qK@?RO8swE9mwSi`iiNA)UZ$H%MN^%P87G2ZAX-pA8Cb80P^7F16#Ez#Dp z2TW6BO!bz-G@q_yn#v%{t7NZXFm295+4Y(*Eugs6v_lm)?f)<%L2VN)HO(S&Y5ihk z+FYq=34K?WTLRM#*An_^x43C%<9S>C@sgXCGlQGP+v}%kg*R=n3qFM~jaqQ|dv01q zm^K!st%Yg!-!aYOG3vrJsw*{Z)9;ADG>V9(6-{C67(U-*nr>?rN=pBEVJL@bR8IeX z8Yr6Pq5O0dF_=cN_9omkdd(m>RQ4`nFpXmRrqxAUG;Jg|&Bz)3G%Nfp_R~W3OslGA zTC`xA3Z^amhH2C_`Cs(YX2@_nFpZ8!XIcr_kJ3-e%f$Y}G}?bOk@nF6{cM9`70}tt zP)^kNkM7M3970&U#bCzNd75tKi#6N(zSh*8a$9qC!f}lYyQ~R4$7{&!{!yb&o+he5 z4FlAulE-TpSp1{LH?|RitV??(xB5?OgyO7(Y8X2FqsBM(DhNF>s$o>}A2q(QR~<3- zKs6MW|7ndDjMp$W6>EI74`B%wQH<5i)BK9IvP^ib$sBcC)4oTtMvk^JiQqL%ZNwV? z_WNkR05vdr5WP{zO1&C1PDfT+JLU4eG-RcD=h4$vy0FS-#fwxyR#H5VNw7jz%J`hA z9X${~2`84ME=opL+ABv-+pv_}C-?lYYiH8beWLSA#~~}lIUp-3E3yq6N+_P)nWtW# zF~R#BvQmCiWF@5s>zyC4`ZBW8?PirS8Y3&67$b}x95J2R23hICrlk))z8au*wHC5c z=i+B)AuC;-XOj_%taPQdG%Fp5(VW_ftW-LLvQnup=Q%ADG1-s8kd-D$v(mKO-Q{K= zD;YdntsOmBYs|CK&P4uccg2|xjUIG>N;G=F+v{gmDtuO&JPVE>D^Uw>`pmPE3$oHM zWTkn?N>*RVO79p`vg8?7hxei`vJ%yGl)YnZ(u;|V&Bo{$ zWhLF#cvi}}gmPphDyNL|u7;SEJe40H4rL{ZH8<2{rJl$ne}6&@S&3poR#MXFfj8bm z%u3_6S;@?hMi1zLtfZvTg9$#FFfFvaVA_fU8T(;cf^8$O z44C#fL@@38{*Xs7Evrb63$0*Uj|pU&i^2LKzZY!+)8tjlPkRZ|0-g${Wt{R`57Ra! z4Vc^&rX9}NEg3zibzskySeWMAMrzuHd+uqw$+Q?U&HjsZm4deQ9SPHZm+_wV1|>Ib z(GcENX(hR7SMs@OyuE&!R(R8rOz+&Fnj-r5-|Em_~J_ zrY#(a2u!1hXxeRzRwufl9H!~E#!dT3qnf?x}s^7l^+@*2Gb~3SCgw95vA9V zX~#kkgJ~4gH!T5i(X=GNw2}o(v(huIfnb^oMnrq+nP!yt&k<1?J(ybv)9ec|B3i#T zjt8dE@%)IU9W=xK!!+7|{0g)Wzd_uzsyhVJN?qv_0Mk+yw13(RrX6}lrm0xvn0DFT zFwHe1*Vz)L)n9l-V%nZG+jD*ji?LLUR!;*#9-QzvVv)4mvov5)2yR= zc}<0BV|@hEvIoC@1JfcrD}Cq;)1G_~OndugS`C=?xl-RI4`Ev3#t1%o(7WlpBQPx} z;;%OGFztR*X+Q1EPQzqRm^Snm>FB|XVIRs(CDXb}`)OOR`4*3bX_Yg1KP}vVo0c+y zw^foKH*IGVZW?c|pQaVwwC+RkDTHa%g2&PGrCA;`nAR7j4TWjS@0b?*0(D^;)s>ny z(Haq$MiJ4pteK33PDD9O(`}8L_Wm`>VH%Z_S4A6&rgEVqK8SD(pW@qy6WiF{Z-I9-Vu->=DmBU&xGLTKLLZqupUzLb_nu)nmVS!L+sPk5@%u z+R=8>e%iG&6Rh*|;?==dFd~Xs5+BRE!5>ejsjUyMU-L(W0cvBhpSEDRMNgO()p})M zUzqm9PcZHD#W@DE)6`>k*DKK*rfnV|_S4!}d%?6aHDYDgVcOB2=%*Q}tNYEKPft+07wD($bx%GSMW(fr_S2epPC3#UrX9M>O|wtnrp1ir zZB?`hH!U=jo5tJgr)h;Ztp#ZU)2Icnm~zwPFs%nn>jTpa3YbP8Rq@=jaYfXHX;fEg zTEc2XU>Ze4)0WL)tkemV!!+I2xM^=kpd6-AIhp3zR5Z<7`St)}FpXm6-|0*n35RCW zNGeRDn7(PV^-LQsnC4KRpBAWRT8y4)6S!$cG$QKojego%ZkpU)Z|3@2=bnY>r)5vZ z@xU}X9-V1F&WPyxD%gLRM*A;dqjECMJxnysNBIWh*kl^T zoL=Q>-e5Hjy`~5DESyw@X%rJpb4EXH9O7a>ElM!Wwt#6KdZta#Gi?wzP2mjFy_lfpDQo*&V)RLswiX|(_N6=)wHwQ~gSve$>nG&5Fe!lR0dU|MbC z%|~v`iBq4SPW?2Pwr)YV2Tb#y`_~*Zn0C9i)U?;hjxCqNv}dcRpJp%jxoK6pD@^Oh zW_N4_(=Is)rZujXR1Bt#IliS?C78C>Q9SqD`q&w!4e}1@oD9>h?h{N4cXG3aX_`;P z24}*w7n@r1ewtIqlcvMxt6OECIcTpzE48lKK}293MMUd{EoAJ zU|oQobp!RR6ISVH`)~H&uN+h zmd|J}$BZ_!9L$uL`mpvxda`kotl5*4N16p;LF|==u@mJCS>`}qgU@JdYZRjz-M`ex z)7EIt9Ps`|Dr?r^PhNx1Xn$=R&$Ttmu(R04yv}zt{crOcd`A0gHJ)l~_%ju@5#Qyl zCaXNJ!DqC;R^tt7%n$QpPN?Bm&xnn~+B4mZ_Sb6srQJr5_BiTT=WDv$_Sb6g z|VdzsI-dsqY#85mf~F?S#3I-|8Hg?uq<%$9Mdw$;fY|t0TW*rTlv1PaBlT zZ`13I4A_JGwqhX0R%sj}{hpsI@>_(>o5g#O-x?IiZ))p)N8Y<7sQ+9}`As)3)U-|R zITz$Ny8?6Lf4YP$zSkmA9o$`--}<#W+0_gAZOA-6KCum}7ind^`!xQ&Nqoffn~etT zh`Djzjz9BT;qzOG5)cXbjao1dzc3neeTw|n0{N{r^4q)bhk<{S(qEI z)&UXZH;Rb)EoLcWyJ!VH@|$jJ7D`&Y{k$m3k>9AC{;lpH<~Kj(OIquS{HA@c$2`B$ zYp5@8d>S$2H;U=^>uCj+fdy8z7szjblvdVj=f+#(y)fo#L}RYB5}#Jq z)A&TtH}czLA;0}!k53#$znA**bUeEJ=Ii^Ttk^pA4EvA#M*ELnf%b8R`k=7x&~d@K zX1_;PgLNmf-oBjz>xQNY*4=#2r~<5O82PZiDXe?8L26ym>l2@Zz&fWVf^`p5Oi!Ll zQ%9yQEcu{3#!AKYK6PGX?}l}o8oDJti;Gt;un?>p`F0rEj=L}dkCl`HrT7~*5YC%<4mz!TD;S{WU?@WDpck!^8^WI6tx5K)j2J0l& zDd%@kP2kYvO0nLzJ9mVvmGr(Sp z)(!cFb;b0o)1Nb6z^zk|b=AINox61)qZO}M2W0r4SXY>%nZP>3j|U|E zy8D42Q&h07)F!gdPVO_wM>7J}`O9yAS`F*!TM7NT{hBRPVcof1A0{4yb&3a-_}a$o zYcHC>y6(F!-dGCj?3(^6Tt!sk^b1&bYTblgD`1_YoiJx^d0g27*6qsc*YXam%L$W? zTXc{wbd85~^FB%Yb@3$+&rXANX4<)Q-I~WYGky0=fOWCjex1&`O6du%mauN&NN!z` zBiy==b9fuRL!u+=(uHvg-i|-5E4+0ta`EYeb<~2^rMY!iV4W|l3xsvgzhm9hA*c)M zsIJsHD~iB6iip${IFctN$J_Czb%nR?Dy_(cb<~0`<+*id zV4bUA-Q(|A*Eb4vVI9?#T91m&=f%C+aGzlzoc zD4*sd2J0wx=d#YaZrHQg*Aatt6w|lvl%91{1nUaUM?Ju&O+1IKEm%kAunB^7bR}iN zH>~SX2qb>O+2JTzXF_xA=+~w9c=7CH zn)>iKtIPmcH^)M-F5j|tRam#heA3==ux|Zz!MfJ0X*8^h4}Imo8`hN>Em#**>HRra z*W_qe?HRDH*J|M$wshXj;jqqVtIbD)_<`y)t#!I{*pSj4yJov4sE6CqIjqjED|6rW zw}y4gI*@fZRT3Tnr_Lz+VBOF`QtQ?>dVlrrB8lpVK)&ukZrxq1 zCn4*2JN~q;@YWrnIVD&}E$HdVtvd?qY+#))`gQleV_oQZ)P;3aS8Cm}Wr)B!iip-J zwlHR~7v-={w>56vJ#Uo5Iw~jY`p1aY1uCD=d_AnA*!go(>tZS*2J0v$T1WFyckv!# zziy^rUBQ0cEj{bn>si-Xu#V1Q*Kq6P)_QlspmSK7&!=-(N4>ds=WkrgQW)zd4#)Ap zIy#;o(Ym^Hg($3}{TIICZ1@dsU6<>EbvAD<#lpHUh4-X)v*XlhzX{fbjI3Q6)|r$x zTx|sF#`;RFtJ%0ohjdt1VX1Hqn^E(@LRhzDmjAkZ_W|l%#mKr!Y{TtflcKP$x6#lm zJz$;sqF~*M4S5N$?)lP|-7{fb@)5zhMHZ8ez`E2?oASrOy2i_eeqF;?_2k@L_gtxWerkgH?*>xqPVD^Ut}(3JP{6v&t=n(E1M8em zQ@_qm-f17VE(7u_J9FV;=_iglH6-QIRR>%==`P`@rhu#Wn5Zv^XX z3s|@C`_{>=^zQnjZ=K!0+#%!bd>jv~qvO$8_v5UcH0y-@hjq07_!Vd$zdpft^vm3P z#WB5^(lCf+Ua8Jj{jx)&43V?eiHU6SQDfHL$(#*Y5XPol&H)oSi2eJ=) z=V;`$<*aP;nVQ9anXq?_%-K-Xuv@`v@R@X~F)+uUO&{scPOrVFG4lJYS$NQjElw!L zp2&)7YuFp}8hj?5YTP&RV-C6H*zW;r}pvv{fvv#wyy0_KOYPt>o%aqw%y zsYVD3Vn=N&vpUGkvNnwE^j)o4eAAv?Fy-5LiOfzl_)I$0xRUM5CVi^RqE;W%7(9Hd z8PI&HW^tA|n`~B8d*qKV^BR06ooXz~N!GMA@nu=VWz5j?v*uD(JGOX?6&oDLYq--W z-j|tls!<`wgGFTounlFFX$)TEXolVxrCF>h#@w2jvtekf#!XSfvbL1{rez}cglNYUkb7nuUA%v5o_byJrGEz__cS~y|5>VP~@Ir^Lg$OKTo#nS^Xzt2dc~MSrDwi{C8I3&W#(8lNv1eIHN3b zQhWtzPP#eI_i|t4q~D*>ScAites=qtGySI`C&e|9=A;S7Hf+2Vny5}(O#N@&>y3;b z&pv~k0y$}okdqv~-v5^5BnQ2*hJVXRCEnq9kdx?mbUDfFhq=Sat2NkvhP{F`%}*R&@`!m`AgoX)`NkQ0)?@L zvn$Sg++DNHlfA29pz>6{t3NLb122Ea zK!c;G3j?XHv|qlVGa@jMBBFs?_cJz$=80gSZfo4Y>ol4H1F4)0oI6}Ju$uA#twVu< z6kB&#YG7U|#9$!B^bMqYWQt=D6Te~LEWyA^xSz%_!9cnjC(XNK&5(BefBrWN+$k9N zjd^sr#edl^kFdw_z(6`4oq<2jJo=gC*nb#E`!5<&S3?H2k=Z{c1Bgs6P~y zt|dAiay8Ew2JUDkH88Ptt1kXFiE7p>D%jXicTd%BSryuigN?h&NNwC2_IlPv*tqO> z-akA&o7>n^xQB`52X3P?*5OhAP-yp`cPcLQT|MJzv;a0z3wEi)ZQKYOKL|D+|Bj7M zZBZ9CQeA2PFqQ6&2OB9O+L&<|_vN7bb-+g5)-05CW85npQ4Slaoc_Ihv|wXtrd)yZ zQL>R@3vu%wx>GT|hWdwB;t+$46ccTvd3PH<8d!^dn8j2*8|UfS*h1rQ`tseA`SC32;Y`pAzW;1N8^eWmV8#d0mA=nrm@p%etw0qFcEfO}i zDI)D3W|+*f^@WWm6Ujy=dDbG;ySK3Mj=j>X18nTyO={!02{&J_hK*0INc)G2_pQ2+ zIVC}Tp@r1OE6<*`HzONUq&AMXb!^-LHZG_kwXs3wjnxZb&V&)Nc$G?uBv= zx5cG3Ne?i~Og0Mb{?o=n+t}G1pJv!dE!ejKw{b0OdT+uRHh*hmr4#wl5h)jx!C*r?kYxA79KRf3IFPVQ|UFWM+m zF2{Hv*+{V&J9)oRv@v5RVz7~7+(t7)vXQ=jV!v^gV59!r71`KB&qlhgUR;yZMbE~z zf{jiE&Yk!Fk8HGWh~t5cbUZp6f1G~f%3Iif*hu>?8t8}&O8v&Ce+m7@)1k=&(Qk}A zr~ab~Y#bK?8*#2$xm(03C)il=gY!p?OT0RCx3u4Qfn9oWkZfEc*cd+bm^*BY4h^et zuiOCjeKWzv1zzR-VPi`1heHm-#?j*i8@IPhIRqPJe|2k>2OI6hxvR6I7L0_A$)nEx z6%HF`+evMFI`N^`hcN@yeTI^aj`FOOkx^zN=Bs!2sP>=_Y#cd8YU9AG4@UKbjm2(B zZG4+Fb4@aAjIJZK@zQX=l6S3P<4&oKeGN9-dc(#=b;w31d|LTq^`oKbQ(>dyqm?+P zwwCWhKZI-y6z-{#>c(x{fHfavqtNbOY>fK(7cTIZGX9gla1k;YpJv!dEjS4C4s;#P za@d#+8|`3Y=2vWdC)}g*&}P(yjZ|0KZ;Z)91U6Dcv~l2Z#!5P%95(8<#%(-D=isoB z%E`S0Q$!mLluPM8O0bb)W4B2AjT5a9gN+mu`i%;j*Qfg;{hN(lzhWcJb+y;CalBxo zV*wj6)%v})>4y6KMkl>-MeBc=>l#b<*?^67JU^n1GY(__VI%Fo_+3_@FHAO`do9>_ zeq_aZu<=2^ZV48!F}oJ^8=d8qSzs$i*l6|kx6AotW9Dv2zww^wuSI8(jmcyquBkt` z<=Cy`Y3es?-xXg48)xOr;`92~$101!#%p#>S1pE(0}=%rPp_~_*touTx4n&FfzvjILOfgN@^^N^Kl3dM}12LZ2UVwYNK1b zl>>)sZKQsqwY*~!Zlg-LH%nv?w=rQJw^3;KpEee{-xx@%RA3{u;J6mt#)X27C1B(4 z-?4E^3)F>;R98CQ*b(b-$wrEZHg-CVJC!7(95(8<#%(_2Rz{TFS?E{*RfW~%u$`0FuK-2gXI9=&QXD~roP zr@L6PnTBpG_EL^!@)C_Et5^_IBj-{Lz7BwDG|bj$elysvDI3Vxz|H$KkA8Jy50#HJ zua{{wElrxUK{>nzUk5-n`d7l=DmXb`Q+AO?Q~FFIOP4#aCtbE_&SN+v=udz4xD~I# z*8xzC1-Q|S&%P44*9~L6$0V|HGCOwfdKXp<6KoH2{aEAxUW2a#pc+nhG@34L{??Sk zp9Ctqsw6wMsu**u7QixBYc!j198>UjTy*OIs75wEb6eL{WaV5LyByS)y{e{SvVj#@ z%1Vu9G1dsQy~u0ubpYDqn4{60svE}2-PdTQ+Bh@YaSm*E+D%RDDvhT4lVpvNu-1TI zQLnAx$yleeH#B8&9d}Nj&TLyR2lk-mbB#5Qe9>bM)~yb()Q`tsV;bG}jy?6`bFO9NAy-W>-6_dcB?hk!j7F|{+LLmXqul3iv6C~9 zs{*<{HRy+2d@Rj19K-MKkWy`oprxe>@!H985oYS$sR&K{#9_jYRFYB8$?f?j$GAx zlQdU7uNsj4NQG-g?@4o2(3O-bxs$ODpq{iJ?>*@Cpb3<#8cTDP{I}Gc>&+9@(fM5^ z{rJx}O0@4sxoSG)DjT`yV4katg?sKa!RLv_IDWwz8S2Li?fx@Y6*^ay#y6016}8}R zt$D7Ri(K^*{dgPXs)OIjRm*RpE^-ysmG zhH~U8DyLj^b*`AJ43&!}B8FT=u|BJHxr)}TscCi&xr$<9Kc2=o=>C0Tt~w{=Do4HR zt|(Vk(92c7@myu3LO*^S&s9crZ>$gB$W^=l%UosiFa3CzIXE8VDmorruKID-2PC9n z|B*8`QS&i(cBiUMV~<=o3>#Tv!NwPTezk**EwWSQ=EBBx4R%Rv zoO<0owgzm>jTdaJ?R&NXY#cE2(5ou2@!2QA#;*0xZiS6`3I3lWVPlilf{n+04*dli z&kl)tTM9N>Ru}v6nW=4IWAE4#o%~_rA6+mvW~A$9$JtdVQU^A+o*|6??%cXP3^uwX z_{1%RjVA_5ZM;zZ?_Za}#+nzUHU?aJ^Li(2Y*FBzSzYfBn;l6u=16V4Ud;Q(M%Xyk zQ`(Q8XOg6jBpdsXjkfY>)wzwY4)Zpja){538DM=V*(kL8Pa6wuqvcb4nqecg;G*{2 z#%ZweIc&6tjr+c1;~d=mfNZ3?QXBntAp#pIBHHMA8FOA?D2I)@t#KQV)7b=Uq;j(H z;e63XBjtjFh`~mRbzY{kk>kW>cGyci@`>xVST$M8~wWqHYx^;%!Q5j&d4fNfQ>y*3fC@_ zwr&st8_(@At5yj%+8-kub^XRqo_~iZVB^&RLcdX!?%oSFzW0C7U>j@7-L8!%R9;hk?fZ z{dsS1pS8OuE`Gi{>-Ki{-M-KJ{{FqaZgWq5ypS`e`^P3fX>J@Y4jnR&=}>s5d0(+|SnPYKSQ@`CUn;;}!_x=GiSIXPW259doG z_+`wg{AeMvv>VR34?jLs94nac|G?zb(Nb~raK+qsa1-RpVR*JZ|3z(%{>GP3%ahw3hiXmd2DQ1~-kzRbY7IXLI6u`R2jI-nD4jbR z38e3Ge%cziN}GcYqp$}&JGWd79YGh^Z#dlX+HLfyWks!M)Cz{^8a6d(n`bX*#wUKH z-8`D)vn_6J;0s%_ti7#CZ|&^B?ZyLiKy$NpgVv!18cynKXv2mB#yy|iqdoX<_iOsK zVc4-9o*l-E=le&R{5FKCf@u#biPZGirfUVJttSXm(=poJ8&k}QDFdi} zZ=*L$Jqk=Su9#>Xi4$YOX-%_QV4}A$dR}S@c^W;EDNO=5Oo$KrjzpxIs8@lBjW%Jr zjjq8D(~OGg+jIb6+M%riqxZPe=t(vGu~1W&ap9>?2~7Q?tfq%*V2Vpj37AMJFnkV7 zeRZknuc*hh7YBy-ZO?&Ezt7B%jprxw2gy?o-)6=W&BL^hK>2|?N)iSRETJT`NGutp z&|lacC3EZzxf(_|G0}>;Dh_2%?u}7KZ~{>i{tLv0%?iFs*Wicp0|jMc2OR(?w~*q# zrmv+9isHtE;yR5To#zG08}_o|cq(`+E+J83n2`mXRg~%aP&yUYvfl%fFpMJ1AjP3G zVgH3Pz|nKZ)EgpD?wH`bY;rv?AtYOI=(%``NW(~G5ioVv!ql=~!DJkln09KNptvXW zKbVi{e!#RIp6eRd97_vKyV8v52HM>lQ=i0?fDj{{a$-s)>r&ibQ;)2smRDUdiIIef z%W6U_^k7Uhbojmw!-!g<)4Li*mJ)#CXb>=QlWM{^1O3-$=o);~)bgr|>F0C+sA;!m z0;W@Xlr|`8dPEq;fN|f69|=r*f@~N!)9&7wk`faI?W+Isjs}z4MF{T_wEv8Hy!GOB zLnfsMoE>CRka6X#lsSA`&Wcm^l}q+P$}liFQpm*;$v6Z&149#|xg;b|1KTI3a_MX) zmNL!lxDiC(_CB4M`L}Lx@x0Iw?*(D zYGRqz;tvB{P1;n)m`T?q)7PAs9`eA1z6D2AVj?bfHUQ8-sv!?dkh1}#9xtbdr-tT= zi6o5nv>IlTPNhuYIFjkEnwTC^F@2K`08E?7={=#ZoR4W15usF#|6TQ=!1S^A2vhS> z+TB~GkV!Kpw5Ay~8>r8kI&r(rKOMd2gZL8u83Rn^1+B<2Lc z)pQL$MsNABg2^b;0idSqNli~XLr7`#-WHfTjYqFZ2uyd)F{Zm}V5*itz~N<-5Hgjm z%jh{vAj@YLf(b?n%^Wo0n@~@lMi1>BSv^Yrne-f426)VbS^k4zUjY((d#g#?_Db}<)3FvBmS7Ob_s++$he{=@7RP3 zi|z$Q&MjC?R|fnr!KjE35(q`AnAiZq0J?<`=$5#-VZuNjC_r<^M2dl3Y@_GEgov<3 zt@ZEJ!gOUo#k56Y;u6S=ZqNn=({H8GTl}+SCj_R#!;I;NH880q5T&44XQfKPbixl4 z3@BlWL_h;Xiq%9)LTluOX%h&_C(Ok#Ezf`Sf?_tCZF_^hu~5@5d@$jF zNHqzo$G(YXxECg}cSy;{H^GVBjUIkLjWA&s=mhOb73m2>h?i?(`h|k2ak0d-m3-4l zons28nzm9g5ioTaZ5vpnxCZ>$*f!Gz-_Fd-#; z3g09-d8rA52>0?lL%>&eHObGVnh27OiA*BsDahfpPYAJMP{CvrC8i9i>7=gH1_jeb zVf4BhH9aIS{mCF$Kc)j9(z{i=ipm>l+Mr;{0Vc|u7XPmO z>jKksl#SkU+TB}Cc6kHUq%L-)>I)&hLp?I4mCF}`3HU&>F`;YX=7tI5JZ_f(ljuia z0>KUUFU)D(Xcol4jDWIB@Hpm9E@wk0vt{xnn`X` zM^2nx&jmPExu+qfA|@MRIYp(y`FlYw=TaF-0eEO)IeTSUojNmg(V*}ot?az0x6=ki z;djH~Sio9mykCA)Or85L($s0bgLc31;_%S*yK`oL{@}gSQ|2vuhjWQ+ERl|7O`w*A zLSoXg(y?SFWbWI0doG!bC1QOc^Y)vdv=~o?%z>M4%4HIXOmf8&bUts3VOLtHAga`@ zGxgoY@IC5LV1LUMI|9e#K=@zKEmDSujAqe#z*cwcxVnH+_qG_AdAMQclmz>g*ux<@ zl_-eeCulW-JarX|aS8UfRO}q)0QT#sZmHbGa1+-pw;loHXxKZ9!RMw0_Rsu^Ek=!1 zplr3$f`IhOS5eB+7|g>Leo^mMBYy3hUDwq)r3Zh43)o{EDuab5TsmH6Ov*z0YMSXuK&*} zrr(NNw^XCown)X)Lk9q+0Wx~0bY7KJ)O1D|y@2sb{x<^Cm!4r?m#=}zuC$PvAmFYh z9d$;tXQ)SkY1A7NIVWNCFa|+R0u#Rt`x!m&I}}JSmaCeiQIoz208xY^FrgHwA{N|P z6Vs@Q>0ya!E3K){=mFZGVEQ|urhxJGnKJ^@mmgqEU!>i=)nr#%a1|h}uBm?XN()?M z+n-a90@Lf>m}p+Bm?De`D1q}|C z4>i56V)_jo0BYJrm6jPjNE;MPKLt$d;JMcLb>k-lrbj2)=si!ndtH=+q!jzRMfzA8V4-@2kZd#kWa_we z4=_Pzj@Sf)+u#(9njfaGsF=7Q0y2#drl)jmKBkL+2yZ0nYV7%ks|BW0+ZfYC4NOW2 zC#^1h*B3&br5=TvE-VNW$BzI?CS+ty!yXBl)RQ|V@TKHV-7rxKPK)29CbXl#C?YY5 z^aDc3f2@h=f`X}$jVEA=32WLo57V|Q1*U*;TC7uJllq*V zGlX1o=YlW^BPZ|vM=eovQxifWMR|viKA4c91)mcp;1dq_0xbLPe*lGA401WsM@?() zR4^Hw8UUv46q`J)Z9kiOyo`Q#Z^s&2u9jL_+YhG-UrP!no zW0P2dW0QCiOfD5flj%$fyyPXZi4{*mT5rcDT!Lq7+TOh|{;W!wLhw6yb>k1<(d&8e zNBn3rJrZ)ezQwT##Y2wR6eWs6tsR@RcdPt&Oa8kl(|cLJe!fh1O8$)v|1&E1pFYn{ z@0+x{w@mH2305K1`@J&tty?(jChZS+V}dbp7M~%{yA)Hz4U>pW0Fo&6^OUet2uk#<;53bzk2P(7K*huX8OU^$oZcxnOn0Isg=eR6>d#~d`O-PY^nd=C z;J0?7ZUWXcW~s4BeVBM+2sORyi3tZw)=g~rsF|Ltnn+3*MtWeP)542eY=VfOUw9Rm zC^~^?^-^p4Pc<>Ut6*wm;|Z9!y!E)ggwCK?({VsV>*~f6vxkM6&YodRTx|AK6WmZN zF+oC}QmyGn|H%N}`f!fEAYxqenlM-_2@?^0XCOOt1J&m6D++9s57;LVX@B<>;WPFM)8ZhxMJHD!4IUmz;R1!SfjbFYm6Y|*^c6!HXcW+E~ z-6R1@QjK0JUe|4T-=ZGhe$`@*&tkzc0 ze?h3}s8puvLiv{tOr7lu!Gr@vs6^6+@1ccU4Wp=9Tn7RD8vYw3-XP3KK`q- zUBxsYG3}%<^AUXoZBPv3vxo?uUB-id`vZY#Zj>?ISOb$?0-?oD#edbgJj3gD11&9W z+K1YXW!l5q*2UU)wS*48?6U&ekQV9CuhBwH`X=qF7VTHsAGT|+XlpvPk87)1wT;?} z2K`#C)qua2Ea6|svM@W30r5j{m3CXU|9<`zHVdTvc$j{LO^895FFYjPl3rS#++iOG ze>9!D5q>I;jOfwu6C6Lg>5;ti%z>2p>+h~^{FLo)6z&4NhJJO9XM@)9+8lko9;4B|I5$Al4&wz-lDPKKt RPGEXH$e7sNiil +# Date: 05 Feb 2010 +# Location: Minsk, Belarus, 53N 27E +$SkyTraq,Venus6 +$Kernel,v1.4.23,000006FE,19324205,F,16.367667MHz +$ver,011023,rev,090210 +$GPVTG,287.04,T,,M,0.774,N,1.435,K,A*33 +$GPGGA,085032.00,5355.17581,N,02730.04649,E,1,04,17.30,267.5,M,25.0,M,,*65 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.95,17.30,7.74*0E +$GPGSV,3,1,12,03,67,251,,06,72,220,,08,07,331,24,14,06,151,*71 +$GPGSV,3,2,12,15,15,032,46,16,15,204,,18,55,074,42,19,47,295,20*76 +$GPGSV,3,3,12,21,33,087,48,22,67,157,,24,02,084,40,26,18,131,34*7D +$GPGLL,5355.17581,N,02730.04649,E,085032.00,A,A*60 +$GPRMC,085033.00,A,5355.17512,N,02730.04479,E,0.835,284.07,050210,,,A*6C +$GPVTG,284.07,T,,M,0.835,N,1.547,K,A*3D +$GPGGA,085033.00,5355.17512,N,02730.04479,E,1,04,17.31,266.9,M,25.0,M,,*63 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.96,17.31,7.74*0C +$GPGSV,3,1,12,03,67,251,,06,72,220,,08,07,331,26,14,06,151,*73 +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,19*7C +$GPGSV,3,3,12,21,33,087,49,22,67,157,,24,02,084,41,26,18,131,36*7F +$GPGLL,5355.17512,N,02730.04479,E,085033.00,A,A*6A +$GPRMC,085034.00,A,5355.17453,N,02730.04323,E,0.492,281.09,050210,,,A*6D +$GPVTG,281.09,T,,M,0.492,N,0.911,K,A*39 +$GPGGA,085034.00,5355.17453,N,02730.04323,E,1,04,17.31,266.2,M,25.0,M,,*63 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.96,17.31,7.74*0C +$GPGSV,3,1,12,03,67,251,,06,72,220,,08,07,331,26,14,06,151,*73 +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,18*7D +$GPGSV,3,3,12,21,33,087,48,22,67,157,,24,02,084,40,26,18,131,35*7C +$GPGLL,5355.17453,N,02730.04323,E,085034.00,A,A*61 +$GPRMC,085035.00,A,5355.17396,N,02730.04163,E,0.355,280.76,050210,,,A*61 +$GPVTG,280.76,T,,M,0.355,N,0.657,K,A*31 +$GPGGA,085035.00,5355.17396,N,02730.04163,E,1,04,17.32,265.6,M,25.0,M,,*6E +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.97,17.32,7.74*0E +$GPGSV,3,1,12,03,67,251,,06,72,220,,08,07,331,26,14,06,151,*73 +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,16*73 +$GPGSV,3,3,12,21,33,087,47,22,67,157,,24,02,084,40,26,18,131,35*73 +$GPGLL,5355.17396,N,02730.04163,E,085035.00,A,A*68 +$GPRMC,085036.00,A,5355.17332,N,02730.04006,E,0.831,278.54,050210,,,A*60 +$GPVTG,278.54,T,,M,0.831,N,1.540,K,A*3B +$GPGGA,085036.00,5355.17332,N,02730.04006,E,1,04,17.33,265.3,M,25.0,M,,*65 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.98,17.33,7.74*00 +$GPGSV,3,1,12,03,67,251,28,06,72,220,,08,07,331,27,14,06,151,*78 +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,14*71 +$GPGSV,3,3,12,21,33,087,47,22,67,157,,24,02,084,41,26,18,131,36*71 +$GPGLL,5355.17332,N,02730.04006,E,085036.00,A,A*67 +$GPRMC,085037.00,A,5355.17281,N,02730.03900,E,0.252,277.72,050210,,,A*64 +$GPVTG,277.72,T,,M,0.252,N,0.467,K,A*3A +$GPGGA,085037.00,5355.17281,N,02730.03900,E,1,04,17.34,265.1,M,25.0,M,,*60 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.98,17.34,7.74*07 +$GPGSV,3,1,12,03,67,251,,06,72,220,,08,07,331,27,14,06,151,*72 +$GPGSV,3,2,12,15,15,032,48,16,15,204,,18,55,074,43,19,47,295,13*79 +$GPGSV,3,3,12,21,33,087,47,22,67,157,,24,02,084,41,26,18,131,36*71 +$GPGLL,5355.17281,N,02730.03900,E,085037.00,A,A*67 +$GPRMC,085038.00,A,5355.17239,N,02730.03826,E,0.115,,050210,,,A*74 +$GPVTG,,T,,M,0.115,N,0.212,K,A*27 +$GPGGA,085038.00,5355.17239,N,02730.03826,E,1,04,17.34,265.1,M,25.0,M,,*69 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.99,17.34,7.74*06 +$GPGSV,3,1,12,03,67,251,,06,72,220,25,08,07,331,28,14,06,151,*7A +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,15*70 +$GPGSV,3,3,12,21,33,087,47,22,67,157,,24,02,084,41,26,18,131,35*72 +$GPGLL,5355.17239,N,02730.03826,E,085038.00,A,A*6E +$GPRMC,085039.00,A,5355.17198,N,02730.03759,E,0.137,,050210,,,A*7A +$GPVTG,,T,,M,0.137,N,0.254,K,A*25 +$GPGGA,085039.00,5355.17198,N,02730.03759,E,1,04,17.35,265.1,M,25.0,M,,*66 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.00,17.35,7.74*06 +$GPGSV,3,1,12,03,67,251,28,06,72,220,24,08,07,331,28,14,06,151,*71 +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,16*73 +$GPGSV,3,3,12,21,33,087,47,22,67,157,,24,02,084,40,26,18,131,35*73 +$GPGLL,5355.17198,N,02730.03759,E,085039.00,A,A*60 +$GPRMC,085040.00,A,5355.17137,N,02730.03625,E,0.168,,050210,,,A*71 +$GPVTG,,T,,M,0.168,N,0.311,K,A*2F +$GPGGA,085040.00,5355.17137,N,02730.03625,E,1,04,17.36,265.1,M,25.0,M,,*64 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.01,17.36,7.74*04 +$GPGSV,3,1,12,03,67,251,27,06,72,220,23,08,07,331,28,14,06,151,*79 +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,42,19,47,295,16*70 +$GPGSV,3,3,12,21,33,087,45,22,67,157,27,24,02,084,39,26,18,131,33*7C +$GPGLL,5355.17137,N,02730.03625,E,085040.00,A,A*61 +$GPRMC,085041.00,A,5355.17092,N,02730.03549,E,0.298,274.51,050210,,,A*60 +$GPVTG,274.51,T,,M,0.298,N,0.552,K,A*39 +$GPGGA,085041.00,5355.17092,N,02730.03549,E,1,04,17.37,265.0,M,25.0,M,,*62 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.01,17.37,7.74*05 +$GPGSV,3,1,12,03,67,250,27,06,72,220,23,08,07,331,28,14,06,151,*78 +$GPGSV,3,2,12,15,15,032,46,16,15,204,,18,55,074,43,19,47,295,17*73 +$GPGSV,3,3,12,21,33,087,46,22,67,157,27,24,02,084,39,26,18,131,33*7F +$GPGLL,5355.17092,N,02730.03549,E,085041.00,A,A*67 +$GPRMC,085042.00,A,5355.17075,N,02730.03565,E,0.253,275.14,050210,,,A*63 +$GPVTG,275.14,T,,M,0.253,N,0.469,K,A*37 +$GPGGA,085042.00,5355.17075,N,02730.03565,E,1,04,17.37,265.0,M,25.0,M,,*66 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.02,17.37,7.74*06 +$GPGSV,3,1,12,03,67,250,26,06,72,220,22,08,07,331,28,14,06,151,*78 +$GPGSV,3,2,12,15,15,032,46,16,15,204,,18,55,074,44,19,47,295,16*75 +$GPGSV,3,3,12,21,33,087,46,22,67,157,27,24,02,084,39,26,18,131,32*7E +$GPGLL,5355.17075,N,02730.03565,E,085042.00,A,A*63 +$GPRMC,085043.00,A,5355.17087,N,02730.03666,E,0.177,,050210,,,A*71 +$GPVTG,,T,,M,0.177,N,0.327,K,A*24 +$GPGGA,085043.00,5355.17087,N,02730.03666,E,1,04,17.38,265.2,M,25.0,M,,*67 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.03,17.38,7.74*08 +$GPGSV,3,1,12,03,67,250,,06,72,220,21,08,07,331,28,14,06,151,*7F +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,44,19,47,295,16*76 +$GPGSV,3,3,12,21,33,087,46,22,67,157,28,24,02,084,39,26,18,131,30*73 +$GPGLL,5355.17087,N,02730.03666,E,085043.00,A,A*6F +$GPRMC,085044.00,A,5355.17136,N,02730.03861,E,0.309,281.42,050210,,,A*6C +$GPVTG,281.42,T,,M,0.309,N,0.572,K,A*3A +$GPGGA,085044.00,5355.17136,N,02730.03861,E,1,04,17.39,265.4,M,25.0,M,,*65 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.03,17.39,7.74*09 +$GPGSV,3,1,12,03,67,250,,06,72,219,19,08,07,331,29,14,06,151,*7F +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,44,19,47,295,15*75 +$GPGSV,3,3,12,21,33,087,46,22,67,157,28,24,02,084,39,26,18,131,28*7A +$GPGLL,5355.17136,N,02730.03861,E,085044.00,A,A*6A +$GPRMC,085045.00,A,5355.17209,N,02730.04094,E,0.774,290.35,050210,,,A*69 +$GPVTG,290.35,T,,M,0.774,N,1.434,K,A*36 +$GPGGA,085045.00,5355.17209,N,02730.04094,E,1,04,17.39,265.7,M,25.0,M,,*6D +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.04,17.39,7.74*0E +$GPGSV,3,1,12,03,67,250,,06,72,219,17,08,07,331,28,14,06,151,*70 +$GPGSV,3,2,12,15,15,032,44,16,15,204,,18,55,074,44,19,47,295,14*75 +$GPGSV,3,3,12,21,33,087,46,22,67,157,28,24,02,084,39,26,18,131,27*75 +$GPGLL,5355.17209,N,02730.04094,E,085045.00,A,A*61 +$GPRMC,085046.00,A,5355.17280,N,02730.04292,E,0.376,298.76,050210,,,A*66 +$GPVTG,298.76,T,,M,0.376,N,0.697,K,A*35 +$GPGGA,085046.00,5355.17280,N,02730.04292,E,1,04,17.40,266.0,M,25.0,M,,*61 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.05,17.40,7.74*01 +$GPGSV,3,1,12,03,67,250,,06,72,219,14,08,07,331,28,14,06,151,*73 +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,45,19,47,295,15*74 +$GPGSV,3,3,12,21,33,087,46,22,67,157,30,24,02,084,40,26,18,131,27*72 +$GPGLL,5355.17280,N,02730.04292,E,085046.00,A,A*67 +$GPRMC,085047.00,A,5355.17358,N,02730.04516,E,0.431,306.60,050210,,,A*6D +$GPVTG,306.60,T,,M,0.431,N,0.799,K,A*3F +$GPGGA,085047.00,5355.17358,N,02730.04516,E,1,04,17.41,266.5,M,25.0,M,,*6B +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.05,17.41,7.74*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,11,08,07,331,28,14,06,151,*72 +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,45,19,47,295,15*74 +$GPGSV,3,3,12,21,33,087,46,22,67,157,30,24,02,084,40,26,18,131,29*7C +$GPGLL,5355.17358,N,02730.04516,E,085047.00,A,A*69 +$GPRMC,085048.00,A,5355.17430,N,02730.04697,E,0.219,311.70,050210,,,A*6A +$GPVTG,311.70,T,,M,0.219,N,0.406,K,A*31 +$GPGGA,085048.00,5355.17430,N,02730.04697,E,1,04,17.42,266.9,M,25.0,M,,*68 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.06,17.42,7.74*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,08,08,07,331,27,14,06,151,*75 +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,46,19,47,295,14*76 +$GPGSV,3,3,12,21,33,087,47,22,67,157,29,24,02,084,41,26,18,131,32*7E +$GPGLL,5355.17430,N,02730.04697,E,085048.00,A,A*65 +$GPRMC,085049.00,A,5355.17510,N,02730.04910,E,0.590,317.91,050210,,,A*67 +$GPVTG,317.91,T,,M,0.590,N,1.092,K,A*36 +$GPGGA,085049.00,5355.17510,N,02730.04910,E,1,04,17.42,267.4,M,25.0,M,,*66 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.07,17.42,7.74*01 +$GPGSV,3,1,12,03,67,250,26,06,72,219,,08,07,331,27,14,06,151,23*7C +$GPGSV,3,2,12,15,15,032,44,16,15,204,,18,55,074,46,19,47,295,14*77 +$GPGSV,3,3,12,21,33,087,47,22,67,157,29,24,02,084,41,26,18,131,33*7F +$GPGLL,5355.17510,N,02730.04910,E,085049.00,A,A*67 +$GPRMC,085050.00,A,5355.17582,N,02730.05082,E,0.273,321.57,050210,,,A*62 +$GPVTG,321.57,T,,M,0.273,N,0.505,K,A*39 +$GPGGA,085050.00,5355.17582,N,02730.05082,E,1,04,17.43,267.9,M,25.0,M,,*6A +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.07,17.43,7.74*00 +$GPGSV,3,1,12,03,67,250,25,06,72,219,,08,07,331,26,14,06,151,*7F +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,46,19,47,295,15*77 +$GPGSV,3,3,12,21,33,087,47,22,67,157,29,24,02,084,41,26,18,131,34*78 +$GPGLL,5355.17582,N,02730.05082,E,085050.00,A,A*67 +$GPRMC,085051.00,A,5355.17632,N,02730.05184,E,0.307,327.68,050210,,,A*64 +$GPVTG,327.68,T,,M,0.307,N,0.569,K,A*3B +$GPGGA,085051.00,5355.17632,N,02730.05184,E,1,04,17.44,268.3,M,25.0,M,,*66 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.08,17.44,7.74*08 +$GPGSV,3,1,12,03,67,250,,06,72,219,,08,07,331,26,14,06,151,*78 +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,46,19,47,295,16*74 +$GPGSV,3,3,12,21,33,087,47,22,67,157,28,24,02,084,41,26,18,131,34*79 +$GPGLL,5355.17632,N,02730.05184,E,085051.00,A,A*69 +$GPRMC,085052.00,A,5355.17477,N,02730.04765,E,0.521,322.69,050210,,,A*6A +$GPVTG,322.69,T,,M,0.521,N,0.966,K,A*3E +$GPGGA,085052.00,5355.17477,N,02730.04765,E,1,05,3.57,266.0,M,25.0,M,,*55 +$GPGSA,A,3,18,21,26,24,15,,,,,,,,4.12,3.57,2.06*0C +$GPGSV,3,1,12,03,67,250,,06,72,219,,08,07,331,26,14,06,151,26*7C +$GPGSV,3,2,12,15,15,032,44,16,15,204,,18,55,074,46,19,47,295,16*75 +$GPGSV,3,3,12,21,33,087,47,22,67,157,28,24,02,084,41,26,18,130,35*79 +$GPGLL,5355.17477,N,02730.04765,E,085052.00,A,A*61 +$GPRMC,085053.00,A,5355.16685,N,02730.02924,E,0.116,,050210,,,A*7A +$GPVTG,,T,,M,0.116,N,0.215,K,A*23 +$GPGGA,085053.00,5355.16685,N,02730.02924,E,1,04,4.99,244.3,M,25.0,M,,*50 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.26*03 +$GPGSV,3,1,12,03,67,250,,06,72,219,,08,07,331,25,14,06,151,25*7C +$GPGSV,3,2,12,15,14,032,43,16,15,204,,18,55,074,45,19,47,295,18*7E +$GPGSV,3,3,12,21,33,087,46,22,67,157,28,24,02,084,41,26,18,130,34*79 +$GPGLL,5355.16685,N,02730.02924,E,085053.00,A,A*63 +$GPRMC,085054.00,A,5355.16719,N,02730.02813,E,0.044,,050210,,,A*7A +$GPVTG,,T,,M,0.044,N,0.082,K,A*29 +$GPGGA,085054.00,5355.16719,N,02730.02813,E,1,04,4.99,243.9,M,25.0,M,,*5B +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.26*03 +$GPGSV,3,1,12,03,67,250,,06,72,219,,08,07,331,24,14,06,151,25*7D +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,074,46,19,47,295,17*74 +$GPGSV,3,3,12,21,33,087,47,22,67,157,27,24,02,084,41,26,18,130,33*70 +$GPGLL,5355.16719,N,02730.02813,E,085054.00,A,A*65 +$GPRMC,085055.00,A,5355.16726,N,02730.02707,E,0.025,,050210,,,A*7A +$GPVTG,,T,,M,0.025,N,0.047,K,A*27 +$GPGGA,085055.00,5355.16726,N,02730.02707,E,1,04,4.99,243.9,M,25.0,M,,*5C +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.26*03 +$GPGSV,3,1,12,03,67,250,,06,72,219,25,08,07,331,23,14,06,151,24*7C +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,074,46,19,47,295,17*73 +$GPGSV,3,3,12,21,33,087,48,22,67,157,26,24,02,084,41,26,18,130,33*7E +$GPGLL,5355.16726,N,02730.02707,E,085055.00,A,A*62 +$GPRMC,085056.00,A,5355.16743,N,02730.02569,E,0.104,,050210,,,A*72 +$GPVTG,,T,,M,0.104,N,0.192,K,A*2C +$GPGGA,085056.00,5355.16743,N,02730.02569,E,1,04,4.99,244.1,M,25.0,M,,*59 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,24,08,07,331,23,14,06,151,24*7D +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,47,295,16*75 +$GPGSV,3,3,12,21,33,087,48,22,67,157,25,24,02,084,41,26,18,130,33*7D +$GPGLL,5355.16743,N,02730.02569,E,085056.00,A,A*68 +$GPRMC,085057.00,A,5355.16755,N,02730.02418,E,0.054,,050210,,,A*77 +$GPVTG,,T,,M,0.054,N,0.100,K,A*23 +$GPGGA,085057.00,5355.16755,N,02730.02418,E,1,04,4.99,244.3,M,25.0,M,,*5A +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,24,08,07,331,25,14,06,151,25*7A +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,47,19,48,295,15*7F +$GPGSV,3,3,12,21,33,087,50,22,67,157,24,24,02,084,42,26,18,130,35*70 +$GPGLL,5355.16755,N,02730.02418,E,085057.00,A,A*69 +$GPRMC,085058.00,A,5355.16773,N,02730.02276,E,0.083,,050210,,,A*78 +$GPVTG,,T,,M,0.083,N,0.154,K,A*28 +$GPGGA,085058.00,5355.16773,N,02730.02276,E,1,04,4.99,244.3,M,25.0,M,,*5F +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,22,08,07,331,26,14,06,151,24*7E +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,13*7F +$GPGSV,3,3,12,21,33,087,49,22,67,157,,24,02,084,42,26,18,130,34*7F +$GPGLL,5355.16773,N,02730.02276,E,085058.00,A,A*6C +$GPRMC,085059.00,A,5355.16784,N,02730.02176,E,0.038,,050210,,,A*72 +$GPVTG,,T,,M,0.038,N,0.071,K,A*2E +$GPGGA,085059.00,5355.16784,N,02730.02176,E,1,04,4.99,244.2,M,25.0,M,,*54 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,19,08,07,331,26,14,06,151,24*76 +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,12*7E +$GPGSV,3,3,12,21,32,087,49,22,67,157,23,24,02,084,42,26,18,130,34*7F +$GPGLL,5355.16784,N,02730.02176,E,085059.00,A,A*66 +$GPRMC,085100.00,A,5355.16789,N,02730.02093,E,0.059,,050210,,,A*7F +$GPVTG,,T,,M,0.059,N,0.109,K,A*27 +$GPGGA,085100.00,5355.16789,N,02730.02093,E,1,04,4.99,244.3,M,25.0,M,,*5F +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,27,06,72,219,17,08,07,331,27,14,06,151,23*7B +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,14*7F +$GPGSV,3,3,12,21,32,087,49,22,67,156,23,24,02,084,41,26,18,130,34*7D +$GPGLL,5355.16789,N,02730.02093,E,085100.00,A,A*6C +$GPRMC,085101.00,A,5355.16793,N,02730.02037,E,0.033,,050210,,,A*77 +$GPVTG,,T,,M,0.033,N,0.062,K,A*27 +$GPGGA,085101.00,5355.16793,N,02730.02037,E,1,04,4.99,244.4,M,25.0,M,,*5C +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,25,06,72,219,15,08,07,331,27,14,06,151,22*7A +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,15*7E +$GPGSV,3,3,12,21,32,087,49,22,67,156,24,24,02,084,41,26,18,130,34*7A +$GPGLL,5355.16793,N,02730.02037,E,085101.00,A,A*68 +$GPRMC,085102.00,A,5355.16792,N,02730.01981,E,0.245,317.09,050210,,,A*63 +$GPVTG,317.09,T,,M,0.245,N,0.453,K,A*30 +$GPGGA,085102.00,5355.16792,N,02730.01981,E,1,04,4.99,244.5,M,25.0,M,,*58 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,25,06,72,219,17,08,07,331,28,14,06,151,20*75 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,15*7E +$GPGSV,3,3,12,21,32,087,49,22,67,156,25,24,01,085,41,26,18,130,33*7E +$GPGLL,5355.16792,N,02730.01981,E,085102.00,A,A*6D +$GPRMC,085103.00,A,5355.16789,N,02730.01903,E,0.466,312.02,050210,,,A*6B +$GPVTG,312.02,T,,M,0.466,N,0.863,K,A*36 +$GPGGA,085103.00,5355.16789,N,02730.01903,E,1,04,4.99,244.5,M,25.0,M,,*59 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,24,06,72,219,20,08,07,331,28,14,06,151,*72 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,15*7E +$GPGSV,3,3,12,21,32,087,49,22,67,156,25,24,01,085,41,26,18,130,33*7E +$GPGLL,5355.16789,N,02730.01903,E,085103.00,A,A*6C +$GPRMC,085104.00,A,5355.16784,N,02730.01827,E,0.519,307.35,050210,,,A*6F +$GPVTG,307.35,T,,M,0.519,N,0.962,K,A*3F +$GPGGA,085104.00,5355.16784,N,02730.01827,E,1,04,4.99,244.3,M,25.0,M,,*52 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,24,06,72,219,21,08,07,331,28,14,06,151,*73 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,14*7F +$GPGSV,3,3,12,21,32,087,49,22,67,156,25,24,01,085,41,26,18,130,33*7E +$GPGLL,5355.16784,N,02730.01827,E,085104.00,A,A*61 +$GPRMC,085105.00,A,5355.16779,N,02730.01767,E,0.466,302.81,050210,,,A*64 +$GPVTG,302.81,T,,M,0.466,N,0.863,K,A*3C +$GPGGA,085105.00,5355.16779,N,02730.01767,E,1,04,4.99,244.1,M,25.0,M,,*58 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,24,06,72,219,21,08,07,331,28,14,06,151,*73 +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,12*7E +$GPGSV,3,3,12,21,32,087,49,22,67,156,24,24,01,085,42,26,18,130,33*7C +$GPGLL,5355.16779,N,02730.01767,E,085105.00,A,A*69 +$GPRMC,085106.00,A,5355.16774,N,02730.01722,E,0.239,298.38,050210,,,A*67 +$GPVTG,298.38,T,,M,0.239,N,0.443,K,A*3E +$GPGGA,085106.00,5355.16774,N,02730.01722,E,1,04,4.99,243.8,M,25.0,M,,*59 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,24,06,72,219,20,08,07,331,27,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,10*7C +$GPGSV,3,3,12,21,32,087,48,22,67,156,,24,01,085,42,26,18,130,34*7C +$GPGLL,5355.16774,N,02730.01722,E,085106.00,A,A*66 +$GPRMC,085107.00,A,5355.16776,N,02730.01731,E,0.085,,050210,,,A*75 +$GPVTG,,T,,M,0.085,N,0.157,K,A*2D +$GPGGA,085107.00,5355.16776,N,02730.01731,E,1,04,4.99,243.6,M,25.0,M,,*56 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,24,06,72,219,17,08,07,331,27,14,06,151,*79 +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,10*7C +$GPGSV,3,3,12,21,32,087,48,22,67,156,,24,01,085,42,26,18,130,35*7D +$GPGLL,5355.16776,N,02730.01731,E,085107.00,A,A*67 +$GPRMC,085108.00,A,5355.16781,N,02730.01786,E,0.188,,050210,,,A*72 +$GPVTG,,T,,M,0.188,N,0.349,K,A*2C +$GPGGA,085108.00,5355.16781,N,02730.01786,E,1,04,4.99,243.4,M,25.0,M,,*5F +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,23,06,72,219,15,08,07,331,26,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,13*7F +$GPGSV,3,3,12,21,32,087,47,22,67,156,,24,01,085,42,26,18,130,36*71 +$GPGLL,5355.16781,N,02730.01786,E,085108.00,A,A*6C +$GPRMC,085109.00,A,5355.16801,N,02730.01883,E,0.221,306.41,050210,,,A*60 +$GPVTG,306.41,T,,M,0.221,N,0.409,K,A*31 +$GPGGA,085109.00,5355.16801,N,02730.01883,E,1,04,4.99,243.5,M,25.0,M,,*52 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,11,08,07,331,25,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,41,16,14,204,,18,55,073,45,19,48,295,16*7B +$GPGSV,3,3,12,21,32,087,45,22,67,156,,24,01,085,41,26,18,130,36*70 +$GPGLL,5355.16801,N,02730.01883,E,085109.00,A,A*60 +$GPRMC,085110.00,A,5355.16838,N,02730.02013,E,0.088,,050210,,,A*7F +$GPVTG,,T,,M,0.088,N,0.162,K,A*26 +$GPGGA,085110.00,5355.16838,N,02730.02013,E,1,04,4.99,243.9,M,25.0,M,,*5E +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,10,08,07,331,24,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,40,16,14,204,26,18,55,073,45,19,48,295,18*70 +$GPGSV,3,3,12,21,32,087,45,22,67,156,,24,01,085,40,26,18,130,37*70 +$GPGLL,5355.16838,N,02730.02013,E,085110.00,A,A*60 +$GPRMC,085111.00,A,5355.16896,N,02730.02189,E,0.078,,050210,,,A*77 +$GPVTG,,T,,M,0.078,N,0.145,K,A*2C +$GPGGA,085111.00,5355.16896,N,02730.02189,E,1,04,4.99,244.7,M,25.0,M,,*50 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,,08,07,331,23,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,40,16,14,204,,18,55,073,46,19,48,295,20*7C +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,41,26,18,130,39*7C +$GPGLL,5355.16896,N,02730.02189,E,085111.00,A,A*67 +$GPRMC,085112.00,A,5355.16942,N,02730.02332,E,0.033,,050210,,,A*71 +$GPVTG,,T,,M,0.033,N,0.061,K,A*24 +$GPGGA,085112.00,5355.16942,N,02730.02332,E,1,04,4.99,245.4,M,25.0,M,,*5B +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,27,06,72,219,,08,07,331,23,14,06,151,*78 +$GPGSV,3,2,12,15,14,032,41,16,14,204,,18,55,073,46,19,48,295,22*7F +$GPGSV,3,3,12,21,32,087,47,22,67,156,,24,01,085,41,26,18,130,39*7D +$GPGLL,5355.16942,N,02730.02332,E,085112.00,A,A*6E +$GPRMC,085113.00,A,5355.16988,N,02730.02475,E,0.143,,050210,,,A*74 +$GPVTG,,T,,M,0.143,N,0.264,K,A*25 +$GPGGA,085113.00,5355.16988,N,02730.02475,E,1,04,4.98,246.1,M,25.0,M,,*5F +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,27,06,72,219,,08,07,331,24,14,06,151,*7F +$GPGSV,3,2,12,15,14,032,41,16,14,204,,18,55,073,45,19,48,295,24*7A +$GPGSV,3,3,12,21,32,087,47,22,67,156,,24,01,085,41,26,18,130,39*7D +$GPGLL,5355.16988,N,02730.02475,E,085113.00,A,A*6D +$GPRMC,085114.00,A,5355.17026,N,02730.02579,E,0.058,,050210,,,A*79 +$GPVTG,,T,,M,0.058,N,0.107,K,A*28 +$GPGGA,085114.00,5355.17026,N,02730.02579,E,1,04,4.98,246.8,M,25.0,M,,*50 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,27,06,72,219,,08,07,331,25,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,42,16,14,204,,18,55,073,45,19,48,295,24*79 +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,41,26,18,130,39*7C +$GPGLL,5355.17026,N,02730.02579,E,085114.00,A,A*6B +$GPRMC,085115.00,A,5355.17060,N,02730.02660,E,0.017,,050210,,,A*7A +$GPVTG,,T,,M,0.017,N,0.032,K,A*24 +$GPGGA,085115.00,5355.17060,N,02730.02660,E,1,04,4.98,247.8,M,25.0,M,,*59 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,27,06,72,219,24,08,07,331,26,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,42,16,14,204,,18,55,073,45,19,48,295,24*79 +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,41,26,18,130,39*7C +$GPGLL,5355.17060,N,02730.02660,E,085115.00,A,A*63 +$GPRMC,085116.00,A,5355.17084,N,02730.02730,E,0.040,,050210,,,A*75 +$GPVTG,,T,,M,0.040,N,0.075,K,A*25 +$GPGGA,085116.00,5355.17084,N,02730.02730,E,1,04,4.98,248.5,M,25.0,M,,*56 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,25,06,72,219,23,08,07,331,25,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,42,16,14,204,,18,55,073,45,19,48,295,23*7E +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,41,26,18,130,38*7D +$GPGLL,5355.17084,N,02730.02730,E,085116.00,A,A*6E +$GPRMC,085117.00,A,5355.17100,N,02730.02761,E,0.057,,050210,,,A*7B +$GPVTG,,T,,M,0.057,N,0.106,K,A*26 +$GPGGA,085117.00,5355.17100,N,02730.02761,E,1,04,4.98,249.2,M,25.0,M,,*58 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,24,06,72,219,21,08,07,331,25,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,45,19,48,295,22*7E +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,41,26,18,130,38*7D +$GPGLL,5355.17100,N,02730.02761,E,085117.00,A,A*66 +$GPRMC,085118.00,A,5355.17107,N,02730.02791,E,0.087,,050210,,,A*71 +$GPVTG,,T,,M,0.087,N,0.160,K,A*2B +$GPGGA,085118.00,5355.17107,N,02730.02791,E,1,04,4.98,249.6,M,25.0,M,,*5B +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,23,06,72,219,18,08,07,331,25,14,06,151,*73 +$GPGSV,3,2,12,15,14,032,42,16,14,204,,18,55,073,43,19,48,295,20*7B +$GPGSV,3,3,12,21,32,087,44,22,67,156,,24,01,085,39,26,18,130,35*7D +$GPGLL,5355.17107,N,02730.02791,E,085118.00,A,A*61 +$GPRMC,085119.00,A,5355.17112,N,02730.02835,E,0.205,302.21,050210,,,A*61 +$GPVTG,302.21,T,,M,0.205,N,0.380,K,A*33 +$GPGGA,085119.00,5355.17112,N,02730.02835,E,1,04,4.98,249.8,M,25.0,M,,*51 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,22,06,72,219,14,08,07,331,25,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,44,19,48,295,20*7D +$GPGSV,3,3,12,21,32,087,45,22,67,156,,24,01,085,39,26,18,130,35*7C +$GPGLL,5355.17112,N,02730.02835,E,085119.00,A,A*65 +$GPRMC,085120.00,A,5355.17115,N,02730.02871,E,0.142,,050210,,,A*70 +$GPVTG,,T,,M,0.142,N,0.263,K,A*23 +$GPGGA,085120.00,5355.17115,N,02730.02871,E,1,04,4.98,250.0,M,25.0,M,,*5C +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,21,06,72,219,16,08,07,331,24,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,44,19,48,295,20*7A +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,39,26,18,130,34*7E +$GPGLL,5355.17115,N,02730.02871,E,085120.00,A,A*68 +$GPRMC,085121.00,A,5355.17114,N,02730.02897,E,0.131,,050210,,,A*7C +$GPVTG,,T,,M,0.131,N,0.243,K,A*25 +$GPGGA,085121.00,5355.17114,N,02730.02897,E,1,04,4.98,250.2,M,25.0,M,,*56 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,23,06,72,219,20,08,07,331,25,14,06,151,*78 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,22*78 +$GPGSV,3,3,12,21,32,087,47,22,67,156,,24,01,085,40,26,18,130,34*71 +$GPGLL,5355.17114,N,02730.02897,E,085121.00,A,A*60 +$GPRMC,085122.00,A,5355.17111,N,02730.02927,E,0.018,,050210,,,A*7A +$GPVTG,,T,,M,0.018,N,0.034,K,A*2D +$GPGGA,085122.00,5355.17111,N,02730.02927,E,1,04,4.98,250.6,M,25.0,M,,*5E +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.27*0C +$GPGSV,3,1,12,03,67,250,24,06,72,219,21,08,07,331,24,14,06,151,*7F +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,23*79 +$GPGSV,3,3,12,21,32,087,47,22,67,156,25,24,01,085,39,26,18,130,33*7F +$GPGLL,5355.17111,N,02730.02927,E,085122.00,A,A*6C +$GPRMC,085123.00,A,5355.17101,N,02730.02965,E,0.039,,050210,,,A*7F +$GPVTG,,T,,M,0.039,N,0.073,K,A*2D +$GPGGA,085123.00,5355.17101,N,02730.02965,E,1,04,4.98,250.9,M,25.0,M,,*57 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.27*0C +$GPGSV,3,1,12,03,67,250,25,06,72,219,21,08,07,331,24,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,24*7D +$GPGSV,3,3,12,21,32,087,47,22,67,156,26,24,01,085,40,26,18,130,32*73 +$GPGLL,5355.17101,N,02730.02965,E,085123.00,A,A*6A +$GPRMC,085124.00,A,5355.17091,N,02730.03002,E,0.131,,050210,,,A*70 +$GPVTG,,T,,M,0.131,N,0.242,K,A*24 +$GPGGA,085124.00,5355.17091,N,02730.03002,E,1,04,4.98,251.1,M,25.0,M,,*58 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.27*0C +$GPGSV,3,1,12,03,67,250,26,06,72,219,20,08,07,331,25,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,24*7D +$GPGSV,3,3,12,21,32,087,47,22,67,156,28,24,01,085,40,26,18,130,31*7E +$GPGLL,5355.17091,N,02730.03002,E,085124.00,A,A*6C +$GPRMC,085125.00,A,5355.17079,N,02730.03028,E,0.136,,050210,,,A*78 +$GPVTG,,T,,M,0.136,N,0.252,K,A*22 +$GPGGA,085125.00,5355.17079,N,02730.03028,E,1,04,4.98,251.3,M,25.0,M,,*55 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.27*0C +$GPGSV,3,1,12,03,67,250,26,06,72,219,19,08,07,331,26,14,06,151,*74 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,25*7C +$GPGSV,3,3,12,21,32,087,47,22,67,156,29,24,01,085,41,26,18,130,30*7F +$GPGLL,5355.17079,N,02730.03028,E,085125.00,A,A*63 +$GPRMC,085126.00,A,5355.17068,N,02730.03037,E,0.132,,050210,,,A*71 +$GPVTG,,T,,M,0.132,N,0.245,K,A*20 +$GPGGA,085126.00,5355.17068,N,02730.03037,E,1,04,4.98,251.3,M,25.0,M,,*58 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.28*03 +$GPGSV,3,1,12,03,67,250,27,06,72,219,18,08,07,331,26,14,06,151,*74 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,25*7C +$GPGSV,3,3,12,21,32,087,47,22,67,156,29,24,01,085,41,26,18,130,29*77 +$GPGLL,5355.17068,N,02730.03037,E,085126.00,A,A*6E +$GPRMC,085127.00,A,5355.17058,N,02730.03017,E,0.288,297.97,050210,,,A*6F +$GPVTG,297.97,T,,M,0.288,N,0.533,K,A*38 +$GPGGA,085127.00,5355.17058,N,02730.03017,E,1,04,4.98,251.1,M,25.0,M,,*5A +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.28*03 +$GPGSV,3,1,12,03,67,250,26,06,72,219,17,08,07,331,27,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,25*7D +$GPGSV,3,3,12,21,32,087,48,22,67,156,29,24,01,085,41,26,18,130,27*76 +$GPGLL,5355.17058,N,02730.03017,E,085127.00,A,A*6E +$GPRMC,085128.00,A,5355.17046,N,02730.02966,E,0.498,294.00,050210,,,A*6B +$GPVTG,294.00,T,,M,0.498,N,0.922,K,A*3E +$GPGGA,085128.00,5355.17046,N,02730.02966,E,1,05,1.79,250.8,M,25.0,M,,*57 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.22*01 +$GPGSV,3,1,12,03,67,250,25,06,72,219,15,08,07,330,27,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,25*7E +$GPGSV,3,3,12,21,32,087,48,22,67,156,29,24,01,085,41,26,18,130,26*77 +$GPGLL,5355.17046,N,02730.02966,E,085128.00,A,A*60 +$GPRMC,085129.00,A,5355.17034,N,02730.02913,E,0.588,290.28,050210,,,A*63 +$GPVTG,290.28,T,,M,0.588,N,1.090,K,A*31 +$GPGGA,085129.00,5355.17034,N,02730.02913,E,1,05,1.79,250.6,M,25.0,M,,*5F +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.22*01 +$GPGSV,3,1,12,03,67,250,24,06,72,219,12,08,07,330,28,14,06,151,*72 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,25*7D +$GPGSV,3,3,12,21,32,087,49,22,67,156,28,24,01,085,41,26,18,130,28*79 +$GPGLL,5355.17034,N,02730.02913,E,085129.00,A,A*66 +$GPRMC,085130.00,A,5355.17020,N,02730.02862,E,0.658,286.77,050210,,,A*6A +$GPVTG,286.77,T,,M,0.658,N,1.219,K,A*31 +$GPGGA,085130.00,5355.17020,N,02730.02862,E,1,05,1.79,250.3,M,25.0,M,,*50 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.22*01 +$GPGSV,3,1,12,03,67,250,24,06,72,219,13,08,07,330,28,14,06,151,*73 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,25*7F +$GPGSV,3,3,12,21,32,087,49,22,67,156,28,24,01,085,40,26,18,130,29*79 +$GPGLL,5355.17020,N,02730.02862,E,085130.00,A,A*6C +$GPRMC,085131.00,A,5355.17009,N,02730.02821,E,0.658,283.54,050210,,,A*63 +$GPVTG,283.54,T,,M,0.658,N,1.219,K,A*35 +$GPGGA,085131.00,5355.17009,N,02730.02821,E,1,05,1.79,250.1,M,25.0,M,,*5F +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,17,08,07,330,27,14,06,151,*7A +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,25*7C +$GPGSV,3,3,12,21,32,087,49,22,67,156,27,24,01,085,41,26,18,130,30*7F +$GPGLL,5355.17009,N,02730.02821,E,085131.00,A,A*61 +$GPRMC,085132.00,A,5355.16991,N,02730.02767,E,0.997,280.53,050210,,,A*6C +$GPVTG,280.53,T,,M,0.997,N,1.848,K,A*33 +$GPGGA,085132.00,5355.16991,N,02730.02767,E,1,05,1.79,249.8,M,25.0,M,,*59 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,27,06,72,219,20,08,07,330,26,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,24*7D +$GPGSV,3,3,12,21,32,087,49,22,67,156,27,24,01,085,41,26,18,130,35*7A +$GPGLL,5355.16991,N,02730.02767,E,085132.00,A,A*66 +$GPRMC,085133.00,A,5355.16972,N,02730.02710,E,1.137,277.73,050210,,,A*69 +$GPVTG,277.73,T,,M,1.137,N,2.107,K,A*3B +$GPGGA,085133.00,5355.16972,N,02730.02710,E,1,05,1.79,249.6,M,25.0,M,,*5B +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,27,06,72,219,19,08,07,330,25,14,06,151,*77 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,23*78 +$GPGSV,3,3,12,21,32,087,48,22,67,156,26,24,01,085,39,26,18,130,34*74 +$GPGLL,5355.16972,N,02730.02710,E,085133.00,A,A*6A +$GPRMC,085134.00,A,5355.16953,N,02730.02655,E,1.016,275.06,050210,,,A*6F +$GPVTG,275.06,T,,M,1.016,N,1.882,K,A*3E +$GPGGA,085134.00,5355.16953,N,02730.02655,E,1,05,1.79,249.3,M,25.0,M,,*5A +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,16,08,07,330,23,14,06,151,*7F +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,21*78 +$GPGSV,3,3,12,21,32,087,49,22,67,156,26,24,01,085,41,26,18,130,35*7B +$GPGLL,5355.16953,N,02730.02655,E,085134.00,A,A*6E +$GPRMC,085135.00,A,5355.16935,N,02730.02610,E,0.860,272.53,050210,,,A*60 +$GPVTG,272.53,T,,M,0.860,N,1.594,K,A*3B +$GPGGA,085135.00,5355.16935,N,02730.02610,E,1,05,1.79,249.1,M,25.0,M,,*58 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,23,06,72,219,15,08,07,330,22,14,06,151,*78 +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,45,19,48,295,19*76 +$GPGSV,3,3,12,21,32,087,48,22,67,156,26,24,01,085,41,26,18,130,35*7A +$GPGLL,5355.16935,N,02730.02610,E,085135.00,A,A*6E +$GPRMC,085136.00,A,5355.16958,N,02730.02675,E,0.386,270.33,050210,,,A*6C +$GPVTG,270.33,T,,M,0.386,N,0.715,K,A*36 +$GPGGA,085136.00,5355.16958,N,02730.02675,E,1,05,1.79,249.7,M,25.0,M,,*55 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,17,08,07,330,21,14,06,151,*78 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,18*72 +$GPGSV,3,3,12,21,32,087,50,22,67,156,27,24,01,085,42,26,18,130,36*72 +$GPGLL,5355.16958,N,02730.02675,E,085136.00,A,A*65 +$GPRMC,085137.00,A,5355.16951,N,02730.02661,E,0.151,,050210,,,A*72 +$GPVTG,,T,,M,0.151,N,0.280,K,A*2C +$GPGGA,085137.00,5355.16951,N,02730.02661,E,1,05,1.79,249.6,M,25.0,M,,*59 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,20,08,07,330,20,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,19*73 +$GPGSV,3,3,12,21,32,087,50,22,67,156,27,24,01,085,42,26,18,130,36*72 +$GPGLL,5355.16951,N,02730.02661,E,085137.00,A,A*68 +$GPRMC,085138.00,A,5355.16944,N,02730.02634,E,0.523,279.74,050210,,,A*69 +$GPVTG,279.74,T,,M,0.523,N,0.970,K,A*38 +$GPGGA,085138.00,5355.16944,N,02730.02634,E,1,05,1.79,249.5,M,25.0,M,,*51 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,20,08,07,330,18,14,06,151,*72 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,19*73 +$GPGSV,3,3,12,21,32,087,49,22,67,156,27,24,01,085,42,26,18,130,37*7B +$GPGLL,5355.16944,N,02730.02634,E,085138.00,A,A*63 +$GPRMC,085139.00,A,5355.16947,N,02730.02631,E,0.955,288.42,050210,,,A*68 +$GPVTG,288.42,T,,M,0.955,N,1.769,K,A*39 +$GPGGA,085139.00,5355.16947,N,02730.02631,E,1,05,1.79,249.7,M,25.0,M,,*54 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,17,08,07,330,18,14,06,151,*76 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,19*73 +$GPGSV,3,3,12,21,32,087,50,22,67,156,26,24,01,085,42,26,18,130,37*72 +$GPGLL,5355.16947,N,02730.02631,E,085139.00,A,A*64 +$GPRMC,085140.00,A,5355.16953,N,02730.02634,E,1.209,296.51,050210,,,A*68 +$GPVTG,296.51,T,,M,1.209,N,2.240,K,A*3A +$GPGGA,085140.00,5355.16953,N,02730.02634,E,1,05,1.79,249.8,M,25.0,M,,*55 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,27,06,72,219,12,08,07,330,18,14,06,151,*72 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,19*73 +$GPGSV,3,3,12,21,32,087,49,22,67,156,25,24,01,085,42,26,18,130,37*79 +$GPGLL,5355.16953,N,02730.02634,E,085140.00,A,A*6A +$GPRMC,085141.00,A,5355.16952,N,02730.02616,E,1.203,304.08,050210,,,A*64 +$GPVTG,304.08,T,,M,1.203,N,2.230,K,A*31 +$GPGGA,085141.00,5355.16952,N,02730.02616,E,1,05,1.79,249.9,M,25.0,M,,*54 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,28,06,72,219,12,08,07,330,18,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,19*70 +$GPGSV,3,3,12,21,32,087,49,22,67,156,22,24,01,085,43,26,18,130,38*70 +$GPGLL,5355.16952,N,02730.02616,E,085141.00,A,A*6A +$GPRMC,085142.00,A,5355.16901,N,02730.02472,E,0.382,311.88,050210,,,A*64 +$GPVTG,311.88,T,,M,0.382,N,0.707,K,A*37 +$GPGGA,085142.00,5355.16901,N,02730.02472,E,1,05,1.79,249.0,M,25.0,M,,*58 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,17,08,07,330,19,14,06,151,*77 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,19*70 +$GPGSV,3,3,12,21,32,087,49,22,67,156,,24,01,085,42,26,18,130,38*71 +$GPGLL,5355.16901,N,02730.02472,E,085142.00,A,A*6F +$GPRMC,085143.00,A,5355.16896,N,02730.02443,E,0.211,319.01,050210,,,A*6A +$GPVTG,319.01,T,,M,0.211,N,0.392,K,A*3D +$GPGGA,085143.00,5355.16896,N,02730.02443,E,1,05,1.79,249.1,M,25.0,M,,*55 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,25,06,72,219,21,08,07,330,20,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,19*70 +$GPGSV,3,3,12,21,32,087,49,22,67,156,,24,01,085,42,26,18,130,37*7E +$GPGLL,5355.16896,N,02730.02443,E,085143.00,A,A*63 +$GPRMC,085144.00,A,5355.16895,N,02730.02431,E,0.186,,050210,,,A*72 +$GPVTG,,T,,M,0.186,N,0.345,K,A*2E +$GPGGA,085144.00,5355.16895,N,02730.02431,E,1,05,1.79,249.3,M,25.0,M,,*56 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,23,08,07,330,21,14,06,151,*7F +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,21*7B +$GPGSV,3,3,12,21,32,087,48,22,67,156,27,24,01,085,42,26,18,130,37*7A +$GPGLL,5355.16895,N,02730.02431,E,085144.00,A,A*62 +$GPRMC,085145.00,A,5355.16894,N,02730.02410,E,0.409,314.01,050210,,,A*6A +$GPVTG,314.01,T,,M,0.409,N,0.758,K,A*3D +$GPGGA,085145.00,5355.16894,N,02730.02410,E,1,05,1.79,249.3,M,25.0,M,,*55 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,23,08,07,330,21,14,07,151,*7E +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,44,19,48,295,21*7C +$GPGSV,3,3,12,21,32,087,47,22,67,156,27,24,01,085,40,26,18,130,36*76 +$GPGLL,5355.16894,N,02730.02410,E,085145.00,A,A*61 +$GPRMC,085146.00,A,5355.16889,N,02730.02363,E,0.246,309.09,050210,,,A*6F +$GPVTG,309.09,T,,M,0.246,N,0.455,K,A*3A +$GPGGA,085146.00,5355.16889,N,02730.02363,E,1,05,1.79,249.3,M,25.0,M,,*59 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,23,08,07,330,22,14,07,151,*7D +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,44,19,48,295,23*79 +$GPGSV,3,3,12,21,32,087,46,22,67,156,26,24,01,085,40,26,18,130,35*75 +$GPGLL,5355.16889,N,02730.02363,E,085146.00,A,A*6D +$GPRMC,085147.00,A,5355.16883,N,02730.02334,E,0.023,,050210,,,A*7A +$GPVTG,,T,,M,0.023,N,0.043,K,A*25 +$GPGGA,085147.00,5355.16883,N,02730.02334,E,1,05,1.79,249.3,M,25.0,M,,*50 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,25,08,07,330,24,14,07,151,*7D +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,46,19,48,295,25*7F +$GPGSV,3,3,12,21,32,087,48,22,67,156,26,24,01,085,41,26,18,130,35*7A +$GPGLL,5355.16883,N,02730.02334,E,085147.00,A,A*64 +$GPRMC,085148.00,A,5355.16875,N,02730.02320,E,0.058,,050210,,,A*75 +$GPVTG,,T,,M,0.058,N,0.107,K,A*28 +$GPGGA,085148.00,5355.16875,N,02730.02320,E,1,05,1.79,249.4,M,25.0,M,,*54 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,25,08,07,330,25,14,07,151,*7C +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,46,19,48,295,26*7C +$GPGSV,3,3,12,21,32,087,47,22,67,156,26,24,01,085,41,26,18,130,35*75 +$GPGLL,5355.16875,N,02730.02320,E,085148.00,A,A*67 +$GPRMC,085149.00,A,5355.16866,N,02730.02314,E,0.346,304.62,050210,,,A*60 +$GPVTG,304.62,T,,M,0.346,N,0.641,K,A*3C +$GPGGA,085149.00,5355.16866,N,02730.02314,E,1,05,1.79,249.4,M,25.0,M,,*50 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,25,08,07,330,25,14,07,151,*7C +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,26*7C +$GPGSV,3,3,12,21,32,087,47,22,67,156,26,24,01,085,41,26,18,130,34*74 +$GPGLL,5355.16866,N,02730.02314,E,085149.00,A,A*63 +$GPRMC,085150.00,A,5355.16856,N,02730.02311,E,0.506,300.38,050210,,,A*67 +$GPVTG,300.38,T,,M,0.506,N,0.937,K,A*3B +$GPGGA,085150.00,5355.16856,N,02730.02311,E,1,05,1.79,249.5,M,25.0,M,,*5F +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,28,06,72,219,25,08,07,330,25,14,07,151,*76 +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,45,19,48,295,27*7E +$GPGSV,3,3,12,21,32,087,47,22,67,156,27,24,01,085,41,26,18,130,33*72 +$GPGLL,5355.16856,N,02730.02311,E,085150.00,A,A*6D +$GPRMC,085151.00,A,5355.16845,N,02730.02318,E,0.564,296.45,050210,,,A*6D +$GPVTG,296.45,T,,M,0.564,N,1.045,K,A*36 +$GPGGA,085151.00,5355.16845,N,02730.02318,E,1,05,1.79,249.6,M,25.0,M,,*56 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,29,06,72,219,24,08,07,330,25,14,07,151,*76 +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,45,19,48,295,26*7F +$GPGSV,3,3,12,21,32,087,46,22,67,156,28,24,01,085,40,26,18,130,32*7C +$GPGLL,5355.16845,N,02730.02318,E,085151.00,A,A*67 +$GPRMC,085152.00,A,5355.16838,N,02730.02346,E,0.143,,050210,,,A*7C +$GPVTG,,T,,M,0.143,N,0.265,K,A*24 +$GPGGA,085152.00,5355.16838,N,02730.02346,E,1,05,1.79,249.8,M,25.0,M,,*5A +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,249,29,06,72,219,22,08,07,330,26,14,07,151,*7B +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,45,19,48,295,26*7F +$GPGSV,3,3,12,21,32,087,46,22,67,156,29,24,01,085,40,26,18,130,31*7E +$GPGLL,5355.16838,N,02730.02346,E,085152.00,A,A*65 +$GPRMC,085153.00,A,5355.16831,N,02730.02377,E,0.025,,050210,,,A*77 +$GPVTG,,T,,M,0.025,N,0.047,K,A*27 +$GPGGA,085153.00,5355.16831,N,02730.02377,E,1,05,1.79,250.0,M,25.0,M,,*50 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,249,29,06,72,219,23,08,07,330,26,14,07,151,*7A +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,45,19,48,295,26*7F +$GPGSV,3,3,12,21,32,087,46,22,67,156,31,24,01,085,40,26,18,130,32*74 +$GPGLL,5355.16831,N,02730.02377,E,085153.00,A,A*6F +$GPRMC,085154.00,A,5355.16823,N,02730.02421,E,0.081,,050210,,,A*79 +$GPVTG,,T,,M,0.081,N,0.150,K,A*2E +$GPGGA,085154.00,5355.16823,N,02730.02421,E,1,05,1.79,250.3,M,25.0,M,,*53 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,249,29,06,72,219,23,08,07,330,26,14,07,151,*7A +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,45,19,48,295,25*7C +$GPGSV,3,3,12,21,32,087,46,22,67,156,32,24,01,085,40,26,18,130,32*77 +$GPGLL,5355.16823,N,02730.02421,E,085154.00,A,A*6F +$GPRMC,085155.00,A,5355.16818,N,02730.02469,E,0.187,,050210,,,A*7B +$GPVTG,,T,,M,0.187,N,0.347,K,A*2D +$GPGGA,085155.00,5355.16818,N,02730.02469,E,1,05,1.79,250.5,M,25.0,M,,*50 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,249,29,06,71,217,22,08,07,330,26,14,07,151,*76 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,25*7F +$GPGSV,3,3,12,21,32,087,46,22,67,156,31,24,01,085,40,26,18,130,31*77 +$GPGLL,5355.16818,N,02730.02469,E,085155.00,A,A*6A +$GPRMC,085156.00,A,5355.16811,N,02730.02486,E,0.011,,050210,,,A*7E +$GPVTG,,T,,M,0.011,N,0.020,K,A*21 +$GPGGA,085156.00,5355.16811,N,02730.02486,E,1,05,1.79,250.7,M,25.0,M,,*59 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.24*07 +$GPGSV,3,1,12,03,67,249,28,06,71,217,20,08,07,330,26,14,07,151,*75 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,24*7E +$GPGSV,3,3,12,21,32,087,46,22,67,156,30,24,01,085,41,26,18,130,32*74 +$GPGLL,5355.16811,N,02730.02486,E,085156.00,A,A*61 +$GPRMC,085157.00,A,5355.16805,N,02730.02498,E,0.183,,050210,,,A*7F +$GPVTG,,T,,M,0.183,N,0.339,K,A*20 +$GPGGA,085157.00,5355.16805,N,02730.02498,E,1,05,1.79,250.7,M,25.0,M,,*52 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.24*07 +$GPGSV,3,1,12,03,67,249,28,06,71,217,18,08,07,330,26,14,07,151,*7E +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,23*78 +$GPGSV,3,3,12,21,32,087,46,22,67,156,29,24,01,085,41,26,18,130,33*7D +$GPGLL,5355.16805,N,02730.02498,E,085157.00,A,A*6A +$GPRMC,085158.00,A,5355.16801,N,02730.02510,E,0.258,292.57,050210,,,A*65 +$GPVTG,292.57,T,,M,0.258,N,0.478,K,A*32 +$GPGGA,085158.00,5355.16801,N,02730.02510,E,1,05,1.79,250.8,M,25.0,M,,*57 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.24*07 +$GPGSV,3,1,12,03,67,249,27,06,71,217,16,08,07,330,25,14,07,151,*7C +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,22*79 +$GPGSV,3,3,12,21,32,087,46,22,67,156,28,24,01,085,41,26,18,130,33*7C +$GPGLL,5355.16801,N,02730.02510,E,085158.00,A,A*60 +$GPRMC,085159.00,A,5355.16799,N,02730.02518,E,0.364,289.04,050210,,,A*60 +$GPVTG,289.04,T,,M,0.364,N,0.675,K,A*3F +$GPGGA,085159.00,5355.16799,N,02730.02518,E,1,05,1.79,250.9,M,25.0,M,,*51 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.24*07 +$GPGSV,3,1,12,03,67,249,27,06,71,217,13,08,07,330,24,14,07,151,*78 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,20*7B +$GPGSV,3,3,12,21,32,087,46,22,67,156,27,24,01,085,42,26,18,130,34*77 +$GPGLL,5355.16799,N,02730.02518,E,085159.00,A,A*67 +$GPRMC,085200.00,A,5355.16797,N,02730.02521,E,0.225,285.42,050210,,,A*61 +$GPVTG,285.42,T,,M,0.225,N,0.417,K,A*33 +$GPGGA,085200.00,5355.16797,N,02730.02521,E,1,05,1.79,251.0,M,25.0,M,,*52 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.24*07 +$GPGSV,3,1,12,03,67,249,28,06,71,217,14,08,07,330,23,14,07,151,*77 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,19*71 +$GPGSV,3,3,12,21,32,087,47,22,67,156,27,24,01,085,42,26,18,130,35*77 +$GPGLL,5355.16797,N,02730.02521,E,085200.00,A,A*6C +$GPRMC,085201.00,A,5355.16798,N,02730.02524,E,0.256,282.12,050210,,,A*6C +$GPVTG,282.12,T,,M,0.256,N,0.474,K,A*30 +$GPGGA,085201.00,5355.16798,N,02730.02524,E,1,05,1.79,251.1,M,25.0,M,,*58 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.87,1.79,2.24*06 +$GPGSV,3,1,12,03,67,249,29,06,71,217,16,08,07,330,21,14,07,151,*76 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,16*7E +$GPGSV,3,3,12,21,32,087,47,22,67,156,27,24,01,085,42,26,18,130,35*77 +$GPGLL,5355.16798,N,02730.02524,E,085201.00,A,A*67 +$GPRMC,085202.00,A,5355.16797,N,02730.02521,E,0.079,,050210,,,A*7F diff --git a/test/daemon/venus634lp.log.chk b/test/daemon/venus634lp.log.chk new file mode 100644 index 0000000..1a45e3a --- /dev/null +++ b/test/daemon/venus634lp.log.chk @@ -0,0 +1,902 @@ +$GPVTG,287.04,T,,M,0.774,N,1.435,K,A*33 +$GPGGA,085032.00,5355.17581,N,02730.04649,E,1,04,17.30,267.5,M,25.0,M,,*65 +{"class":"TPV","tag":"GGA","lat":53.919596833,"lon":27.500774833,"alt":267.500,"mode":3} +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.95,17.30,7.74*0E +{"class":"TPV","tag":"GSA","lat":53.919596833,"lon":27.500774833,"alt":267.500,"epv":178.020,"mode":3} +$GPGSV,3,1,12,03,67,251,,06,72,220,,08,07,331,24,14,06,151,*71 +$GPGSV,3,2,12,15,15,032,46,16,15,204,,18,55,074,42,19,47,295,20*76 +$GPGSV,3,3,12,21,33,087,48,22,67,157,,24,02,084,40,26,18,131,34*7D +{"class":"SKY","tag":"GSV","xdop":11.35,"ydop":6.34,"vdop":5.42,"tdop":1.00,"hdop":13.00,"gdop":14.12,"pdop":14.08,"satellites":[{"PRN":3,"el":67,"az":251,"ss":0,"used":false},{"PRN":6,"el":72,"az":220,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":24,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":46,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":42,"used":true},{"PRN":19,"el":47,"az":295,"ss":20,"used":false},{"PRN":21,"el":33,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":157,"ss":0,"used":false},{"PRN":24,"el":2,"az":84,"ss":40,"used":true},{"PRN":26,"el":18,"az":131,"ss":34,"used":false}]} +$GPGLL,5355.17581,N,02730.04649,E,085032.00,A,A*60 +{"class":"TPV","tag":"GLL","lat":53.919596833,"lon":27.500774833,"alt":267.500,"epx":170.223,"epy":95.066,"epv":178.020,"mode":3} +$GPRMC,085033.00,A,5355.17512,N,02730.04479,E,0.835,284.07,050210,,,A*6C +$GPVTG,284.07,T,,M,0.835,N,1.547,K,A*3D +$GPGGA,085033.00,5355.17512,N,02730.04479,E,1,04,17.31,266.9,M,25.0,M,,*63 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.96,17.31,7.74*0C +$GPGSV,3,1,12,03,67,251,,06,72,220,,08,07,331,26,14,06,151,*73 +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,19*7C +$GPGSV,3,3,12,21,33,087,49,22,67,157,,24,02,084,41,26,18,131,36*7F +{"class":"SKY","tag":"GSV","xdop":11.35,"ydop":6.34,"vdop":5.42,"tdop":1.00,"hdop":13.00,"gdop":14.12,"pdop":14.08,"satellites":[{"PRN":3,"el":67,"az":251,"ss":0,"used":false},{"PRN":6,"el":72,"az":220,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":47,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":43,"used":true},{"PRN":19,"el":47,"az":295,"ss":19,"used":false},{"PRN":21,"el":33,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":157,"ss":0,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":true},{"PRN":26,"el":18,"az":131,"ss":36,"used":false}]} +$GPGLL,5355.17512,N,02730.04479,E,085033.00,A,A*6A +{"class":"TPV","tag":"GLL","time":1265359833.000,"ept":0.005,"lat":53.919585333,"lon":27.500746500,"alt":266.900,"epx":170.223,"epy":95.066,"epv":124.583,"track":284.0700,"speed":0.430,"climb":0.000,"mode":3} +$GPRMC,085034.00,A,5355.17453,N,02730.04323,E,0.492,281.09,050210,,,A*6D +$GPVTG,281.09,T,,M,0.492,N,0.911,K,A*39 +$GPGGA,085034.00,5355.17453,N,02730.04323,E,1,04,17.31,266.2,M,25.0,M,,*63 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.96,17.31,7.74*0C +$GPGSV,3,1,12,03,67,251,,06,72,220,,08,07,331,26,14,06,151,*73 +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,18*7D +$GPGSV,3,3,12,21,33,087,48,22,67,157,,24,02,084,40,26,18,131,35*7C +{"class":"SKY","tag":"GSV","xdop":11.35,"ydop":6.34,"vdop":5.42,"tdop":1.00,"hdop":13.00,"gdop":14.12,"pdop":14.08,"satellites":[{"PRN":3,"el":67,"az":251,"ss":0,"used":false},{"PRN":6,"el":72,"az":220,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":47,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":43,"used":true},{"PRN":19,"el":47,"az":295,"ss":18,"used":false},{"PRN":21,"el":33,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":157,"ss":0,"used":false},{"PRN":24,"el":2,"az":84,"ss":40,"used":true},{"PRN":26,"el":18,"az":131,"ss":35,"used":false}]} +$GPGLL,5355.17453,N,02730.04323,E,085034.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1265359834.000,"ept":0.005,"lat":53.919575500,"lon":27.500720500,"alt":266.200,"epx":170.223,"epy":95.066,"epv":124.583,"track":281.0900,"speed":0.253,"climb":0.000,"eps":340.45,"mode":3} +$GPRMC,085035.00,A,5355.17396,N,02730.04163,E,0.355,280.76,050210,,,A*61 +$GPVTG,280.76,T,,M,0.355,N,0.657,K,A*31 +$GPGGA,085035.00,5355.17396,N,02730.04163,E,1,04,17.32,265.6,M,25.0,M,,*6E +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.97,17.32,7.74*0E +$GPGSV,3,1,12,03,67,251,,06,72,220,,08,07,331,26,14,06,151,*73 +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,16*73 +$GPGSV,3,3,12,21,33,087,47,22,67,157,,24,02,084,40,26,18,131,35*73 +{"class":"SKY","tag":"GSV","xdop":11.35,"ydop":6.34,"vdop":5.42,"tdop":1.00,"hdop":13.00,"gdop":14.12,"pdop":14.08,"satellites":[{"PRN":3,"el":67,"az":251,"ss":0,"used":false},{"PRN":6,"el":72,"az":220,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":47,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":43,"used":true},{"PRN":19,"el":47,"az":295,"ss":16,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":0,"used":false},{"PRN":24,"el":2,"az":84,"ss":40,"used":true},{"PRN":26,"el":18,"az":131,"ss":35,"used":false}]} +$GPGLL,5355.17396,N,02730.04163,E,085035.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1265359835.000,"ept":0.005,"lat":53.919566000,"lon":27.500693833,"alt":265.600,"epx":170.223,"epy":95.066,"epv":124.583,"track":280.7600,"speed":0.183,"climb":0.000,"eps":340.45,"mode":3} +$GPRMC,085036.00,A,5355.17332,N,02730.04006,E,0.831,278.54,050210,,,A*60 +$GPVTG,278.54,T,,M,0.831,N,1.540,K,A*3B +$GPGGA,085036.00,5355.17332,N,02730.04006,E,1,04,17.33,265.3,M,25.0,M,,*65 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.98,17.33,7.74*00 +$GPGSV,3,1,12,03,67,251,28,06,72,220,,08,07,331,27,14,06,151,*78 +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,14*71 +$GPGSV,3,3,12,21,33,087,47,22,67,157,,24,02,084,41,26,18,131,36*71 +{"class":"SKY","tag":"GSV","xdop":11.35,"ydop":6.34,"vdop":5.42,"tdop":1.00,"hdop":13.00,"gdop":14.12,"pdop":14.08,"satellites":[{"PRN":3,"el":67,"az":251,"ss":28,"used":false},{"PRN":6,"el":72,"az":220,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":27,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":47,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":43,"used":true},{"PRN":19,"el":47,"az":295,"ss":14,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":0,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":true},{"PRN":26,"el":18,"az":131,"ss":36,"used":false}]} +$GPGLL,5355.17332,N,02730.04006,E,085036.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359836.000,"ept":0.005,"lat":53.919555333,"lon":27.500667667,"alt":265.300,"epx":170.223,"epy":95.066,"epv":124.583,"track":278.5400,"speed":0.428,"climb":0.000,"eps":340.45,"mode":3} +$GPRMC,085037.00,A,5355.17281,N,02730.03900,E,0.252,277.72,050210,,,A*64 +$GPVTG,277.72,T,,M,0.252,N,0.467,K,A*3A +$GPGGA,085037.00,5355.17281,N,02730.03900,E,1,04,17.34,265.1,M,25.0,M,,*60 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.98,17.34,7.74*07 +$GPGSV,3,1,12,03,67,251,,06,72,220,,08,07,331,27,14,06,151,*72 +$GPGSV,3,2,12,15,15,032,48,16,15,204,,18,55,074,43,19,47,295,13*79 +$GPGSV,3,3,12,21,33,087,47,22,67,157,,24,02,084,41,26,18,131,36*71 +{"class":"SKY","tag":"GSV","xdop":11.35,"ydop":6.34,"vdop":5.42,"tdop":1.00,"hdop":13.00,"gdop":14.12,"pdop":14.08,"satellites":[{"PRN":3,"el":67,"az":251,"ss":0,"used":false},{"PRN":6,"el":72,"az":220,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":27,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":48,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":43,"used":true},{"PRN":19,"el":47,"az":295,"ss":13,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":0,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":true},{"PRN":26,"el":18,"az":131,"ss":36,"used":false}]} +$GPGLL,5355.17281,N,02730.03900,E,085037.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359837.000,"ept":0.005,"lat":53.919546833,"lon":27.500650000,"alt":265.100,"epx":170.223,"epy":95.066,"epv":124.583,"track":277.7200,"speed":0.130,"climb":0.000,"eps":340.45,"mode":3} +$GPRMC,085038.00,A,5355.17239,N,02730.03826,E,0.115,,050210,,,A*74 +$GPVTG,,T,,M,0.115,N,0.212,K,A*27 +$GPGGA,085038.00,5355.17239,N,02730.03826,E,1,04,17.34,265.1,M,25.0,M,,*69 +$GPGSA,A,3,18,21,24,15,,,,,,,,,18.99,17.34,7.74*06 +$GPGSV,3,1,12,03,67,251,,06,72,220,25,08,07,331,28,14,06,151,*7A +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,15*70 +$GPGSV,3,3,12,21,33,087,47,22,67,157,,24,02,084,41,26,18,131,35*72 +{"class":"SKY","tag":"GSV","xdop":11.35,"ydop":6.34,"vdop":5.42,"tdop":1.00,"hdop":13.00,"gdop":14.12,"pdop":14.08,"satellites":[{"PRN":3,"el":67,"az":251,"ss":0,"used":false},{"PRN":6,"el":72,"az":220,"ss":25,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":47,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":43,"used":true},{"PRN":19,"el":47,"az":295,"ss":15,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":0,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":true},{"PRN":26,"el":18,"az":131,"ss":35,"used":false}]} +$GPGLL,5355.17239,N,02730.03826,E,085038.00,A,A*6E +{"class":"TPV","tag":"GLL","time":1265359838.000,"ept":0.005,"lat":53.919539833,"lon":27.500637667,"alt":265.100,"epx":170.223,"epy":95.066,"epv":124.583,"track":0.0000,"speed":0.059,"climb":0.000,"eps":340.45,"mode":3} +$GPRMC,085039.00,A,5355.17198,N,02730.03759,E,0.137,,050210,,,A*7A +$GPVTG,,T,,M,0.137,N,0.254,K,A*25 +$GPGGA,085039.00,5355.17198,N,02730.03759,E,1,04,17.35,265.1,M,25.0,M,,*66 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.00,17.35,7.74*06 +$GPGSV,3,1,12,03,67,251,28,06,72,220,24,08,07,331,28,14,06,151,*71 +$GPGSV,3,2,12,15,15,032,47,16,15,204,,18,55,074,43,19,47,295,16*73 +$GPGSV,3,3,12,21,33,087,47,22,67,157,,24,02,084,40,26,18,131,35*73 +{"class":"SKY","tag":"GSV","xdop":11.35,"ydop":6.34,"vdop":5.42,"tdop":1.00,"hdop":13.00,"gdop":14.12,"pdop":14.08,"satellites":[{"PRN":3,"el":67,"az":251,"ss":28,"used":false},{"PRN":6,"el":72,"az":220,"ss":24,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":47,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":43,"used":true},{"PRN":19,"el":47,"az":295,"ss":16,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":0,"used":false},{"PRN":24,"el":2,"az":84,"ss":40,"used":true},{"PRN":26,"el":18,"az":131,"ss":35,"used":false}]} +$GPGLL,5355.17198,N,02730.03759,E,085039.00,A,A*60 +{"class":"TPV","tag":"GLL","time":1265359839.000,"ept":0.005,"lat":53.919533000,"lon":27.500626500,"alt":265.100,"epx":170.223,"epy":95.066,"epv":124.583,"track":0.0000,"speed":0.070,"climb":0.000,"eps":340.45,"mode":3} +$GPRMC,085040.00,A,5355.17137,N,02730.03625,E,0.168,,050210,,,A*71 +$GPVTG,,T,,M,0.168,N,0.311,K,A*2F +$GPGGA,085040.00,5355.17137,N,02730.03625,E,1,04,17.36,265.1,M,25.0,M,,*64 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.01,17.36,7.74*04 +$GPGSV,3,1,12,03,67,251,27,06,72,220,23,08,07,331,28,14,06,151,*79 +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,42,19,47,295,16*70 +$GPGSV,3,3,12,21,33,087,45,22,67,157,27,24,02,084,39,26,18,131,33*7C +{"class":"SKY","tag":"GSV","xdop":11.35,"ydop":6.34,"vdop":5.42,"tdop":1.00,"hdop":13.00,"gdop":14.12,"pdop":14.08,"satellites":[{"PRN":3,"el":67,"az":251,"ss":27,"used":false},{"PRN":6,"el":72,"az":220,"ss":23,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":45,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":42,"used":true},{"PRN":19,"el":47,"az":295,"ss":16,"used":false},{"PRN":21,"el":33,"az":87,"ss":45,"used":true},{"PRN":22,"el":67,"az":157,"ss":27,"used":false},{"PRN":24,"el":2,"az":84,"ss":39,"used":true},{"PRN":26,"el":18,"az":131,"ss":33,"used":false}]} +$GPGLL,5355.17137,N,02730.03625,E,085040.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1265359840.000,"ept":0.005,"lat":53.919522833,"lon":27.500604167,"alt":265.100,"epx":170.223,"epy":95.066,"epv":124.583,"track":0.0000,"speed":0.086,"climb":0.000,"eps":340.45,"mode":3} +$GPRMC,085041.00,A,5355.17092,N,02730.03549,E,0.298,274.51,050210,,,A*60 +$GPVTG,274.51,T,,M,0.298,N,0.552,K,A*39 +$GPGGA,085041.00,5355.17092,N,02730.03549,E,1,04,17.37,265.0,M,25.0,M,,*62 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.01,17.37,7.74*05 +$GPGSV,3,1,12,03,67,250,27,06,72,220,23,08,07,331,28,14,06,151,*78 +$GPGSV,3,2,12,15,15,032,46,16,15,204,,18,55,074,43,19,47,295,17*73 +$GPGSV,3,3,12,21,33,087,46,22,67,157,27,24,02,084,39,26,18,131,33*7F +{"class":"SKY","tag":"GSV","xdop":11.23,"ydop":6.27,"vdop":5.37,"tdop":1.00,"hdop":12.86,"gdop":13.97,"pdop":13.94,"satellites":[{"PRN":3,"el":67,"az":250,"ss":27,"used":false},{"PRN":6,"el":72,"az":220,"ss":23,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":46,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":43,"used":true},{"PRN":19,"el":47,"az":295,"ss":17,"used":false},{"PRN":21,"el":33,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":157,"ss":27,"used":false},{"PRN":24,"el":2,"az":84,"ss":39,"used":true},{"PRN":26,"el":18,"az":131,"ss":33,"used":false}]} +$GPGLL,5355.17092,N,02730.03549,E,085041.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359841.000,"ept":0.005,"lat":53.919515333,"lon":27.500591500,"alt":265.000,"epx":170.223,"epy":95.066,"epv":124.583,"track":274.5100,"speed":0.153,"climb":0.000,"eps":340.45,"mode":3} +$GPRMC,085042.00,A,5355.17075,N,02730.03565,E,0.253,275.14,050210,,,A*63 +$GPVTG,275.14,T,,M,0.253,N,0.469,K,A*37 +$GPGGA,085042.00,5355.17075,N,02730.03565,E,1,04,17.37,265.0,M,25.0,M,,*66 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.02,17.37,7.74*06 +$GPGSV,3,1,12,03,67,250,26,06,72,220,22,08,07,331,28,14,06,151,*78 +$GPGSV,3,2,12,15,15,032,46,16,15,204,,18,55,074,44,19,47,295,16*75 +$GPGSV,3,3,12,21,33,087,46,22,67,157,27,24,02,084,39,26,18,131,32*7E +{"class":"SKY","tag":"GSV","xdop":11.23,"ydop":6.27,"vdop":5.37,"tdop":1.00,"hdop":12.86,"gdop":13.97,"pdop":13.94,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":220,"ss":22,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":46,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":44,"used":true},{"PRN":19,"el":47,"az":295,"ss":16,"used":false},{"PRN":21,"el":33,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":157,"ss":27,"used":false},{"PRN":24,"el":2,"az":84,"ss":39,"used":true},{"PRN":26,"el":18,"az":131,"ss":32,"used":false}]} +$GPGLL,5355.17075,N,02730.03565,E,085042.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1265359842.000,"ept":0.005,"lat":53.919512500,"lon":27.500594167,"alt":265.000,"epx":168.458,"epy":94.058,"epv":123.537,"track":275.1400,"speed":0.130,"climb":0.000,"eps":338.68,"mode":3} +$GPRMC,085043.00,A,5355.17087,N,02730.03666,E,0.177,,050210,,,A*71 +$GPVTG,,T,,M,0.177,N,0.327,K,A*24 +$GPGGA,085043.00,5355.17087,N,02730.03666,E,1,04,17.38,265.2,M,25.0,M,,*67 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.03,17.38,7.74*08 +$GPGSV,3,1,12,03,67,250,,06,72,220,21,08,07,331,28,14,06,151,*7F +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,44,19,47,295,16*76 +$GPGSV,3,3,12,21,33,087,46,22,67,157,28,24,02,084,39,26,18,131,30*73 +{"class":"SKY","tag":"GSV","xdop":11.23,"ydop":6.27,"vdop":5.37,"tdop":1.00,"hdop":12.86,"gdop":13.97,"pdop":13.94,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":220,"ss":21,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":45,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":44,"used":true},{"PRN":19,"el":47,"az":295,"ss":16,"used":false},{"PRN":21,"el":33,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":157,"ss":28,"used":false},{"PRN":24,"el":2,"az":84,"ss":39,"used":true},{"PRN":26,"el":18,"az":131,"ss":30,"used":false}]} +$GPGLL,5355.17087,N,02730.03666,E,085043.00,A,A*6F +{"class":"TPV","tag":"GLL","time":1265359843.000,"ept":0.005,"lat":53.919514500,"lon":27.500611000,"alt":265.200,"epx":168.458,"epy":94.058,"epv":123.537,"track":0.0000,"speed":0.091,"climb":0.000,"eps":336.92,"mode":3} +$GPRMC,085044.00,A,5355.17136,N,02730.03861,E,0.309,281.42,050210,,,A*6C +$GPVTG,281.42,T,,M,0.309,N,0.572,K,A*3A +$GPGGA,085044.00,5355.17136,N,02730.03861,E,1,04,17.39,265.4,M,25.0,M,,*65 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.03,17.39,7.74*09 +$GPGSV,3,1,12,03,67,250,,06,72,219,19,08,07,331,29,14,06,151,*7F +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,44,19,47,295,15*75 +$GPGSV,3,3,12,21,33,087,46,22,67,157,28,24,02,084,39,26,18,131,28*7A +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":19,"used":false},{"PRN":8,"el":7,"az":331,"ss":29,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":45,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":44,"used":true},{"PRN":19,"el":47,"az":295,"ss":15,"used":false},{"PRN":21,"el":33,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":157,"ss":28,"used":false},{"PRN":24,"el":2,"az":84,"ss":39,"used":true},{"PRN":26,"el":18,"az":131,"ss":28,"used":false}]} +$GPGLL,5355.17136,N,02730.03861,E,085044.00,A,A*6A +{"class":"TPV","tag":"GLL","time":1265359844.000,"ept":0.005,"lat":53.919522667,"lon":27.500643500,"alt":265.400,"epx":168.458,"epy":94.058,"epv":123.537,"track":281.4200,"speed":0.159,"climb":0.000,"eps":336.92,"mode":3} +$GPRMC,085045.00,A,5355.17209,N,02730.04094,E,0.774,290.35,050210,,,A*69 +$GPVTG,290.35,T,,M,0.774,N,1.434,K,A*36 +$GPGGA,085045.00,5355.17209,N,02730.04094,E,1,04,17.39,265.7,M,25.0,M,,*6D +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.04,17.39,7.74*0E +$GPGSV,3,1,12,03,67,250,,06,72,219,17,08,07,331,28,14,06,151,*70 +$GPGSV,3,2,12,15,15,032,44,16,15,204,,18,55,074,44,19,47,295,14*75 +$GPGSV,3,3,12,21,33,087,46,22,67,157,28,24,02,084,39,26,18,131,27*75 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":17,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":44,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":44,"used":true},{"PRN":19,"el":47,"az":295,"ss":14,"used":false},{"PRN":21,"el":33,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":157,"ss":28,"used":false},{"PRN":24,"el":2,"az":84,"ss":39,"used":true},{"PRN":26,"el":18,"az":131,"ss":27,"used":false}]} +$GPGLL,5355.17209,N,02730.04094,E,085045.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1265359845.000,"ept":0.005,"lat":53.919534833,"lon":27.500682333,"alt":265.700,"epx":165.547,"epy":92.497,"epv":121.175,"track":290.3500,"speed":0.398,"climb":0.000,"eps":334.01,"mode":3} +$GPRMC,085046.00,A,5355.17280,N,02730.04292,E,0.376,298.76,050210,,,A*66 +$GPVTG,298.76,T,,M,0.376,N,0.697,K,A*35 +$GPGGA,085046.00,5355.17280,N,02730.04292,E,1,04,17.40,266.0,M,25.0,M,,*61 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.05,17.40,7.74*01 +$GPGSV,3,1,12,03,67,250,,06,72,219,14,08,07,331,28,14,06,151,*73 +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,45,19,47,295,15*74 +$GPGSV,3,3,12,21,33,087,46,22,67,157,30,24,02,084,40,26,18,131,27*72 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":14,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":45,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":45,"used":true},{"PRN":19,"el":47,"az":295,"ss":15,"used":false},{"PRN":21,"el":33,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":157,"ss":30,"used":false},{"PRN":24,"el":2,"az":84,"ss":40,"used":true},{"PRN":26,"el":18,"az":131,"ss":27,"used":false}]} +$GPGLL,5355.17280,N,02730.04292,E,085046.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359846.000,"ept":0.005,"lat":53.919546667,"lon":27.500715333,"alt":266.000,"epx":165.547,"epy":92.497,"epv":121.175,"track":298.7600,"speed":0.193,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085047.00,A,5355.17358,N,02730.04516,E,0.431,306.60,050210,,,A*6D +$GPVTG,306.60,T,,M,0.431,N,0.799,K,A*3F +$GPGGA,085047.00,5355.17358,N,02730.04516,E,1,04,17.41,266.5,M,25.0,M,,*6B +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.05,17.41,7.74*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,11,08,07,331,28,14,06,151,*72 +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,45,19,47,295,15*74 +$GPGSV,3,3,12,21,33,087,46,22,67,157,30,24,02,084,40,26,18,131,29*7C +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":11,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":45,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":45,"used":true},{"PRN":19,"el":47,"az":295,"ss":15,"used":false},{"PRN":21,"el":33,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":157,"ss":30,"used":false},{"PRN":24,"el":2,"az":84,"ss":40,"used":true},{"PRN":26,"el":18,"az":131,"ss":29,"used":false}]} +$GPGLL,5355.17358,N,02730.04516,E,085047.00,A,A*69 +{"class":"TPV","tag":"GLL","time":1265359847.000,"ept":0.005,"lat":53.919559667,"lon":27.500752667,"alt":266.500,"epx":165.547,"epy":92.497,"epv":121.175,"track":306.6000,"speed":0.222,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085048.00,A,5355.17430,N,02730.04697,E,0.219,311.70,050210,,,A*6A +$GPVTG,311.70,T,,M,0.219,N,0.406,K,A*31 +$GPGGA,085048.00,5355.17430,N,02730.04697,E,1,04,17.42,266.9,M,25.0,M,,*68 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.06,17.42,7.74*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,08,08,07,331,27,14,06,151,*75 +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,46,19,47,295,14*76 +$GPGSV,3,3,12,21,33,087,47,22,67,157,29,24,02,084,41,26,18,131,32*7E +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":8,"used":false},{"PRN":8,"el":7,"az":331,"ss":27,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":45,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":46,"used":true},{"PRN":19,"el":47,"az":295,"ss":14,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":29,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":true},{"PRN":26,"el":18,"az":131,"ss":32,"used":false}]} +$GPGLL,5355.17430,N,02730.04697,E,085048.00,A,A*65 +{"class":"TPV","tag":"GLL","time":1265359848.000,"ept":0.005,"lat":53.919571667,"lon":27.500782833,"alt":266.900,"epx":165.547,"epy":92.497,"epv":121.175,"track":311.7000,"speed":0.113,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085049.00,A,5355.17510,N,02730.04910,E,0.590,317.91,050210,,,A*67 +$GPVTG,317.91,T,,M,0.590,N,1.092,K,A*36 +$GPGGA,085049.00,5355.17510,N,02730.04910,E,1,04,17.42,267.4,M,25.0,M,,*66 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.07,17.42,7.74*01 +$GPGSV,3,1,12,03,67,250,26,06,72,219,,08,07,331,27,14,06,151,23*7C +$GPGSV,3,2,12,15,15,032,44,16,15,204,,18,55,074,46,19,47,295,14*77 +$GPGSV,3,3,12,21,33,087,47,22,67,157,29,24,02,084,41,26,18,131,33*7F +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":27,"used":false},{"PRN":14,"el":6,"az":151,"ss":23,"used":false},{"PRN":15,"el":15,"az":32,"ss":44,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":46,"used":true},{"PRN":19,"el":47,"az":295,"ss":14,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":29,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":true},{"PRN":26,"el":18,"az":131,"ss":33,"used":false}]} +$GPGLL,5355.17510,N,02730.04910,E,085049.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359849.000,"ept":0.005,"lat":53.919585000,"lon":27.500818333,"alt":267.400,"epx":165.547,"epy":92.497,"epv":121.175,"track":317.9100,"speed":0.304,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085050.00,A,5355.17582,N,02730.05082,E,0.273,321.57,050210,,,A*62 +$GPVTG,321.57,T,,M,0.273,N,0.505,K,A*39 +$GPGGA,085050.00,5355.17582,N,02730.05082,E,1,04,17.43,267.9,M,25.0,M,,*6A +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.07,17.43,7.74*00 +$GPGSV,3,1,12,03,67,250,25,06,72,219,,08,07,331,26,14,06,151,*7F +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,46,19,47,295,15*77 +$GPGSV,3,3,12,21,33,087,47,22,67,157,29,24,02,084,41,26,18,131,34*78 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":25,"used":false},{"PRN":6,"el":72,"az":219,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":45,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":46,"used":true},{"PRN":19,"el":47,"az":295,"ss":15,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":29,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":true},{"PRN":26,"el":18,"az":131,"ss":34,"used":false}]} +$GPGLL,5355.17582,N,02730.05082,E,085050.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359850.000,"ept":0.005,"lat":53.919597000,"lon":27.500847000,"alt":267.900,"epx":165.547,"epy":92.497,"epv":121.175,"track":321.5700,"speed":0.140,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085051.00,A,5355.17632,N,02730.05184,E,0.307,327.68,050210,,,A*64 +$GPVTG,327.68,T,,M,0.307,N,0.569,K,A*3B +$GPGGA,085051.00,5355.17632,N,02730.05184,E,1,04,17.44,268.3,M,25.0,M,,*66 +$GPGSA,A,3,18,21,24,15,,,,,,,,,19.08,17.44,7.74*08 +$GPGSV,3,1,12,03,67,250,,06,72,219,,08,07,331,26,14,06,151,*78 +$GPGSV,3,2,12,15,15,032,45,16,15,204,,18,55,074,46,19,47,295,16*74 +$GPGSV,3,3,12,21,33,087,47,22,67,157,28,24,02,084,41,26,18,131,34*79 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":15,"az":32,"ss":45,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":46,"used":true},{"PRN":19,"el":47,"az":295,"ss":16,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":28,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":true},{"PRN":26,"el":18,"az":131,"ss":34,"used":false}]} +$GPGLL,5355.17632,N,02730.05184,E,085051.00,A,A*69 +{"class":"TPV","tag":"GLL","time":1265359851.000,"ept":0.005,"lat":53.919605333,"lon":27.500864000,"alt":268.300,"epx":165.547,"epy":92.497,"epv":121.175,"track":327.6800,"speed":0.158,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085052.00,A,5355.17477,N,02730.04765,E,0.521,322.69,050210,,,A*6A +$GPVTG,322.69,T,,M,0.521,N,0.966,K,A*3E +$GPGGA,085052.00,5355.17477,N,02730.04765,E,1,05,3.57,266.0,M,25.0,M,,*55 +$GPGSA,A,3,18,21,26,24,15,,,,,,,,4.12,3.57,2.06*0C +$GPGSV,3,1,12,03,67,250,,06,72,219,,08,07,331,26,14,06,151,26*7C +$GPGSV,3,2,12,15,15,032,44,16,15,204,,18,55,074,46,19,47,295,16*75 +$GPGSV,3,3,12,21,33,087,47,22,67,157,28,24,02,084,41,26,18,130,35*79 +{"class":"SKY","tag":"GSV","xdop":1.30,"ydop":0.76,"vdop":1.45,"tdop":0.84,"hdop":1.51,"gdop":2.26,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":26,"used":false},{"PRN":15,"el":15,"az":32,"ss":44,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":46,"used":true},{"PRN":19,"el":47,"az":295,"ss":16,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":28,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":true},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.17477,N,02730.04765,E,085052.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1265359852.000,"ept":0.005,"lat":53.919579500,"lon":27.500794167,"alt":266.000,"epx":165.547,"epy":92.497,"epv":121.175,"track":322.6900,"speed":0.268,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085053.00,A,5355.16685,N,02730.02924,E,0.116,,050210,,,A*7A +$GPVTG,,T,,M,0.116,N,0.215,K,A*23 +$GPGGA,085053.00,5355.16685,N,02730.02924,E,1,04,4.99,244.3,M,25.0,M,,*50 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.26*03 +$GPGSV,3,1,12,03,67,250,,06,72,219,,08,07,331,25,14,06,151,25*7C +$GPGSV,3,2,12,15,14,032,43,16,15,204,,18,55,074,45,19,47,295,18*7E +$GPGSV,3,3,12,21,33,087,46,22,67,157,28,24,02,084,41,26,18,130,34*79 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":25,"used":false},{"PRN":14,"el":6,"az":151,"ss":25,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":15,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":45,"used":true},{"PRN":19,"el":47,"az":295,"ss":18,"used":false},{"PRN":21,"el":33,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":157,"ss":28,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.16685,N,02730.02924,E,085053.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1265359853.000,"ept":0.005,"lat":53.919447500,"lon":27.500487333,"alt":244.300,"epx":19.524,"epy":11.413,"epv":33.436,"track":0.0000,"speed":0.060,"climb":0.000,"eps":185.07,"mode":3} +$GPRMC,085054.00,A,5355.16719,N,02730.02813,E,0.044,,050210,,,A*7A +$GPVTG,,T,,M,0.044,N,0.082,K,A*29 +$GPGGA,085054.00,5355.16719,N,02730.02813,E,1,04,4.99,243.9,M,25.0,M,,*5B +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.26*03 +$GPGSV,3,1,12,03,67,250,,06,72,219,,08,07,331,24,14,06,151,25*7D +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,074,46,19,47,295,17*74 +$GPGSV,3,3,12,21,33,087,47,22,67,157,27,24,02,084,41,26,18,130,33*70 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":24,"used":false},{"PRN":14,"el":6,"az":151,"ss":25,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":46,"used":true},{"PRN":19,"el":47,"az":295,"ss":17,"used":false},{"PRN":21,"el":33,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":157,"ss":27,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.16719,N,02730.02813,E,085054.00,A,A*65 +{"class":"TPV","tag":"GLL","time":1265359854.000,"ept":0.005,"lat":53.919453167,"lon":27.500468833,"alt":243.900,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.023,"climb":0.000,"eps":185.07,"mode":3} +$GPRMC,085055.00,A,5355.16726,N,02730.02707,E,0.025,,050210,,,A*7A +$GPVTG,,T,,M,0.025,N,0.047,K,A*27 +$GPGGA,085055.00,5355.16726,N,02730.02707,E,1,04,4.99,243.9,M,25.0,M,,*5C +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.26*03 +$GPGSV,3,1,12,03,67,250,,06,72,219,25,08,07,331,23,14,06,151,24*7C +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,074,46,19,47,295,17*73 +$GPGSV,3,3,12,21,33,087,48,22,67,157,26,24,02,084,41,26,18,130,33*7E +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":25,"used":false},{"PRN":8,"el":7,"az":331,"ss":23,"used":false},{"PRN":14,"el":6,"az":151,"ss":24,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":74,"ss":46,"used":true},{"PRN":19,"el":47,"az":295,"ss":17,"used":false},{"PRN":21,"el":33,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":157,"ss":26,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.16726,N,02730.02707,E,085055.00,A,A*62 +{"class":"TPV","tag":"GLL","time":1265359855.000,"ept":0.005,"lat":53.919454333,"lon":27.500451167,"alt":243.900,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.013,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085056.00,A,5355.16743,N,02730.02569,E,0.104,,050210,,,A*72 +$GPVTG,,T,,M,0.104,N,0.192,K,A*2C +$GPGGA,085056.00,5355.16743,N,02730.02569,E,1,04,4.99,244.1,M,25.0,M,,*59 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,24,08,07,331,23,14,06,151,24*7D +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,47,295,16*75 +$GPGSV,3,3,12,21,33,087,48,22,67,157,25,24,02,084,41,26,18,130,33*7D +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":24,"used":false},{"PRN":8,"el":7,"az":331,"ss":23,"used":false},{"PRN":14,"el":6,"az":151,"ss":24,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":47,"az":295,"ss":16,"used":false},{"PRN":21,"el":33,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":157,"ss":25,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.16743,N,02730.02569,E,085056.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1265359856.000,"ept":0.005,"lat":53.919457167,"lon":27.500428167,"alt":244.100,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.054,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085057.00,A,5355.16755,N,02730.02418,E,0.054,,050210,,,A*77 +$GPVTG,,T,,M,0.054,N,0.100,K,A*23 +$GPGGA,085057.00,5355.16755,N,02730.02418,E,1,04,4.99,244.3,M,25.0,M,,*5A +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,24,08,07,331,25,14,06,151,25*7A +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,47,19,48,295,15*7F +$GPGSV,3,3,12,21,33,087,50,22,67,157,24,24,02,084,42,26,18,130,35*70 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":24,"used":false},{"PRN":8,"el":7,"az":331,"ss":25,"used":false},{"PRN":14,"el":6,"az":151,"ss":25,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":47,"used":true},{"PRN":19,"el":48,"az":295,"ss":15,"used":false},{"PRN":21,"el":33,"az":87,"ss":50,"used":true},{"PRN":22,"el":67,"az":157,"ss":24,"used":false},{"PRN":24,"el":2,"az":84,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.16755,N,02730.02418,E,085057.00,A,A*69 +{"class":"TPV","tag":"GLL","time":1265359857.000,"ept":0.005,"lat":53.919459167,"lon":27.500403000,"alt":244.300,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.028,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085058.00,A,5355.16773,N,02730.02276,E,0.083,,050210,,,A*78 +$GPVTG,,T,,M,0.083,N,0.154,K,A*28 +$GPGGA,085058.00,5355.16773,N,02730.02276,E,1,04,4.99,244.3,M,25.0,M,,*5F +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,22,08,07,331,26,14,06,151,24*7E +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,13*7F +$GPGSV,3,3,12,21,33,087,49,22,67,157,,24,02,084,42,26,18,130,34*7F +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":22,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":24,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":13,"used":false},{"PRN":21,"el":33,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":157,"ss":0,"used":false},{"PRN":24,"el":2,"az":84,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.16773,N,02730.02276,E,085058.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1265359858.000,"ept":0.005,"lat":53.919462167,"lon":27.500379333,"alt":244.300,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.043,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085059.00,A,5355.16784,N,02730.02176,E,0.038,,050210,,,A*72 +$GPVTG,,T,,M,0.038,N,0.071,K,A*2E +$GPGGA,085059.00,5355.16784,N,02730.02176,E,1,04,4.99,244.2,M,25.0,M,,*54 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,19,08,07,331,26,14,06,151,24*76 +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,12*7E +$GPGSV,3,3,12,21,32,087,49,22,67,157,23,24,02,084,42,26,18,130,34*7F +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":19,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":24,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":12,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":157,"ss":23,"used":false},{"PRN":24,"el":2,"az":84,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.16784,N,02730.02176,E,085059.00,A,A*66 +{"class":"TPV","tag":"GLL","time":1265359859.000,"ept":0.005,"lat":53.919464000,"lon":27.500362667,"alt":244.200,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.020,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085100.00,A,5355.16789,N,02730.02093,E,0.059,,050210,,,A*7F +$GPVTG,,T,,M,0.059,N,0.109,K,A*27 +$GPGGA,085100.00,5355.16789,N,02730.02093,E,1,04,4.99,244.3,M,25.0,M,,*5F +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,27,06,72,219,17,08,07,331,27,14,06,151,23*7B +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,14*7F +$GPGSV,3,3,12,21,32,087,49,22,67,156,23,24,02,084,41,26,18,130,34*7D +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":27,"used":false},{"PRN":6,"el":72,"az":219,"ss":17,"used":false},{"PRN":8,"el":7,"az":331,"ss":27,"used":false},{"PRN":14,"el":6,"az":151,"ss":23,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":14,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":23,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.16789,N,02730.02093,E,085100.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1265359860.000,"ept":0.005,"lat":53.919464833,"lon":27.500348833,"alt":244.300,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.030,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085101.00,A,5355.16793,N,02730.02037,E,0.033,,050210,,,A*77 +$GPVTG,,T,,M,0.033,N,0.062,K,A*27 +$GPGGA,085101.00,5355.16793,N,02730.02037,E,1,04,4.99,244.4,M,25.0,M,,*5C +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,25,06,72,219,15,08,07,331,27,14,06,151,22*7A +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,15*7E +$GPGSV,3,3,12,21,32,087,49,22,67,156,24,24,02,084,41,26,18,130,34*7A +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":25,"used":false},{"PRN":6,"el":72,"az":219,"ss":15,"used":false},{"PRN":8,"el":7,"az":331,"ss":27,"used":false},{"PRN":14,"el":6,"az":151,"ss":22,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":15,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":24,"used":false},{"PRN":24,"el":2,"az":84,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.16793,N,02730.02037,E,085101.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1265359861.000,"ept":0.005,"lat":53.919465500,"lon":27.500339500,"alt":244.400,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.017,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085102.00,A,5355.16792,N,02730.01981,E,0.245,317.09,050210,,,A*63 +$GPVTG,317.09,T,,M,0.245,N,0.453,K,A*30 +$GPGGA,085102.00,5355.16792,N,02730.01981,E,1,04,4.99,244.5,M,25.0,M,,*58 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,25,06,72,219,17,08,07,331,28,14,06,151,20*75 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,15*7E +$GPGSV,3,3,12,21,32,087,49,22,67,156,25,24,01,085,41,26,18,130,33*7E +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":25,"used":false},{"PRN":6,"el":72,"az":219,"ss":17,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":20,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":15,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":25,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.16792,N,02730.01981,E,085102.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1265359862.000,"ept":0.005,"lat":53.919465333,"lon":27.500330167,"alt":244.500,"epx":165.547,"epy":92.497,"epv":121.175,"track":317.0900,"speed":0.126,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085103.00,A,5355.16789,N,02730.01903,E,0.466,312.02,050210,,,A*6B +$GPVTG,312.02,T,,M,0.466,N,0.863,K,A*36 +$GPGGA,085103.00,5355.16789,N,02730.01903,E,1,04,4.99,244.5,M,25.0,M,,*59 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,24,06,72,219,20,08,07,331,28,14,06,151,*72 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,15*7E +$GPGSV,3,3,12,21,32,087,49,22,67,156,25,24,01,085,41,26,18,130,33*7E +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":24,"used":false},{"PRN":6,"el":72,"az":219,"ss":20,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":15,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":25,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.16789,N,02730.01903,E,085103.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1265359863.000,"ept":0.005,"lat":53.919464833,"lon":27.500317167,"alt":244.500,"epx":165.547,"epy":92.497,"epv":121.175,"track":312.0200,"speed":0.240,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085104.00,A,5355.16784,N,02730.01827,E,0.519,307.35,050210,,,A*6F +$GPVTG,307.35,T,,M,0.519,N,0.962,K,A*3F +$GPGGA,085104.00,5355.16784,N,02730.01827,E,1,04,4.99,244.3,M,25.0,M,,*52 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,24,06,72,219,21,08,07,331,28,14,06,151,*73 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,14*7F +$GPGSV,3,3,12,21,32,087,49,22,67,156,25,24,01,085,41,26,18,130,33*7E +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":24,"used":false},{"PRN":6,"el":72,"az":219,"ss":21,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":14,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":25,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.16784,N,02730.01827,E,085104.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1265359864.000,"ept":0.005,"lat":53.919464000,"lon":27.500304500,"alt":244.300,"epx":165.547,"epy":92.497,"epv":121.175,"track":307.3500,"speed":0.267,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085105.00,A,5355.16779,N,02730.01767,E,0.466,302.81,050210,,,A*64 +$GPVTG,302.81,T,,M,0.466,N,0.863,K,A*3C +$GPGGA,085105.00,5355.16779,N,02730.01767,E,1,04,4.99,244.1,M,25.0,M,,*58 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,24,06,72,219,21,08,07,331,28,14,06,151,*73 +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,12*7E +$GPGSV,3,3,12,21,32,087,49,22,67,156,24,24,01,085,42,26,18,130,33*7C +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":24,"used":false},{"PRN":6,"el":72,"az":219,"ss":21,"used":false},{"PRN":8,"el":7,"az":331,"ss":28,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":12,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":24,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.16779,N,02730.01767,E,085105.00,A,A*69 +{"class":"TPV","tag":"GLL","time":1265359865.000,"ept":0.005,"lat":53.919463167,"lon":27.500294500,"alt":244.100,"epx":165.547,"epy":92.497,"epv":121.175,"track":302.8100,"speed":0.240,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085106.00,A,5355.16774,N,02730.01722,E,0.239,298.38,050210,,,A*67 +$GPVTG,298.38,T,,M,0.239,N,0.443,K,A*3E +$GPGGA,085106.00,5355.16774,N,02730.01722,E,1,04,4.99,243.8,M,25.0,M,,*59 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,24,06,72,219,20,08,07,331,27,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,10*7C +$GPGSV,3,3,12,21,32,087,48,22,67,156,,24,01,085,42,26,18,130,34*7C +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":24,"used":false},{"PRN":6,"el":72,"az":219,"ss":20,"used":false},{"PRN":8,"el":7,"az":331,"ss":27,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":10,"used":false},{"PRN":21,"el":32,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.16774,N,02730.01722,E,085106.00,A,A*66 +{"class":"TPV","tag":"GLL","time":1265359866.000,"ept":0.005,"lat":53.919462333,"lon":27.500287000,"alt":243.800,"epx":165.547,"epy":92.497,"epv":121.175,"track":298.3800,"speed":0.123,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085107.00,A,5355.16776,N,02730.01731,E,0.085,,050210,,,A*75 +$GPVTG,,T,,M,0.085,N,0.157,K,A*2D +$GPGGA,085107.00,5355.16776,N,02730.01731,E,1,04,4.99,243.6,M,25.0,M,,*56 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,24,06,72,219,17,08,07,331,27,14,06,151,*79 +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,10*7C +$GPGSV,3,3,12,21,32,087,48,22,67,156,,24,01,085,42,26,18,130,35*7D +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":24,"used":false},{"PRN":6,"el":72,"az":219,"ss":17,"used":false},{"PRN":8,"el":7,"az":331,"ss":27,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":10,"used":false},{"PRN":21,"el":32,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.16776,N,02730.01731,E,085107.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359867.000,"ept":0.005,"lat":53.919462667,"lon":27.500288500,"alt":243.600,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.044,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085108.00,A,5355.16781,N,02730.01786,E,0.188,,050210,,,A*72 +$GPVTG,,T,,M,0.188,N,0.349,K,A*2C +$GPGGA,085108.00,5355.16781,N,02730.01786,E,1,04,4.99,243.4,M,25.0,M,,*5F +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,23,06,72,219,15,08,07,331,26,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,46,19,48,295,13*7F +$GPGSV,3,3,12,21,32,087,47,22,67,156,,24,01,085,42,26,18,130,36*71 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":23,"used":false},{"PRN":6,"el":72,"az":219,"ss":15,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":13,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":36,"used":true}]} +$GPGLL,5355.16781,N,02730.01786,E,085108.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1265359868.000,"ept":0.005,"lat":53.919463500,"lon":27.500297667,"alt":243.400,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.097,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085109.00,A,5355.16801,N,02730.01883,E,0.221,306.41,050210,,,A*60 +$GPVTG,306.41,T,,M,0.221,N,0.409,K,A*31 +$GPGGA,085109.00,5355.16801,N,02730.01883,E,1,04,4.99,243.5,M,25.0,M,,*52 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,11,08,07,331,25,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,41,16,14,204,,18,55,073,45,19,48,295,16*7B +$GPGSV,3,3,12,21,32,087,45,22,67,156,,24,01,085,41,26,18,130,36*70 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":11,"used":false},{"PRN":8,"el":7,"az":331,"ss":25,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":41,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":16,"used":false},{"PRN":21,"el":32,"az":87,"ss":45,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":36,"used":true}]} +$GPGLL,5355.16801,N,02730.01883,E,085109.00,A,A*60 +{"class":"TPV","tag":"GLL","time":1265359869.000,"ept":0.005,"lat":53.919466833,"lon":27.500313833,"alt":243.500,"epx":165.547,"epy":92.497,"epv":121.175,"track":306.4100,"speed":0.114,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085110.00,A,5355.16838,N,02730.02013,E,0.088,,050210,,,A*7F +$GPVTG,,T,,M,0.088,N,0.162,K,A*26 +$GPGGA,085110.00,5355.16838,N,02730.02013,E,1,04,4.99,243.9,M,25.0,M,,*5E +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,10,08,07,331,24,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,40,16,14,204,26,18,55,073,45,19,48,295,18*70 +$GPGSV,3,3,12,21,32,087,45,22,67,156,,24,01,085,40,26,18,130,37*70 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":10,"used":false},{"PRN":8,"el":7,"az":331,"ss":24,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":40,"used":true},{"PRN":16,"el":14,"az":204,"ss":26,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":18,"used":false},{"PRN":21,"el":32,"az":87,"ss":45,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":37,"used":true}]} +$GPGLL,5355.16838,N,02730.02013,E,085110.00,A,A*60 +{"class":"TPV","tag":"GLL","time":1265359870.000,"ept":0.005,"lat":53.919473000,"lon":27.500335500,"alt":243.900,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.045,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085111.00,A,5355.16896,N,02730.02189,E,0.078,,050210,,,A*77 +$GPVTG,,T,,M,0.078,N,0.145,K,A*2C +$GPGGA,085111.00,5355.16896,N,02730.02189,E,1,04,4.99,244.7,M,25.0,M,,*50 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,,06,72,219,,08,07,331,23,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,40,16,14,204,,18,55,073,46,19,48,295,20*7C +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,41,26,18,130,39*7C +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":23,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":40,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":20,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":39,"used":true}]} +$GPGLL,5355.16896,N,02730.02189,E,085111.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359871.000,"ept":0.005,"lat":53.919482667,"lon":27.500364833,"alt":244.700,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.040,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085112.00,A,5355.16942,N,02730.02332,E,0.033,,050210,,,A*71 +$GPVTG,,T,,M,0.033,N,0.061,K,A*24 +$GPGGA,085112.00,5355.16942,N,02730.02332,E,1,04,4.99,245.4,M,25.0,M,,*5B +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.99,2.27*02 +$GPGSV,3,1,12,03,67,250,27,06,72,219,,08,07,331,23,14,06,151,*78 +$GPGSV,3,2,12,15,14,032,41,16,14,204,,18,55,073,46,19,48,295,22*7F +$GPGSV,3,3,12,21,32,087,47,22,67,156,,24,01,085,41,26,18,130,39*7D +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":27,"used":false},{"PRN":6,"el":72,"az":219,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":23,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":41,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":22,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":39,"used":true}]} +$GPGLL,5355.16942,N,02730.02332,E,085112.00,A,A*6E +{"class":"TPV","tag":"GLL","time":1265359872.000,"ept":0.005,"lat":53.919490333,"lon":27.500388667,"alt":245.400,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.017,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085113.00,A,5355.16988,N,02730.02475,E,0.143,,050210,,,A*74 +$GPVTG,,T,,M,0.143,N,0.264,K,A*25 +$GPGGA,085113.00,5355.16988,N,02730.02475,E,1,04,4.98,246.1,M,25.0,M,,*5F +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,27,06,72,219,,08,07,331,24,14,06,151,*7F +$GPGSV,3,2,12,15,14,032,41,16,14,204,,18,55,073,45,19,48,295,24*7A +$GPGSV,3,3,12,21,32,087,47,22,67,156,,24,01,085,41,26,18,130,39*7D +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":27,"used":false},{"PRN":6,"el":72,"az":219,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":24,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":41,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":24,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":39,"used":true}]} +$GPGLL,5355.16988,N,02730.02475,E,085113.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1265359873.000,"ept":0.005,"lat":53.919498000,"lon":27.500412500,"alt":246.100,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.074,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085114.00,A,5355.17026,N,02730.02579,E,0.058,,050210,,,A*79 +$GPVTG,,T,,M,0.058,N,0.107,K,A*28 +$GPGGA,085114.00,5355.17026,N,02730.02579,E,1,04,4.98,246.8,M,25.0,M,,*50 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,27,06,72,219,,08,07,331,25,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,42,16,14,204,,18,55,073,45,19,48,295,24*79 +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,41,26,18,130,39*7C +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":27,"used":false},{"PRN":6,"el":72,"az":219,"ss":0,"used":false},{"PRN":8,"el":7,"az":331,"ss":25,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":42,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":24,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":39,"used":true}]} +$GPGLL,5355.17026,N,02730.02579,E,085114.00,A,A*6B +{"class":"TPV","tag":"GLL","time":1265359874.000,"ept":0.005,"lat":53.919504333,"lon":27.500429833,"alt":246.800,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.030,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085115.00,A,5355.17060,N,02730.02660,E,0.017,,050210,,,A*7A +$GPVTG,,T,,M,0.017,N,0.032,K,A*24 +$GPGGA,085115.00,5355.17060,N,02730.02660,E,1,04,4.98,247.8,M,25.0,M,,*59 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,27,06,72,219,24,08,07,331,26,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,42,16,14,204,,18,55,073,45,19,48,295,24*79 +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,41,26,18,130,39*7C +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":27,"used":false},{"PRN":6,"el":72,"az":219,"ss":24,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":42,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":24,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":39,"used":true}]} +$GPGLL,5355.17060,N,02730.02660,E,085115.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1265359875.000,"ept":0.005,"lat":53.919510000,"lon":27.500443333,"alt":247.800,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.009,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085116.00,A,5355.17084,N,02730.02730,E,0.040,,050210,,,A*75 +$GPVTG,,T,,M,0.040,N,0.075,K,A*25 +$GPGGA,085116.00,5355.17084,N,02730.02730,E,1,04,4.98,248.5,M,25.0,M,,*56 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,25,06,72,219,23,08,07,331,25,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,42,16,14,204,,18,55,073,45,19,48,295,23*7E +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,41,26,18,130,38*7D +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":25,"used":false},{"PRN":6,"el":72,"az":219,"ss":23,"used":false},{"PRN":8,"el":7,"az":331,"ss":25,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":42,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":23,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":38,"used":true}]} +$GPGLL,5355.17084,N,02730.02730,E,085116.00,A,A*6E +{"class":"TPV","tag":"GLL","time":1265359876.000,"ept":0.005,"lat":53.919514000,"lon":27.500455000,"alt":248.500,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.021,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085117.00,A,5355.17100,N,02730.02761,E,0.057,,050210,,,A*7B +$GPVTG,,T,,M,0.057,N,0.106,K,A*26 +$GPGGA,085117.00,5355.17100,N,02730.02761,E,1,04,4.98,249.2,M,25.0,M,,*58 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,24,06,72,219,21,08,07,331,25,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,45,19,48,295,22*7E +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,41,26,18,130,38*7D +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":24,"used":false},{"PRN":6,"el":72,"az":219,"ss":21,"used":false},{"PRN":8,"el":7,"az":331,"ss":25,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":22,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":38,"used":true}]} +$GPGLL,5355.17100,N,02730.02761,E,085117.00,A,A*66 +{"class":"TPV","tag":"GLL","time":1265359877.000,"ept":0.005,"lat":53.919516667,"lon":27.500460167,"alt":249.200,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.029,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085118.00,A,5355.17107,N,02730.02791,E,0.087,,050210,,,A*71 +$GPVTG,,T,,M,0.087,N,0.160,K,A*2B +$GPGGA,085118.00,5355.17107,N,02730.02791,E,1,04,4.98,249.6,M,25.0,M,,*5B +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,23,06,72,219,18,08,07,331,25,14,06,151,*73 +$GPGSV,3,2,12,15,14,032,42,16,14,204,,18,55,073,43,19,48,295,20*7B +$GPGSV,3,3,12,21,32,087,44,22,67,156,,24,01,085,39,26,18,130,35*7D +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":23,"used":false},{"PRN":6,"el":72,"az":219,"ss":18,"used":false},{"PRN":8,"el":7,"az":331,"ss":25,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":42,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":43,"used":true},{"PRN":19,"el":48,"az":295,"ss":20,"used":false},{"PRN":21,"el":32,"az":87,"ss":44,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":39,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.17107,N,02730.02791,E,085118.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1265359878.000,"ept":0.005,"lat":53.919517833,"lon":27.500465167,"alt":249.600,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.045,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085119.00,A,5355.17112,N,02730.02835,E,0.205,302.21,050210,,,A*61 +$GPVTG,302.21,T,,M,0.205,N,0.380,K,A*33 +$GPGGA,085119.00,5355.17112,N,02730.02835,E,1,04,4.98,249.8,M,25.0,M,,*51 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,22,06,72,219,14,08,07,331,25,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,44,19,48,295,20*7D +$GPGSV,3,3,12,21,32,087,45,22,67,156,,24,01,085,39,26,18,130,35*7C +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":22,"used":false},{"PRN":6,"el":72,"az":219,"ss":14,"used":false},{"PRN":8,"el":7,"az":331,"ss":25,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":44,"used":true},{"PRN":19,"el":48,"az":295,"ss":20,"used":false},{"PRN":21,"el":32,"az":87,"ss":45,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":39,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.17112,N,02730.02835,E,085119.00,A,A*65 +{"class":"TPV","tag":"GLL","time":1265359879.000,"ept":0.005,"lat":53.919518667,"lon":27.500472500,"alt":249.800,"epx":165.547,"epy":92.497,"epv":121.175,"track":302.2100,"speed":0.105,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085120.00,A,5355.17115,N,02730.02871,E,0.142,,050210,,,A*70 +$GPVTG,,T,,M,0.142,N,0.263,K,A*23 +$GPGGA,085120.00,5355.17115,N,02730.02871,E,1,04,4.98,250.0,M,25.0,M,,*5C +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,21,06,72,219,16,08,07,331,24,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,44,19,48,295,20*7A +$GPGSV,3,3,12,21,32,087,46,22,67,156,,24,01,085,39,26,18,130,34*7E +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":21,"used":false},{"PRN":6,"el":72,"az":219,"ss":16,"used":false},{"PRN":8,"el":7,"az":331,"ss":24,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":44,"used":true},{"PRN":19,"el":48,"az":295,"ss":20,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":39,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.17115,N,02730.02871,E,085120.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1265359880.000,"ept":0.005,"lat":53.919519167,"lon":27.500478500,"alt":250.000,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.073,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085121.00,A,5355.17114,N,02730.02897,E,0.131,,050210,,,A*7C +$GPVTG,,T,,M,0.131,N,0.243,K,A*25 +$GPGGA,085121.00,5355.17114,N,02730.02897,E,1,04,4.98,250.2,M,25.0,M,,*56 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.48,4.98,2.27*03 +$GPGSV,3,1,12,03,67,250,23,06,72,219,20,08,07,331,25,14,06,151,*78 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,22*78 +$GPGSV,3,3,12,21,32,087,47,22,67,156,,24,01,085,40,26,18,130,34*71 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":23,"used":false},{"PRN":6,"el":72,"az":219,"ss":20,"used":false},{"PRN":8,"el":7,"az":331,"ss":25,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":22,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.17114,N,02730.02897,E,085121.00,A,A*60 +{"class":"TPV","tag":"GLL","time":1265359881.000,"ept":0.005,"lat":53.919519000,"lon":27.500482833,"alt":250.200,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.067,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085122.00,A,5355.17111,N,02730.02927,E,0.018,,050210,,,A*7A +$GPVTG,,T,,M,0.018,N,0.034,K,A*2D +$GPGGA,085122.00,5355.17111,N,02730.02927,E,1,04,4.98,250.6,M,25.0,M,,*5E +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.27*0C +$GPGSV,3,1,12,03,67,250,24,06,72,219,21,08,07,331,24,14,06,151,*7F +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,23*79 +$GPGSV,3,3,12,21,32,087,47,22,67,156,25,24,01,085,39,26,18,130,33*7F +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":24,"used":false},{"PRN":6,"el":72,"az":219,"ss":21,"used":false},{"PRN":8,"el":7,"az":331,"ss":24,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":23,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":25,"used":false},{"PRN":24,"el":1,"az":85,"ss":39,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.17111,N,02730.02927,E,085122.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1265359882.000,"ept":0.005,"lat":53.919518500,"lon":27.500487833,"alt":250.600,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.009,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085123.00,A,5355.17101,N,02730.02965,E,0.039,,050210,,,A*7F +$GPVTG,,T,,M,0.039,N,0.073,K,A*2D +$GPGGA,085123.00,5355.17101,N,02730.02965,E,1,04,4.98,250.9,M,25.0,M,,*57 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.27*0C +$GPGSV,3,1,12,03,67,250,25,06,72,219,21,08,07,331,24,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,24*7D +$GPGSV,3,3,12,21,32,087,47,22,67,156,26,24,01,085,40,26,18,130,32*73 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":25,"used":false},{"PRN":6,"el":72,"az":219,"ss":21,"used":false},{"PRN":8,"el":7,"az":331,"ss":24,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":24,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":26,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":32,"used":true}]} +$GPGLL,5355.17101,N,02730.02965,E,085123.00,A,A*6A +{"class":"TPV","tag":"GLL","time":1265359883.000,"ept":0.005,"lat":53.919516833,"lon":27.500494167,"alt":250.900,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.020,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085124.00,A,5355.17091,N,02730.03002,E,0.131,,050210,,,A*70 +$GPVTG,,T,,M,0.131,N,0.242,K,A*24 +$GPGGA,085124.00,5355.17091,N,02730.03002,E,1,04,4.98,251.1,M,25.0,M,,*58 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.27*0C +$GPGSV,3,1,12,03,67,250,26,06,72,219,20,08,07,331,25,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,24*7D +$GPGSV,3,3,12,21,32,087,47,22,67,156,28,24,01,085,40,26,18,130,31*7E +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":20,"used":false},{"PRN":8,"el":7,"az":331,"ss":25,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":24,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":28,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":31,"used":true}]} +$GPGLL,5355.17091,N,02730.03002,E,085124.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1265359884.000,"ept":0.005,"lat":53.919515167,"lon":27.500500333,"alt":251.100,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.067,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085125.00,A,5355.17079,N,02730.03028,E,0.136,,050210,,,A*78 +$GPVTG,,T,,M,0.136,N,0.252,K,A*22 +$GPGGA,085125.00,5355.17079,N,02730.03028,E,1,04,4.98,251.3,M,25.0,M,,*55 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.27*0C +$GPGSV,3,1,12,03,67,250,26,06,72,219,19,08,07,331,26,14,06,151,*74 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,25*7C +$GPGSV,3,3,12,21,32,087,47,22,67,156,29,24,01,085,41,26,18,130,30*7F +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":19,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":25,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":29,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":30,"used":true}]} +$GPGLL,5355.17079,N,02730.03028,E,085125.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1265359885.000,"ept":0.005,"lat":53.919513167,"lon":27.500504667,"alt":251.300,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.070,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085126.00,A,5355.17068,N,02730.03037,E,0.132,,050210,,,A*71 +$GPVTG,,T,,M,0.132,N,0.245,K,A*20 +$GPGGA,085126.00,5355.17068,N,02730.03037,E,1,04,4.98,251.3,M,25.0,M,,*58 +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.28*03 +$GPGSV,3,1,12,03,67,250,27,06,72,219,18,08,07,331,26,14,06,151,*74 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,25*7C +$GPGSV,3,3,12,21,32,087,47,22,67,156,29,24,01,085,41,26,18,130,29*77 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":27,"used":false},{"PRN":6,"el":72,"az":219,"ss":18,"used":false},{"PRN":8,"el":7,"az":331,"ss":26,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":25,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":29,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":29,"used":true}]} +$GPGLL,5355.17068,N,02730.03037,E,085126.00,A,A*6E +{"class":"TPV","tag":"GLL","time":1265359886.000,"ept":0.005,"lat":53.919511333,"lon":27.500506167,"alt":251.300,"epx":165.547,"epy":92.497,"epv":121.175,"track":0.0000,"speed":0.068,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085127.00,A,5355.17058,N,02730.03017,E,0.288,297.97,050210,,,A*6F +$GPVTG,297.97,T,,M,0.288,N,0.533,K,A*38 +$GPGGA,085127.00,5355.17058,N,02730.03017,E,1,04,4.98,251.1,M,25.0,M,,*5A +$GPGSA,A,3,18,21,26,15,,,,,,,,,5.47,4.98,2.28*03 +$GPGSV,3,1,12,03,67,250,26,06,72,219,17,08,07,331,27,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,25*7D +$GPGSV,3,3,12,21,32,087,48,22,67,156,29,24,01,085,41,26,18,130,27*76 +{"class":"SKY","tag":"GSV","xdop":11.04,"ydop":6.17,"vdop":5.27,"tdop":0.99,"hdop":12.64,"gdop":13.73,"pdop":13.70,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":17,"used":false},{"PRN":8,"el":7,"az":331,"ss":27,"used":false},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":25,"used":false},{"PRN":21,"el":32,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":156,"ss":29,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":27,"used":true}]} +$GPGLL,5355.17058,N,02730.03017,E,085127.00,A,A*6E +{"class":"TPV","tag":"GLL","time":1265359887.000,"ept":0.005,"lat":53.919509667,"lon":27.500502833,"alt":251.100,"epx":165.547,"epy":92.497,"epv":121.175,"track":297.9700,"speed":0.148,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085128.00,A,5355.17046,N,02730.02966,E,0.498,294.00,050210,,,A*6B +$GPVTG,294.00,T,,M,0.498,N,0.922,K,A*3E +$GPGGA,085128.00,5355.17046,N,02730.02966,E,1,05,1.79,250.8,M,25.0,M,,*57 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.22*01 +$GPGSV,3,1,12,03,67,250,25,06,72,219,15,08,07,330,27,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,25*7E +$GPGSV,3,3,12,21,32,087,48,22,67,156,29,24,01,085,41,26,18,130,26*77 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":25,"used":false},{"PRN":6,"el":72,"az":219,"ss":15,"used":false},{"PRN":8,"el":7,"az":330,"ss":27,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":25,"used":false},{"PRN":21,"el":32,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":156,"ss":29,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":26,"used":true}]} +$GPGLL,5355.17046,N,02730.02966,E,085128.00,A,A*60 +{"class":"TPV","tag":"GLL","time":1265359888.000,"ept":0.005,"lat":53.919507667,"lon":27.500494333,"alt":250.800,"epx":165.547,"epy":92.497,"epv":121.175,"track":294.0000,"speed":0.256,"climb":0.000,"eps":331.09,"mode":3} +$GPRMC,085129.00,A,5355.17034,N,02730.02913,E,0.588,290.28,050210,,,A*63 +$GPVTG,290.28,T,,M,0.588,N,1.090,K,A*31 +$GPGGA,085129.00,5355.17034,N,02730.02913,E,1,05,1.79,250.6,M,25.0,M,,*5F +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.22*01 +$GPGSV,3,1,12,03,67,250,24,06,72,219,12,08,07,330,28,14,06,151,*72 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,46,19,48,295,25*7D +$GPGSV,3,3,12,21,32,087,49,22,67,156,28,24,01,085,41,26,18,130,28*79 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":24,"used":false},{"PRN":6,"el":72,"az":219,"ss":12,"used":false},{"PRN":8,"el":7,"az":330,"ss":28,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":25,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":28,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":28,"used":true}]} +$GPGLL,5355.17034,N,02730.02913,E,085129.00,A,A*66 +{"class":"TPV","tag":"GLL","time":1265359889.000,"ept":0.005,"lat":53.919505667,"lon":27.500485500,"alt":250.600,"epx":19.374,"epy":11.485,"epv":33.380,"track":290.2800,"speed":0.302,"climb":0.000,"eps":184.92,"mode":3} +$GPRMC,085130.00,A,5355.17020,N,02730.02862,E,0.658,286.77,050210,,,A*6A +$GPVTG,286.77,T,,M,0.658,N,1.219,K,A*31 +$GPGGA,085130.00,5355.17020,N,02730.02862,E,1,05,1.79,250.3,M,25.0,M,,*50 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.22*01 +$GPGSV,3,1,12,03,67,250,24,06,72,219,13,08,07,330,28,14,06,151,*73 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,25*7F +$GPGSV,3,3,12,21,32,087,49,22,67,156,28,24,01,085,40,26,18,130,29*79 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":24,"used":false},{"PRN":6,"el":72,"az":219,"ss":13,"used":false},{"PRN":8,"el":7,"az":330,"ss":28,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":25,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":28,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":29,"used":true}]} +$GPGLL,5355.17020,N,02730.02862,E,085130.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1265359890.000,"ept":0.005,"lat":53.919503333,"lon":27.500477000,"alt":250.300,"epx":19.374,"epy":11.485,"epv":33.380,"track":286.7700,"speed":0.339,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085131.00,A,5355.17009,N,02730.02821,E,0.658,283.54,050210,,,A*63 +$GPVTG,283.54,T,,M,0.658,N,1.219,K,A*35 +$GPGGA,085131.00,5355.17009,N,02730.02821,E,1,05,1.79,250.1,M,25.0,M,,*5F +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,17,08,07,330,27,14,06,151,*7A +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,25*7C +$GPGSV,3,3,12,21,32,087,49,22,67,156,27,24,01,085,41,26,18,130,30*7F +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":17,"used":false},{"PRN":8,"el":7,"az":330,"ss":27,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":25,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":30,"used":true}]} +$GPGLL,5355.17009,N,02730.02821,E,085131.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1265359891.000,"ept":0.005,"lat":53.919501500,"lon":27.500470167,"alt":250.100,"epx":19.374,"epy":11.485,"epv":33.380,"track":283.5400,"speed":0.339,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085132.00,A,5355.16991,N,02730.02767,E,0.997,280.53,050210,,,A*6C +$GPVTG,280.53,T,,M,0.997,N,1.848,K,A*33 +$GPGGA,085132.00,5355.16991,N,02730.02767,E,1,05,1.79,249.8,M,25.0,M,,*59 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,27,06,72,219,20,08,07,330,26,14,06,151,*7E +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,24*7D +$GPGSV,3,3,12,21,32,087,49,22,67,156,27,24,01,085,41,26,18,130,35*7A +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":27,"used":false},{"PRN":6,"el":72,"az":219,"ss":20,"used":false},{"PRN":8,"el":7,"az":330,"ss":26,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":24,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.16991,N,02730.02767,E,085132.00,A,A*66 +{"class":"TPV","tag":"GLL","time":1265359892.000,"ept":0.005,"lat":53.919498500,"lon":27.500461167,"alt":249.800,"epx":19.374,"epy":11.485,"epv":33.380,"track":280.5300,"speed":0.513,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085133.00,A,5355.16972,N,02730.02710,E,1.137,277.73,050210,,,A*69 +$GPVTG,277.73,T,,M,1.137,N,2.107,K,A*3B +$GPGGA,085133.00,5355.16972,N,02730.02710,E,1,05,1.79,249.6,M,25.0,M,,*5B +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,27,06,72,219,19,08,07,330,25,14,06,151,*77 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,23*78 +$GPGSV,3,3,12,21,32,087,48,22,67,156,26,24,01,085,39,26,18,130,34*74 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":27,"used":false},{"PRN":6,"el":72,"az":219,"ss":19,"used":false},{"PRN":8,"el":7,"az":330,"ss":25,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":23,"used":false},{"PRN":21,"el":32,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":156,"ss":26,"used":false},{"PRN":24,"el":1,"az":85,"ss":39,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.16972,N,02730.02710,E,085133.00,A,A*6A +{"class":"TPV","tag":"GLL","time":1265359893.000,"ept":0.005,"lat":53.919495333,"lon":27.500451667,"alt":249.600,"epx":19.374,"epy":11.485,"epv":33.380,"track":277.7300,"speed":0.585,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085134.00,A,5355.16953,N,02730.02655,E,1.016,275.06,050210,,,A*6F +$GPVTG,275.06,T,,M,1.016,N,1.882,K,A*3E +$GPGGA,085134.00,5355.16953,N,02730.02655,E,1,05,1.79,249.3,M,25.0,M,,*5A +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,16,08,07,330,23,14,06,151,*7F +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,21*78 +$GPGSV,3,3,12,21,32,087,49,22,67,156,26,24,01,085,41,26,18,130,35*7B +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":16,"used":false},{"PRN":8,"el":7,"az":330,"ss":23,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":21,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":26,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.16953,N,02730.02655,E,085134.00,A,A*6E +{"class":"TPV","tag":"GLL","time":1265359894.000,"ept":0.005,"lat":53.919492167,"lon":27.500442500,"alt":249.300,"epx":19.374,"epy":11.485,"epv":33.380,"track":275.0600,"speed":0.523,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085135.00,A,5355.16935,N,02730.02610,E,0.860,272.53,050210,,,A*60 +$GPVTG,272.53,T,,M,0.860,N,1.594,K,A*3B +$GPGGA,085135.00,5355.16935,N,02730.02610,E,1,05,1.79,249.1,M,25.0,M,,*58 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,23,06,72,219,15,08,07,330,22,14,06,151,*78 +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,45,19,48,295,19*76 +$GPGSV,3,3,12,21,32,087,48,22,67,156,26,24,01,085,41,26,18,130,35*7A +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":23,"used":false},{"PRN":6,"el":72,"az":219,"ss":15,"used":false},{"PRN":8,"el":7,"az":330,"ss":22,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":19,"used":false},{"PRN":21,"el":32,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":156,"ss":26,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.16935,N,02730.02610,E,085135.00,A,A*6E +{"class":"TPV","tag":"GLL","time":1265359895.000,"ept":0.005,"lat":53.919489167,"lon":27.500435000,"alt":249.100,"epx":19.374,"epy":11.485,"epv":33.380,"track":272.5300,"speed":0.442,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085136.00,A,5355.16958,N,02730.02675,E,0.386,270.33,050210,,,A*6C +$GPVTG,270.33,T,,M,0.386,N,0.715,K,A*36 +$GPGGA,085136.00,5355.16958,N,02730.02675,E,1,05,1.79,249.7,M,25.0,M,,*55 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,17,08,07,330,21,14,06,151,*78 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,18*72 +$GPGSV,3,3,12,21,32,087,50,22,67,156,27,24,01,085,42,26,18,130,36*72 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":17,"used":false},{"PRN":8,"el":7,"az":330,"ss":21,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":18,"used":false},{"PRN":21,"el":32,"az":87,"ss":50,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":36,"used":true}]} +$GPGLL,5355.16958,N,02730.02675,E,085136.00,A,A*65 +{"class":"TPV","tag":"GLL","time":1265359896.000,"ept":0.005,"lat":53.919493000,"lon":27.500445833,"alt":249.700,"epx":19.374,"epy":11.485,"epv":33.380,"track":270.3300,"speed":0.199,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085137.00,A,5355.16951,N,02730.02661,E,0.151,,050210,,,A*72 +$GPVTG,,T,,M,0.151,N,0.280,K,A*2C +$GPGGA,085137.00,5355.16951,N,02730.02661,E,1,05,1.79,249.6,M,25.0,M,,*59 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,20,08,07,330,20,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,19*73 +$GPGSV,3,3,12,21,32,087,50,22,67,156,27,24,01,085,42,26,18,130,36*72 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":20,"used":false},{"PRN":8,"el":7,"az":330,"ss":20,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":19,"used":false},{"PRN":21,"el":32,"az":87,"ss":50,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":36,"used":true}]} +$GPGLL,5355.16951,N,02730.02661,E,085137.00,A,A*68 +{"class":"TPV","tag":"GLL","time":1265359897.000,"ept":0.005,"lat":53.919491833,"lon":27.500443500,"alt":249.600,"epx":19.374,"epy":11.485,"epv":33.380,"track":0.0000,"speed":0.078,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085138.00,A,5355.16944,N,02730.02634,E,0.523,279.74,050210,,,A*69 +$GPVTG,279.74,T,,M,0.523,N,0.970,K,A*38 +$GPGGA,085138.00,5355.16944,N,02730.02634,E,1,05,1.79,249.5,M,25.0,M,,*51 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,20,08,07,330,18,14,06,151,*72 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,19*73 +$GPGSV,3,3,12,21,32,087,49,22,67,156,27,24,01,085,42,26,18,130,37*7B +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":20,"used":false},{"PRN":8,"el":7,"az":330,"ss":18,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":19,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":37,"used":true}]} +$GPGLL,5355.16944,N,02730.02634,E,085138.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1265359898.000,"ept":0.005,"lat":53.919490667,"lon":27.500439000,"alt":249.500,"epx":19.374,"epy":11.485,"epv":33.380,"track":279.7400,"speed":0.269,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085139.00,A,5355.16947,N,02730.02631,E,0.955,288.42,050210,,,A*68 +$GPVTG,288.42,T,,M,0.955,N,1.769,K,A*39 +$GPGGA,085139.00,5355.16947,N,02730.02631,E,1,05,1.79,249.7,M,25.0,M,,*54 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,17,08,07,330,18,14,06,151,*76 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,19*73 +$GPGSV,3,3,12,21,32,087,50,22,67,156,26,24,01,085,42,26,18,130,37*72 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":17,"used":false},{"PRN":8,"el":7,"az":330,"ss":18,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":19,"used":false},{"PRN":21,"el":32,"az":87,"ss":50,"used":true},{"PRN":22,"el":67,"az":156,"ss":26,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":37,"used":true}]} +$GPGLL,5355.16947,N,02730.02631,E,085139.00,A,A*64 +{"class":"TPV","tag":"GLL","time":1265359899.000,"ept":0.005,"lat":53.919491167,"lon":27.500438500,"alt":249.700,"epx":19.374,"epy":11.485,"epv":33.380,"track":288.4200,"speed":0.491,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085140.00,A,5355.16953,N,02730.02634,E,1.209,296.51,050210,,,A*68 +$GPVTG,296.51,T,,M,1.209,N,2.240,K,A*3A +$GPGGA,085140.00,5355.16953,N,02730.02634,E,1,05,1.79,249.8,M,25.0,M,,*55 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,27,06,72,219,12,08,07,330,18,14,06,151,*72 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,46,19,48,295,19*73 +$GPGSV,3,3,12,21,32,087,49,22,67,156,25,24,01,085,42,26,18,130,37*79 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":27,"used":false},{"PRN":6,"el":72,"az":219,"ss":12,"used":false},{"PRN":8,"el":7,"az":330,"ss":18,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":19,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":25,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":37,"used":true}]} +$GPGLL,5355.16953,N,02730.02634,E,085140.00,A,A*6A +{"class":"TPV","tag":"GLL","time":1265359900.000,"ept":0.005,"lat":53.919492167,"lon":27.500439000,"alt":249.800,"epx":19.374,"epy":11.485,"epv":33.380,"track":296.5100,"speed":0.622,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085141.00,A,5355.16952,N,02730.02616,E,1.203,304.08,050210,,,A*64 +$GPVTG,304.08,T,,M,1.203,N,2.230,K,A*31 +$GPGGA,085141.00,5355.16952,N,02730.02616,E,1,05,1.79,249.9,M,25.0,M,,*54 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,28,06,72,219,12,08,07,330,18,14,06,151,*7D +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,19*70 +$GPGSV,3,3,12,21,32,087,49,22,67,156,22,24,01,085,43,26,18,130,38*70 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":28,"used":false},{"PRN":6,"el":72,"az":219,"ss":12,"used":false},{"PRN":8,"el":7,"az":330,"ss":18,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":19,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":22,"used":false},{"PRN":24,"el":1,"az":85,"ss":43,"used":false},{"PRN":26,"el":18,"az":130,"ss":38,"used":true}]} +$GPGLL,5355.16952,N,02730.02616,E,085141.00,A,A*6A +{"class":"TPV","tag":"GLL","time":1265359901.000,"ept":0.005,"lat":53.919492000,"lon":27.500436000,"alt":249.900,"epx":19.374,"epy":11.485,"epv":33.380,"track":304.0800,"speed":0.619,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085142.00,A,5355.16901,N,02730.02472,E,0.382,311.88,050210,,,A*64 +$GPVTG,311.88,T,,M,0.382,N,0.707,K,A*37 +$GPGGA,085142.00,5355.16901,N,02730.02472,E,1,05,1.79,249.0,M,25.0,M,,*58 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,26,06,72,219,17,08,07,330,19,14,06,151,*77 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,19*70 +$GPGSV,3,3,12,21,32,087,49,22,67,156,,24,01,085,42,26,18,130,38*71 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":26,"used":false},{"PRN":6,"el":72,"az":219,"ss":17,"used":false},{"PRN":8,"el":7,"az":330,"ss":19,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":19,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":38,"used":true}]} +$GPGLL,5355.16901,N,02730.02472,E,085142.00,A,A*6F +{"class":"TPV","tag":"GLL","time":1265359902.000,"ept":0.005,"lat":53.919483500,"lon":27.500412000,"alt":249.000,"epx":19.374,"epy":11.485,"epv":33.380,"track":311.8800,"speed":0.197,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085143.00,A,5355.16896,N,02730.02443,E,0.211,319.01,050210,,,A*6A +$GPVTG,319.01,T,,M,0.211,N,0.392,K,A*3D +$GPGGA,085143.00,5355.16896,N,02730.02443,E,1,05,1.79,249.1,M,25.0,M,,*55 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,25,06,72,219,21,08,07,330,20,14,06,151,*7B +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,19*70 +$GPGSV,3,3,12,21,32,087,49,22,67,156,,24,01,085,42,26,18,130,37*7E +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":25,"used":false},{"PRN":6,"el":72,"az":219,"ss":21,"used":false},{"PRN":8,"el":7,"az":330,"ss":20,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":19,"used":false},{"PRN":21,"el":32,"az":87,"ss":49,"used":true},{"PRN":22,"el":67,"az":156,"ss":0,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":37,"used":true}]} +$GPGLL,5355.16896,N,02730.02443,E,085143.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1265359903.000,"ept":0.005,"lat":53.919482667,"lon":27.500407167,"alt":249.100,"epx":19.374,"epy":11.485,"epv":33.380,"track":319.0100,"speed":0.109,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085144.00,A,5355.16895,N,02730.02431,E,0.186,,050210,,,A*72 +$GPVTG,,T,,M,0.186,N,0.345,K,A*2E +$GPGGA,085144.00,5355.16895,N,02730.02431,E,1,05,1.79,249.3,M,25.0,M,,*56 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,23,08,07,330,21,14,06,151,*7F +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,21*7B +$GPGSV,3,3,12,21,32,087,48,22,67,156,27,24,01,085,42,26,18,130,37*7A +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.45,"tdop":0.83,"hdop":1.50,"gdop":2.25,"pdop":2.09,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":23,"used":false},{"PRN":8,"el":7,"az":330,"ss":21,"used":true},{"PRN":14,"el":6,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":21,"used":false},{"PRN":21,"el":32,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":37,"used":true}]} +$GPGLL,5355.16895,N,02730.02431,E,085144.00,A,A*62 +{"class":"TPV","tag":"GLL","time":1265359904.000,"ept":0.005,"lat":53.919482500,"lon":27.500405167,"alt":249.300,"epx":19.374,"epy":11.485,"epv":33.380,"track":0.0000,"speed":0.096,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085145.00,A,5355.16894,N,02730.02410,E,0.409,314.01,050210,,,A*6A +$GPVTG,314.01,T,,M,0.409,N,0.758,K,A*3D +$GPGGA,085145.00,5355.16894,N,02730.02410,E,1,05,1.79,249.3,M,25.0,M,,*55 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,23,08,07,330,21,14,07,151,*7E +$GPGSV,3,2,12,15,14,032,43,16,14,204,,18,55,073,44,19,48,295,21*7C +$GPGSV,3,3,12,21,32,087,47,22,67,156,27,24,01,085,40,26,18,130,36*76 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.47,"tdop":0.84,"hdop":1.50,"gdop":2.27,"pdop":2.10,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":23,"used":false},{"PRN":8,"el":7,"az":330,"ss":21,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":43,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":44,"used":true},{"PRN":19,"el":48,"az":295,"ss":21,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":36,"used":true}]} +$GPGLL,5355.16894,N,02730.02410,E,085145.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1265359905.000,"ept":0.005,"lat":53.919482333,"lon":27.500401667,"alt":249.300,"epx":19.374,"epy":11.485,"epv":33.380,"track":314.0100,"speed":0.210,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085146.00,A,5355.16889,N,02730.02363,E,0.246,309.09,050210,,,A*6F +$GPVTG,309.09,T,,M,0.246,N,0.455,K,A*3A +$GPGGA,085146.00,5355.16889,N,02730.02363,E,1,05,1.79,249.3,M,25.0,M,,*59 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,23,08,07,330,22,14,07,151,*7D +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,44,19,48,295,23*79 +$GPGSV,3,3,12,21,32,087,46,22,67,156,26,24,01,085,40,26,18,130,35*75 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.47,"tdop":0.84,"hdop":1.50,"gdop":2.27,"pdop":2.10,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":23,"used":false},{"PRN":8,"el":7,"az":330,"ss":22,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":44,"used":true},{"PRN":19,"el":48,"az":295,"ss":23,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":26,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.16889,N,02730.02363,E,085146.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1265359906.000,"ept":0.005,"lat":53.919481500,"lon":27.500393833,"alt":249.300,"epx":19.362,"epy":11.581,"epv":33.794,"track":309.0900,"speed":0.127,"climb":0.000,"eps":38.74,"mode":3} +$GPRMC,085147.00,A,5355.16883,N,02730.02334,E,0.023,,050210,,,A*7A +$GPVTG,,T,,M,0.023,N,0.043,K,A*25 +$GPGGA,085147.00,5355.16883,N,02730.02334,E,1,05,1.79,249.3,M,25.0,M,,*50 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,25,08,07,330,24,14,07,151,*7D +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,46,19,48,295,25*7F +$GPGSV,3,3,12,21,32,087,48,22,67,156,26,24,01,085,41,26,18,130,35*7A +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.47,"tdop":0.84,"hdop":1.50,"gdop":2.27,"pdop":2.10,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":25,"used":false},{"PRN":8,"el":7,"az":330,"ss":24,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":46,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":25,"used":false},{"PRN":21,"el":32,"az":87,"ss":48,"used":true},{"PRN":22,"el":67,"az":156,"ss":26,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.16883,N,02730.02334,E,085147.00,A,A*64 +{"class":"TPV","tag":"GLL","time":1265359907.000,"ept":0.005,"lat":53.919480500,"lon":27.500389000,"alt":249.300,"epx":19.362,"epy":11.581,"epv":33.794,"track":0.0000,"speed":0.012,"climb":0.000,"eps":38.72,"mode":3} +$GPRMC,085148.00,A,5355.16875,N,02730.02320,E,0.058,,050210,,,A*75 +$GPVTG,,T,,M,0.058,N,0.107,K,A*28 +$GPGGA,085148.00,5355.16875,N,02730.02320,E,1,05,1.79,249.4,M,25.0,M,,*54 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,25,08,07,330,25,14,07,151,*7C +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,46,19,48,295,26*7C +$GPGSV,3,3,12,21,32,087,47,22,67,156,26,24,01,085,41,26,18,130,35*75 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.47,"tdop":0.84,"hdop":1.50,"gdop":2.27,"pdop":2.10,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":25,"used":false},{"PRN":8,"el":7,"az":330,"ss":25,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":46,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":46,"used":true},{"PRN":19,"el":48,"az":295,"ss":26,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":26,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.16875,N,02730.02320,E,085148.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359908.000,"ept":0.005,"lat":53.919479167,"lon":27.500386667,"alt":249.400,"epx":19.362,"epy":11.581,"epv":33.794,"track":0.0000,"speed":0.030,"climb":0.000,"eps":38.72,"mode":3} +$GPRMC,085149.00,A,5355.16866,N,02730.02314,E,0.346,304.62,050210,,,A*60 +$GPVTG,304.62,T,,M,0.346,N,0.641,K,A*3C +$GPGGA,085149.00,5355.16866,N,02730.02314,E,1,05,1.79,249.4,M,25.0,M,,*50 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,,06,72,219,25,08,07,330,25,14,07,151,*7C +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,26*7C +$GPGSV,3,3,12,21,32,087,47,22,67,156,26,24,01,085,41,26,18,130,34*74 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.47,"tdop":0.84,"hdop":1.50,"gdop":2.27,"pdop":2.10,"satellites":[{"PRN":3,"el":67,"az":250,"ss":0,"used":false},{"PRN":6,"el":72,"az":219,"ss":25,"used":false},{"PRN":8,"el":7,"az":330,"ss":25,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":26,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":26,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.16866,N,02730.02314,E,085149.00,A,A*63 +{"class":"TPV","tag":"GLL","time":1265359909.000,"ept":0.005,"lat":53.919477667,"lon":27.500385667,"alt":249.400,"epx":19.362,"epy":11.581,"epv":33.794,"track":304.6200,"speed":0.178,"climb":0.000,"eps":38.72,"mode":3} +$GPRMC,085150.00,A,5355.16856,N,02730.02311,E,0.506,300.38,050210,,,A*67 +$GPVTG,300.38,T,,M,0.506,N,0.937,K,A*3B +$GPGGA,085150.00,5355.16856,N,02730.02311,E,1,05,1.79,249.5,M,25.0,M,,*5F +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,28,06,72,219,25,08,07,330,25,14,07,151,*76 +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,45,19,48,295,27*7E +$GPGSV,3,3,12,21,32,087,47,22,67,156,27,24,01,085,41,26,18,130,33*72 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.47,"tdop":0.84,"hdop":1.50,"gdop":2.27,"pdop":2.10,"satellites":[{"PRN":3,"el":67,"az":250,"ss":28,"used":false},{"PRN":6,"el":72,"az":219,"ss":25,"used":false},{"PRN":8,"el":7,"az":330,"ss":25,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":46,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":27,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.16856,N,02730.02311,E,085150.00,A,A*6D +{"class":"TPV","tag":"GLL","time":1265359910.000,"ept":0.005,"lat":53.919476000,"lon":27.500385167,"alt":249.500,"epx":19.362,"epy":11.581,"epv":33.794,"track":300.3800,"speed":0.260,"climb":0.000,"eps":38.72,"mode":3} +$GPRMC,085151.00,A,5355.16845,N,02730.02318,E,0.564,296.45,050210,,,A*6D +$GPVTG,296.45,T,,M,0.564,N,1.045,K,A*36 +$GPGGA,085151.00,5355.16845,N,02730.02318,E,1,05,1.79,249.6,M,25.0,M,,*56 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,250,29,06,72,219,24,08,07,330,25,14,07,151,*76 +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,45,19,48,295,26*7F +$GPGSV,3,3,12,21,32,087,46,22,67,156,28,24,01,085,40,26,18,130,32*7C +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.47,"tdop":0.84,"hdop":1.50,"gdop":2.27,"pdop":2.10,"satellites":[{"PRN":3,"el":67,"az":250,"ss":29,"used":false},{"PRN":6,"el":72,"az":219,"ss":24,"used":false},{"PRN":8,"el":7,"az":330,"ss":25,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":46,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":26,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":28,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":32,"used":true}]} +$GPGLL,5355.16845,N,02730.02318,E,085151.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359911.000,"ept":0.005,"lat":53.919474167,"lon":27.500386333,"alt":249.600,"epx":19.362,"epy":11.581,"epv":33.794,"track":296.4500,"speed":0.290,"climb":0.000,"eps":38.72,"mode":3} +$GPRMC,085152.00,A,5355.16838,N,02730.02346,E,0.143,,050210,,,A*7C +$GPVTG,,T,,M,0.143,N,0.265,K,A*24 +$GPGGA,085152.00,5355.16838,N,02730.02346,E,1,05,1.79,249.8,M,25.0,M,,*5A +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,249,29,06,72,219,22,08,07,330,26,14,07,151,*7B +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,45,19,48,295,26*7F +$GPGSV,3,3,12,21,32,087,46,22,67,156,29,24,01,085,40,26,18,130,31*7E +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.47,"tdop":0.84,"hdop":1.50,"gdop":2.27,"pdop":2.10,"satellites":[{"PRN":3,"el":67,"az":249,"ss":29,"used":false},{"PRN":6,"el":72,"az":219,"ss":22,"used":false},{"PRN":8,"el":7,"az":330,"ss":26,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":46,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":26,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":29,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":31,"used":true}]} +$GPGLL,5355.16838,N,02730.02346,E,085152.00,A,A*65 +{"class":"TPV","tag":"GLL","time":1265359912.000,"ept":0.005,"lat":53.919473000,"lon":27.500391000,"alt":249.800,"epx":19.362,"epy":11.581,"epv":33.794,"track":0.0000,"speed":0.074,"climb":0.000,"eps":38.72,"mode":3} +$GPRMC,085153.00,A,5355.16831,N,02730.02377,E,0.025,,050210,,,A*77 +$GPVTG,,T,,M,0.025,N,0.047,K,A*27 +$GPGGA,085153.00,5355.16831,N,02730.02377,E,1,05,1.79,250.0,M,25.0,M,,*50 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,249,29,06,72,219,23,08,07,330,26,14,07,151,*7A +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,45,19,48,295,26*7F +$GPGSV,3,3,12,21,32,087,46,22,67,156,31,24,01,085,40,26,18,130,32*74 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.47,"tdop":0.84,"hdop":1.50,"gdop":2.27,"pdop":2.10,"satellites":[{"PRN":3,"el":67,"az":249,"ss":29,"used":false},{"PRN":6,"el":72,"az":219,"ss":23,"used":false},{"PRN":8,"el":7,"az":330,"ss":26,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":46,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":26,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":31,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":32,"used":true}]} +$GPGLL,5355.16831,N,02730.02377,E,085153.00,A,A*6F +{"class":"TPV","tag":"GLL","time":1265359913.000,"ept":0.005,"lat":53.919471833,"lon":27.500396167,"alt":250.000,"epx":19.366,"epy":11.578,"epv":33.799,"track":0.0000,"speed":0.013,"climb":0.000,"eps":38.73,"mode":3} +$GPRMC,085154.00,A,5355.16823,N,02730.02421,E,0.081,,050210,,,A*79 +$GPVTG,,T,,M,0.081,N,0.150,K,A*2E +$GPGGA,085154.00,5355.16823,N,02730.02421,E,1,05,1.79,250.3,M,25.0,M,,*53 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,249,29,06,72,219,23,08,07,330,26,14,07,151,*7A +$GPGSV,3,2,12,15,14,032,46,16,14,204,,18,55,073,45,19,48,295,25*7C +$GPGSV,3,3,12,21,32,087,46,22,67,156,32,24,01,085,40,26,18,130,32*77 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.47,"tdop":0.84,"hdop":1.50,"gdop":2.27,"pdop":2.10,"satellites":[{"PRN":3,"el":67,"az":249,"ss":29,"used":false},{"PRN":6,"el":72,"az":219,"ss":23,"used":false},{"PRN":8,"el":7,"az":330,"ss":26,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":46,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":25,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":32,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":32,"used":true}]} +$GPGLL,5355.16823,N,02730.02421,E,085154.00,A,A*6F +{"class":"TPV","tag":"GLL","time":1265359914.000,"ept":0.005,"lat":53.919470500,"lon":27.500403500,"alt":250.300,"epx":19.366,"epy":11.578,"epv":33.799,"track":0.0000,"speed":0.042,"climb":0.000,"eps":38.73,"mode":3} +$GPRMC,085155.00,A,5355.16818,N,02730.02469,E,0.187,,050210,,,A*7B +$GPVTG,,T,,M,0.187,N,0.347,K,A*2D +$GPGGA,085155.00,5355.16818,N,02730.02469,E,1,05,1.79,250.5,M,25.0,M,,*50 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.23*00 +$GPGSV,3,1,12,03,67,249,29,06,71,217,22,08,07,330,26,14,07,151,*76 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,25*7F +$GPGSV,3,3,12,21,32,087,46,22,67,156,31,24,01,085,40,26,18,130,31*77 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.48,"tdop":0.85,"hdop":1.50,"gdop":2.27,"pdop":2.11,"satellites":[{"PRN":3,"el":67,"az":249,"ss":29,"used":false},{"PRN":6,"el":71,"az":217,"ss":22,"used":false},{"PRN":8,"el":7,"az":330,"ss":26,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":25,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":31,"used":false},{"PRN":24,"el":1,"az":85,"ss":40,"used":false},{"PRN":26,"el":18,"az":130,"ss":31,"used":true}]} +$GPGLL,5355.16818,N,02730.02469,E,085155.00,A,A*6A +{"class":"TPV","tag":"GLL","time":1265359915.000,"ept":0.005,"lat":53.919469667,"lon":27.500411500,"alt":250.500,"epx":19.366,"epy":11.578,"epv":33.799,"track":0.0000,"speed":0.096,"climb":0.000,"eps":38.73,"mode":3} +$GPRMC,085156.00,A,5355.16811,N,02730.02486,E,0.011,,050210,,,A*7E +$GPVTG,,T,,M,0.011,N,0.020,K,A*21 +$GPGGA,085156.00,5355.16811,N,02730.02486,E,1,05,1.79,250.7,M,25.0,M,,*59 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.24*07 +$GPGSV,3,1,12,03,67,249,28,06,71,217,20,08,07,330,26,14,07,151,*75 +$GPGSV,3,2,12,15,14,032,45,16,14,204,,18,55,073,45,19,48,295,24*7E +$GPGSV,3,3,12,21,32,087,46,22,67,156,30,24,01,085,41,26,18,130,32*74 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.48,"tdop":0.85,"hdop":1.50,"gdop":2.27,"pdop":2.11,"satellites":[{"PRN":3,"el":67,"az":249,"ss":28,"used":false},{"PRN":6,"el":71,"az":217,"ss":20,"used":false},{"PRN":8,"el":7,"az":330,"ss":26,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":45,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":24,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":30,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":32,"used":true}]} +$GPGLL,5355.16811,N,02730.02486,E,085156.00,A,A*61 +{"class":"TPV","tag":"GLL","time":1265359916.000,"ept":0.005,"lat":53.919468500,"lon":27.500414333,"alt":250.700,"epx":19.377,"epy":11.569,"epv":34.049,"track":0.0000,"speed":0.006,"climb":0.000,"eps":38.74,"mode":3} +$GPRMC,085157.00,A,5355.16805,N,02730.02498,E,0.183,,050210,,,A*7F +$GPVTG,,T,,M,0.183,N,0.339,K,A*20 +$GPGGA,085157.00,5355.16805,N,02730.02498,E,1,05,1.79,250.7,M,25.0,M,,*52 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.24*07 +$GPGSV,3,1,12,03,67,249,28,06,71,217,18,08,07,330,26,14,07,151,*7E +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,23*78 +$GPGSV,3,3,12,21,32,087,46,22,67,156,29,24,01,085,41,26,18,130,33*7D +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.48,"tdop":0.85,"hdop":1.50,"gdop":2.27,"pdop":2.11,"satellites":[{"PRN":3,"el":67,"az":249,"ss":28,"used":false},{"PRN":6,"el":71,"az":217,"ss":18,"used":false},{"PRN":8,"el":7,"az":330,"ss":26,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":23,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":29,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.16805,N,02730.02498,E,085157.00,A,A*6A +{"class":"TPV","tag":"GLL","time":1265359917.000,"ept":0.005,"lat":53.919467500,"lon":27.500416333,"alt":250.700,"epx":19.377,"epy":11.569,"epv":34.049,"track":0.0000,"speed":0.094,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085158.00,A,5355.16801,N,02730.02510,E,0.258,292.57,050210,,,A*65 +$GPVTG,292.57,T,,M,0.258,N,0.478,K,A*32 +$GPGGA,085158.00,5355.16801,N,02730.02510,E,1,05,1.79,250.8,M,25.0,M,,*57 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.24*07 +$GPGSV,3,1,12,03,67,249,27,06,71,217,16,08,07,330,25,14,07,151,*7C +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,22*79 +$GPGSV,3,3,12,21,32,087,46,22,67,156,28,24,01,085,41,26,18,130,33*7C +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.48,"tdop":0.85,"hdop":1.50,"gdop":2.27,"pdop":2.11,"satellites":[{"PRN":3,"el":67,"az":249,"ss":27,"used":false},{"PRN":6,"el":71,"az":217,"ss":16,"used":false},{"PRN":8,"el":7,"az":330,"ss":25,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":22,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":28,"used":false},{"PRN":24,"el":1,"az":85,"ss":41,"used":false},{"PRN":26,"el":18,"az":130,"ss":33,"used":true}]} +$GPGLL,5355.16801,N,02730.02510,E,085158.00,A,A*60 +{"class":"TPV","tag":"GLL","time":1265359918.000,"ept":0.005,"lat":53.919466833,"lon":27.500418333,"alt":250.800,"epx":19.377,"epy":11.569,"epv":34.049,"track":292.5700,"speed":0.133,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085159.00,A,5355.16799,N,02730.02518,E,0.364,289.04,050210,,,A*60 +$GPVTG,289.04,T,,M,0.364,N,0.675,K,A*3F +$GPGGA,085159.00,5355.16799,N,02730.02518,E,1,05,1.79,250.9,M,25.0,M,,*51 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.24*07 +$GPGSV,3,1,12,03,67,249,27,06,71,217,13,08,07,330,24,14,07,151,*78 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,20*7B +$GPGSV,3,3,12,21,32,087,46,22,67,156,27,24,01,085,42,26,18,130,34*77 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.48,"tdop":0.85,"hdop":1.50,"gdop":2.27,"pdop":2.11,"satellites":[{"PRN":3,"el":67,"az":249,"ss":27,"used":false},{"PRN":6,"el":71,"az":217,"ss":13,"used":false},{"PRN":8,"el":7,"az":330,"ss":24,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":20,"used":false},{"PRN":21,"el":32,"az":87,"ss":46,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":34,"used":true}]} +$GPGLL,5355.16799,N,02730.02518,E,085159.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359919.000,"ept":0.005,"lat":53.919466500,"lon":27.500419667,"alt":250.900,"epx":19.377,"epy":11.569,"epv":34.049,"track":289.0400,"speed":0.187,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085200.00,A,5355.16797,N,02730.02521,E,0.225,285.42,050210,,,A*61 +$GPVTG,285.42,T,,M,0.225,N,0.417,K,A*33 +$GPGGA,085200.00,5355.16797,N,02730.02521,E,1,05,1.79,251.0,M,25.0,M,,*52 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.86,1.79,2.24*07 +$GPGSV,3,1,12,03,67,249,28,06,71,217,14,08,07,330,23,14,07,151,*77 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,19*71 +$GPGSV,3,3,12,21,32,087,47,22,67,156,27,24,01,085,42,26,18,130,35*77 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.48,"tdop":0.85,"hdop":1.50,"gdop":2.27,"pdop":2.11,"satellites":[{"PRN":3,"el":67,"az":249,"ss":28,"used":false},{"PRN":6,"el":71,"az":217,"ss":14,"used":false},{"PRN":8,"el":7,"az":330,"ss":23,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":19,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.16797,N,02730.02521,E,085200.00,A,A*6C +{"class":"TPV","tag":"GLL","time":1265359920.000,"ept":0.005,"lat":53.919466167,"lon":27.500420167,"alt":251.000,"epx":19.377,"epy":11.569,"epv":34.049,"track":285.4200,"speed":0.116,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085201.00,A,5355.16798,N,02730.02524,E,0.256,282.12,050210,,,A*6C +$GPVTG,282.12,T,,M,0.256,N,0.474,K,A*30 +$GPGGA,085201.00,5355.16798,N,02730.02524,E,1,05,1.79,251.1,M,25.0,M,,*58 +$GPGSA,A,3,18,21,08,26,15,,,,,,,,2.87,1.79,2.24*06 +$GPGSV,3,1,12,03,67,249,29,06,71,217,16,08,07,330,21,14,07,151,*76 +$GPGSV,3,2,12,15,14,032,44,16,14,204,,18,55,073,45,19,48,295,16*7E +$GPGSV,3,3,12,21,32,087,47,22,67,156,27,24,01,085,42,26,18,130,35*77 +{"class":"SKY","tag":"GSV","xdop":1.29,"ydop":0.77,"vdop":1.48,"tdop":0.85,"hdop":1.50,"gdop":2.27,"pdop":2.11,"satellites":[{"PRN":3,"el":67,"az":249,"ss":29,"used":false},{"PRN":6,"el":71,"az":217,"ss":16,"used":false},{"PRN":8,"el":7,"az":330,"ss":21,"used":true},{"PRN":14,"el":7,"az":151,"ss":0,"used":false},{"PRN":15,"el":14,"az":32,"ss":44,"used":true},{"PRN":16,"el":14,"az":204,"ss":0,"used":false},{"PRN":18,"el":55,"az":73,"ss":45,"used":true},{"PRN":19,"el":48,"az":295,"ss":16,"used":false},{"PRN":21,"el":32,"az":87,"ss":47,"used":true},{"PRN":22,"el":67,"az":156,"ss":27,"used":false},{"PRN":24,"el":1,"az":85,"ss":42,"used":false},{"PRN":26,"el":18,"az":130,"ss":35,"used":true}]} +$GPGLL,5355.16798,N,02730.02524,E,085201.00,A,A*67 +{"class":"TPV","tag":"GLL","time":1265359921.000,"ept":0.005,"lat":53.919466333,"lon":27.500420667,"alt":251.100,"epx":19.377,"epy":11.569,"epv":34.049,"track":282.1200,"speed":0.132,"climb":0.000,"eps":38.75,"mode":3} +$GPRMC,085202.00,A,5355.16797,N,02730.02521,E,0.079,,050210,,,A*7F diff --git a/test/daemon/zodiac.log b/test/daemon/zodiac.log new file mode 100644 index 0000000000000000000000000000000000000000..61e61c44b06599f7ccb1e76c620060cf9beb7d58 GIT binary patch literal 5686 zcmb{0TWl0n7zgk}+hI$E2C-nddZ2?`((SYb0x75)T0{vJ0wuu&(Y;K&gL}))R9N*v zj1MHf_+W_Qg@_oDAfn?syVr_)pXgSr)WGGX^ojB6|_ETrEJrwqbri(=hvID7+unu zvK%u_*^8NQ%=9}Jdw-1$Ppou;X~&;z_J`Rkb@VazTx%$9IgT0ehcfIiA-W`(ux&Fz z7qq18NMM6KI~a>qC1Q`l;D(^Xjx`HX6129udJa6dG#L&$Rx(jXS2<}j9Ca#bqv=G= zbS#*N*p+lnZR4CpB^5BTDQelY*@~GIe%B{cnY7gsb?Ef)3^-OzH4SAbypJwkzOsR) z(#dsZ*nxK~ghv31+ccO;#o!!m)69*_9jSiV@~59{TuiM*?zxC%J83J_%1(%;lSzj* zC(|@yIzcODSLM#4J{gaj3CFI3Q;5YN!;H}NmJ_83(*X%>wXH-8W%g+{UGYdQ`>@Tb zlI+H&qEbT0)=bfw06Cz;U3dG`DIg=r5O|c$24LLv!Wy`LJyQwe4(o?=Ba7h~L;DU! zvTXzzN_u={WF~olWZSpQzxnDq?dF9|Wb0@`qN8#{NGO}l5^@e6T!DQ*?DNPgQGTxs z9#PnT>C0}sQRs(zH~vfWQVMeC^~^>(USdLsqX(Mb>HRM$GY|# zm%X}+G(!_9gJt(2d-XG{m)(yBe(gc_Qe^H&0JDJ5|D@Q< zCHpqX&W`0=lOB)3WfdRMX&B6&Co>3z;-^*SLNn;Uibd&31mM2Cf>;q z58Ga3e*xLA!?+H;1KAHK_HmM3zTVlf<+@LI?Gxb@3j1ng|J6-1G?6l}o%cMpv%hrt zbuUJC{aMz_5bbVXA^S*VUkc++=qHfCv*EZ$lieLWzPl3N&O_UA6D!WCHoHPdM|>*%RT>6UeC9k_v${{ zO*1r+l5h8ePF~mHp1-}l3$83t_vMhnJDJDX|bKpb^X;nj_iBE#5DtBLxb9xB?jp_5M9RI``5!NfZm;$dU!XJOw}D6Pg~EQV$E&+YGc=KMcXocg_gD9M$bJ<}yptgwHnx5i z_Q#REI20h~^mE95T(M7)>~h`JdH%9%zYkI=>=|SiX@(|J2DYnf8~z;@uj^)z(=e-u zx;KD{cQVAo#@5fmeznl6dn^8y~y6F*dLbcTcoY5C-5Ob0`SWB!%B%VLk;5#nQqn0@fmyRu+P-7GjlO;DVMGf<@Fnp`A?x zOYO9ga9UYN3L(zkI?m)y8&}N0-Rxb$yU)#~9SbC~CQdWRDZQrjuC-6gl6~h{ z=5#`)3YD13DbtvjsdXlE;xvPt^1VqDQ;kYY)zq9OyiD&+nG>fO2p8?4 literal 0 HcmV?d00001 diff --git a/test/geoid.test.chk b/test/geoid.test.chk new file mode 100644 index 0000000..6a5b2e1 --- /dev/null +++ b/test/geoid.test.chk @@ -0,0 +1 @@ + lat= 37.371192 lon= 122.014965 geoid correction= 8.187392 diff --git a/test/packet.test.chk b/test/packet.test.chk new file mode 100644 index 0000000..2f3c8bb --- /dev/null +++ b/test/packet.test.chk @@ -0,0 +1,24 @@ +=== Packet identification tests + === 1: NMEA packet with checksum (1) test succeeded. + 2: NMEA packet with checksum (2) test succeeded. + 3: NMEA packet with checksum and 4 chars of leading garbage test succeeded. + 4: NMEA packet without checksum test succeeded. + 5: NMEA packet with wrong checksum test succeeded. + 6: SiRF WAAS version ID test succeeded. + 7: SiRF WAAS version ID with 3 chars of leading garbage test succeeded. + 8: SiRF WAAS version ID with wrong checksum test succeeded. + 9: SiRF WAAS version ID with bad length test succeeded. +10: Zodiac binary 1000 Geodetic Status Output Message test succeeded. +11: EverMore status packet 0x20 test succeeded. +12: EverMore packet 0x04 with 0x10 0x10 sequence test succeeded. +13: EverMore packet 0x04 with 0x10 0x10 sequence, some noise before packet data test succeeded. +14: EverMore packet 0x04, 0x10 and some other data at the beginning test succeeded. +15: EverMore packet 0x04, 0x10 three times at the beginning test succeeded. +16: RTCM104V3 type 1005 packet test succeeded. +17: RTCM104V3 type 1005 packet with 4th byte garbled test succeeded. +=== EOF with buffer nonempty test === +$GPVTG,308.74,T,,M,0.00,N,0.0,K*68 +$GPGGA,110534.994,4002.1425,N,07531.2585,W,0,00,50.0,172.7,M,-33.8,M,0.0,0000*7A +packet_parse() returned 36 +packet_parse() returned 82 +packet_parse() returned 0 diff --git a/test/sample.aivdm b/test/sample.aivdm new file mode 100644 index 0000000..6420996 --- /dev/null +++ b/test/sample.aivdm @@ -0,0 +1,693 @@ +# Sample AIVDM data sentences provided from real data by Kurt Schwehr +# Mike Greene, Neal Arundale, and AISHub. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +# Type 1: +# From Kurt Schwehr. Dump was attached. Checked using the noaadata tools. +!AIVDM,1,1,,A,15RTgt0PAso;90TKcjM8h6g208CQ,0*4A +# MessageID: 1 +# RepeatIndicator: 0 +# UserID: 371798000 +# NavigationStatus: 0 +# ROT: -127 +# SOG: 12.3 +# PositionAccuracy: 1 +# longitude: -123.395383333 +# latitude: 48.38163333333 +# COG: 224 +# TrueHeading: 215 +# TimeStamp: 33 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 2 +# state_slotoffset: 1249 +# +# Type 1: +# From Kurt Schwehr. Dump was attached. Checked using the noaadata tools. +!AIVDM,1,1,,A,16SteH0P00Jt63hHaa6SagvJ087r,0*42 +# MessageID: 1 +# RepeatIndicator: 0 +# UserID: 440348000 +# NavigationStatus: 0 +# ROT: -128 +# SOG: 0 +# PositionAccuracy: 0 +# longitude: -70.7582 +# latitude: 43.08015 +# COG: 93.4 +# TrueHeading: 511 +# TimeStamp: 13 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# stare_slottimeout: 2 +# state_slotoffset: 506 +# +# Type 2: +# From Kurt Schwehr. Dump was attached. Checked using the noaadata tools. +# I had to regenerate the CRC32 for this one myself, it was missing in +# Kurt's original. +!AIVDM,1,1,,B,25Cjtd0Oj;Jp7ilG7=UkKBoB0<06,0*60 +# MessageID: 2 +# RepeatIndicator: 0 +# UserID: 356302000 +# NavigationStatus: 0 +# ROT: 127 +# SOG: 13.9 +# PositionAccuracy: 0 +# longitude: -71.62614333333333333333333333 +# latitude: 40.39235833333333333333333333 +# COG: 87.7 +# TrueHeading: 91 +# TimeStamp: 41 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 3 +# state_slotoffset: 6 +# +# Type 3: +# From Kurt Schwehr. Dump was attached. Checked using the noaadata tools. +!AIVDM,1,1,,A,38Id705000rRVJhE7cl9n;160000,0*40 +# MessageID: 3 +# RepeatIndicator: 0 +# UserID: 563808000 +# NavigationStatus: 5 +# ROT: 0 +# SOG: 0 +# PositionAccuracy: 1 +# longitude: -76.32753333333333333333333333 +# latitude: 36.91 +# COG: 252 +# TrueHeading: 352 +# TimeStamp: 35 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 0 +# state_slotoffset: 0 +# +# Type 4: +# From Kurt Schwehr. Dump was attached. Checked using the noaadata tools. +!AIVDM,1,1,,A,403OviQuMGCqWrRO9>E6fE700@GO,0*4D +# MessageID: 4 +# RepeatIndicator: 0 +# UserID: 3669702 +# Time_year: 2007 +# Time_month: 5 +# Time_day: 14 +# Time_hour: 19 +# Time_min: 57 +# Time_sec: 39 +# PositionAccuracy: 1 +# Position_longitude: -76.35236166666666666666666667 +# Position_latitude: 36.88376666666666666666666667 +# fixtype: 7 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 4 +# state_slotoffset: 1503 +# +# Type 5: +# From Kurt Schwehr. Dump was attached. Checked using the noaadata tools. +!AIVDM,2,1,1,A,55?MbV02;H;s, seems to be military traffic +# with a mis-entered MMSI. +!AIVDM,2,1,6,A,8>qc9wiKf>d=Cq5r0mdew:?DLq>1LmhHrsqmBCKnJ50,0*30 +!AIVDM,2,2,6,A,3OLc=UCRp,0*4A,b003660465 +# Message Type 8 +# Repeat Indicator 0 +# MMSI 999999999 +# DAC 366 +# FID 22 +# Data 256:eb0d4f917a035b2dfca3d4739381735c18ebbe754936f66850037dcacd9538b8 +# +# Type 9: +# From AISHub. Checked with the noaadata tools. +!AIVDM,1,1,,A,91b77=h3h00nHt0Q3r@@07000<0b,0*69 +# Message Type : 9 +# Repeat Indicator : 0 +# MMSI : 111265591 +# Altitude : 15 +# SOG : 0 +# Position Accuracy : 0 +# Longitude : 7128960 +# Latitude : 34667073 +# Course Over Ground : 0 +# Time Stamp : 28 +# Regional reserved : 0 +# DTE : 0 +# Assigned : 0 +# RAIM flag : 0 +# Radio status : 24597 +# +# Type 10: +# From Kurt Schwehr. Two destination MMSIs. Checked with the noaadata tools. +!AIVDM,1,1,,B,:5MlU41GMK6@,0*6C +# MessageID: 10 +# RepeatIndicator: 0 +# UserID: 366814480 +# Spare1: 0 +# DestID: 366832740 +# Spare2: 0 +# +# Type 10: +# From Mike Greene. One destination MMSI. Decode is known good. +!AIVDM,1,1,,B,:6TMCD1GOS60,0*5B,s36310,d-081,T59.01777335 +# Message Type: 10 +# Repeat Indicator: 0 +# MMSI: 440882000 +# Destination MMSI: 366972000 +# +# Type 11: +# From Kurt Schwehr. Checked with the noaadata tools. +# Message has Coast Guard extended fields following +!AIVDM,1,1,,B,;4R33:1uUK2F`q?mOt@@GoQ00000,0*5D,s28089,d-103,T39.44353985,x147521,r08TPHI1,1242958962 +# MessageID: 11 +# RepeatIndicator: 0 +# UserID: 304137000 +# Time_year: 2009 +# Time_month: 5 +# Time_day: 22 +# Time_hour: 2 +# Time_min: 22 +# Time_sec: 40 +# PositionAccuracy: 1 +# Position_longitude: -94.40768333333333333333333333 +# Position_latitude: 28.40911666666666666666666667 +# fixtype: 1 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 0 +# state_slotoffset: 0 +# +# Type 12: +# From AIS Hub via Neal Arundale. Dumps by ais.py. +# Verified by the text being readable. +!AIVDM,1,1,,A,<02:oP0kKcv0@<51C5PB5@?BDPD?P:?2?EB7PDB16693P381>>5H0,4*4C +# Message Type : 12 +# Repeat Indicator : 0 +# MMSI : 351853000 +# Sequence Number : 1 +# Destination MMSI : 351809000 +# Retransmit flag : 0 +# Text : THANX +!AIVDM,1,1,,A,<42Lati0W:Ov=C7P6B?=Pjoihhjhqq0,2*2B +# Message Type : 12 +# Repeat Indicator : 0 +# MMSI : 271002099 +# Sequence Number : 0 +# Destination MMSI : 271002111 +# Retransmit flag : 1 +# Text : MSG FROM 271002099 +!AIVDM,1,1,,A,9P81?f31<P81@9P>5GPI9BP?5?Per18=HB1U:1@E=B0m3R1p10E3;;R0USCR0HO>0@gN10kGJp,2*7F +# Message Type : 14 +# Repeat Indicator : 0 +# MMSI : 237008900 +# Text : EP228 IX48 FG3 DK7 PL56. +!AIVDM,1,1,,A,>4aDT81@E=@,2*2E +# Message Type : 14 +# Repeat Indicator : 0 +# MMSI : 311764000 +# Text : TEST +# +# Type 15: +# From Mike Greene. This is the 88-bit variant with one MMSI, +# message type and offset. Decode is known good. +!AIVDM,1,1,,A,?5OP=l00052HD00,2*5B +# Message Type: 15 +# Repeat Indicator: 0 +# MMSI: 368578000 +# Destination MMSI: 5158 +# First Message Type: 5 +# First Slot Offset: 0 +# +# Type 15: +# From Kurt Schwehr. This is the 108/112-bit variant with one MMSI and two +# message types. Includes USCG metadata. Decode is known good. +!AIVDM,1,1,,B,?h3Ovn1GP;h00Fc>jpUlNV@ikwpUoP06,0*4C +# MessageID: 18 +# RepeatIndicator: 0 +# UserID: 338087471 +# Reserved1: 0 +# SOG: 0.1 +# PositionAccuracy: 0 +# longitude: -74.07213166666666666666666667 +# latitude: 40.68454 +# COG: 79.6 +# TrueHeading: 511 +# TimeStamp: 49 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: True +# CommStateSelector: 1 +# CommState: 393222 +# Type 18: +# From Kurt Schwehr. Checked with the noaadata tools. +!AIVDM,1,1,,A,B52KB8h006fu`Q6:g1McCwb5oP06,0*00 +# MessageID: 18 +# RepeatIndicator: 0 +# UserID: 338088483 +# Reserved1: 0 +# SOG: 0 +# PositionAccuracy: 0 +# longitude: -70.8111966 +# latitude: 43.11555833 +# COG: 171.6 +# TrueHeading: 511 +# TimeStamp: 20 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: True +# CommStateSelector: 1 +# CommState: 393222 +# Type 18: +# From Kurt Schwehr. Checked with the noaadata tools. +!AIVDM,1,1,,B,B5O6hr00NhWAwwo862PaLELTBJ:V00000000S0D:R220,0*0B +# MessageID: 19 +# RepeatIndicator: 0 +# UserID: 367059850 +# Spare: 0 +# SOG: 8.7 +# PositionAccuracy: 0 +# longitude: -88.8103916667 +# latitude: 29.543695 +# COG: 335.9 +# TrueHeading: 511 +# TimeStamp: 46 +# Spare2: 0 +# name: CAPT.J.RIMES +# shipandcargo: 70 +# dimA: 5 +# dimB: 21 +# dimC: 4 +# dimD: 4 +# fixtype: 1 +# RAIM: False +# DTE: 0 +# Spare3: 0 +# +# Type 20 (1 offset) +# From Mike Greene. Checked with the noaadata tools. +!AIVDM,1,1,,A,Dh3OvjB8IN>4,0*1D +# Message Type: 20 +# Repeat Indicator: 3 +# MMSI: 3669705 +# Offset 1: 2182 +# Reserved Slots 1: 5 +# Timeout 1: 7 +# Increment 1: 225 +# +# Type 20 (3 offsets): +# From Mike Greene. +!AIVDM,1,1,,B,D030p8@2tN?b<`O6DmQO6D0,2*5D +# Message Type: 20 +# Repeat Indicator: 0 +# MMSI: 3160097 +# Offset 1: 47 +# Reserved Slots 1: 1 +# Timeout 1: 7 +# Increment 1: 250 +# Offset 2: 2250 +# Reserved Slots 2: 1 +# Timeout 2: 7 +# Increment 2: 1125 +# Offset 3: 856 +# Reserved Slots 3: 5 +# Timeout 3: 7 +# Increment 3: 1125 +# +# Type 21: +# Has a Name Extension field +# From Mike Greene. Decode is verified by the text being readable. +!AIVDM,2,1,5,B,E1mg=5J1T4W0h97aRh6ba84220o0h:2240Ht50000000000,0*3B +!AIVDM,2,1,2,A,542M92h00001@<7;?G0PD4i@R0220o0h:2240Ht500000000000000,0*3C +!AIVDM,2,2,2,A,0000002,2*24 +!AIVDM,2,2,6,B,00000000000,2*21 diff --git a/test/sample.aivdm.chk b/test/sample.aivdm.chk new file mode 100644 index 0000000..fccce4f --- /dev/null +++ b/test/sample.aivdm.chk @@ -0,0 +1,45 @@ +1|0|371798000|0|-127|123|1|-74037230|29028980|2240|215|33|0x0|0|0x109c2 +1|0|440348000|0|-128|0|0|-42454920|25848090|934|511|13|0x0|0|0x103f4 +2|0|356302000|0|127|139|0|-42975686|24235415|877|91|41|0x0|0|0x1800c +3|0|563808000|5|0|0|1|-45796520|22146000|2520|352|35|0x0|0|0x0 +4|0|003669702|2007-05-14T19:57:39Z|1|-45811417|22130260|7|0|0x105df +5|0|351759000|9134270|0|3FOF8|EVER DIADEM|70|225|70|1|31|1|05-15T14:00Z|122|NEW YORK|0 +6|1|150834090|3|313240222|0|669|11|48:eb2f118f7ff1 +6|0|265538450|0|2655651|0|1|40|16:0000 +7|0|002655651|265538450|0|0|0 +7|1|655901842|158483613|321823389|836359488|0 +7|2|537411077|43101326|717096664|76161024|0 +8|0|366999712|366|22|256:3a53dbb7be4a773137f87d7b0445f040dea05d93f593783194ae9b9d9dbe05fb +8|0|999999999|366|22|256:eb0d4f917a035b2dfca3d4739381735c18ebbe754936f66850037dcacd9538b8 +9|0|111265591|15|0|0|7128960|34667073|0|28|0x0|0|0|0x6015 +10|0|366814480|366832740 +10|0|440882000|366972000 +11|0|304137000|2009-05-22T02:22:40Z|1|-56644610|17045470|1|0|0x0 +12|0|002275200|0|215724000|0|PLEASE REPORT TO JOBOURG TRAFFIC CHANNEL 13 +12|0|351853000|0|316123456|0|GOOD +12|0|351853000|1|351809000|0|THANX +12|0|271002099|0|271002111|1|MSG FROM 271002099 +12|1|237032000|3|2391100|1|EP 531 CARS 80 TRACKS 103 MOTO 5 CREW 86 +12|0|636012668|0|413118000|0|NI HAO.CALL TEST +12|0|211217560|2|211378120|0|GUD PM 2U N HAPI NEW YIR OL D BES FRM AL FUJAIRAH +13|0|211378120|211217560|0|0|0 +14|0|351809000|RCVD YR TEST MSG +14|0|237008900|EP228 IX48 FG3 DK7 PL56. +14|0|311764000|TEST +15|0|368578000|5158|5|0|0|0|0|0|0 +15|3|003669720|367014320|3|516|5|617|0|0|0 +16|0|002053501|224251000|200|0|0|0|0 +17|0|002734450|17478|35992|376:7c0556c07031febbf52924fe33fa2933ffa0fd2932fdb7062922fe3809292afde9122929fcf7002923ffd20c29aaaa +18|0|338087471|0|1|0|-44443279|24410724|796|511|49|0x0|1|0|1|1|1|1|0xe0006 +18|0|338088483|0|0|0|-42486718|25869335|1716|511|20|0x0|1|0|1|1|1|1|0xe0006 +18|0|368161000|0|51|1|-43340309|23688555|349|511|17|0x0|1|0|1|1|0|1|0xe0006 +19|0|367059850|248|87|0|-53286235|17726217|3359|511|46|0x4|CAPT.J.RIMES|70|5|21|4|4|0|0|0|0 +20|3|003669705|2182|5|7|225|0|0|0|0|0|0|0|0|0|0|0|0 +20|0|003160097|47|1|7|250|2250|1|7|1125|856|5|7|1125|0|0|0|0 +21|0|123456789|20|CHINA ROSE MURPHY EXPRESS ALERT|0|-73619155|28752371|5|5|5|5|1|50|165|0x0|0|0 +22|0|003160048|2087|2088|0|0|-44100|27330|-48100|25400|0|0|0|4 +23|0|002268120|1578|30642|1096|30408|6|0|2|9|0 +24|0|271041815|PROGUY|60|1D00014|TC6163|0|15|0|5 +24|0|271040660|GOZDEM-1|37|1C00045|YM5504|0|24|0|6 +5|0|271010059|0|0|TCA2350|HEALTH CONTROL 13|55|6|10|2|2|1|00-00T24:60Z|20||0 +5|0|271010059|0|0|TCA2350|HEALTH CONTROL 13|55|6|10|2|2|1|00-00T24:60Z|20||0 diff --git a/test/sample.rtcm2 b/test/sample.rtcm2 new file mode 100644 index 0000000..0095778 --- /dev/null +++ b/test/sample.rtcm2 @@ -0,0 +1,9 @@ +# Name: RTCM-104 source from a DGPSIP server +# Type: RTCM +# Submitted-by: Wolfgang Rupprecht +# Comments: Has leading garbage, to test parity locking +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +YpgA_]qS@oglgyC|~oAxCJxqBHsDzu_FsHEfOXAdbwg@Es~]ywJ@x]Cxv^[_m_xRrLwzyBXQb`Z[@hMmOzbzjOXU}t_UUUEsHEfOXIfByS@oSpG|cBPAFvtGN}wl`xN@KsHEF}gV^]}g@EAx}~ywwWd\uv^{mrAÁðÜ×ðôÈGmÅÁäÞuLwzyBXye@bdWLhO{bz\pkJCE`jjJHsHEF}gZ\]Kl`_XHF|CNPAGvIxqBHSK{w_BsHEfOXUgB|__WSZ[{Iao~aJB`a@dPUrAsHEfOXM``}[`^yXOE]eVpcJAK`jjjzLwzYpgb[}BlP@lyC|}o^|aIxqBHSeFtÁðÜ×ðôÈÅÁäÞpLwzyBX}bBI`@@mQzZ{I\P~X]O`a@DbZ^CM|LwzYpg\Yq[`~MZKE]eQpMNlO`jjjzLwzYpgL^}Al`W^`F|c{onyNyGN}W^AGuwLwzyBXKeBG`@@leUdDbyouFYAt`}{w[VzG}LwzYpgd\u[`AihtzjZP@\z}G`jjJHsÁðÜ×ðôÈHÅÁäÞEF}gxX}Nl`[B@yC|tonx^}GN}W^FFv_HsHEF}gX_}G`~}SJ[{}oMBGpK_BdzCVxgsLwzyBXwd`x[`aMSeDUeP@lMK`jjjzLwzYpgP]}{S@_l{F|CKPqFjExqBha}yJ@@sHEfOX_fB~_A@e]rZ{]somclvK_BdzygÁðÜ×ðôÈ|ÅÁäÝGLsHEF}G^_Kd_nibVzjZR@l}Mt_UUUEsHEfOxPebFl`GGPyC\IPqEbAxqBha{yH`CsHEfOxpcB@`~_oTBZ{]wo}bVzK_BDHAxCxOsHEF}GWX_|[`qL\nEUeT@lzmJ`jjjzLwzYpGG_}~S@_Bx_G|CvoNyWwGN}wl_XM@}ÁðÜ×ðôÈLÅÁäÞwzYpG{[}M`~_~Y\[{]LP\XJyK_BDHixAXEsHEfOxTb`Md_NdYNEUe_@LuC`jjJHsHEF}GsY}qS@_ZG`yCKw_^_vf@@GTwK@|aAsHEfOxlabu_A`GQLZ{]uoKagEt`}{wRF~gKsHEF}GCZ_x[`IJ]jEUeS@LyEy_UUuwLÁðÜ×ðôÈwÅÁäÞzyBxbcBMl`[B`xCKA`qdqk@@GtEl~B^vLwzyBxRgBw_A`\d[{]DPdkGLt`}[EgxAxuLwzyBxJ``v[`IVXlEUEosGZI`jjjzLwzYpGe[]{S@_BX`F|Ts_V^y]xkHLC^vLwzyBxzbbp_APTYDZ{]yogPlCt`}{W_G|ÁðÜ×ðôÈGtÅÁäÞLwzyBxff@y[`I}UTDUecKBjF`jjJHsHEF}GI^}vS@_rsG|TG`YeZ]xkHd@^sLwzyBxNebB`~oIYhZ{}KPHhIsK_BdZkFzGpLwzyBx^c@}[`Ik[HDUEU@tzEL`jjjzLwzYpG~X}sS@_J~G|tu_z[yb@@GTw{`~aÁðÜ×ðôÈÅÁäÞLwzYpG^_}z_APiZH[{}voTQ|K_BDhbyCXFsHEfOxqd`Ed_vP~oEUe[@T{eF`jjJHsHEF}GV]}Fl`NU`F|tA`eaAh@@GtEH^D~|LwzYpGfY]N`~oLWPZ{]q_PW]@t`}{WYG~gwLwzyBxEa@z[`IoALzjZ`kAzx_UUuwLwÁðÜ×ðôÈzÅÁäÝyBxUebzS@_qj_xCKH`ueQn@@GtEPoA^|LwzYpGJ\]q_APsheDBs_hWkKt`}[eqyCXwLwzyBxmg@Md_vZumDUedkGzI`jjjzLwzYpGB_]pS@_iUHG|TB`mfE]x{Q@q~avLwzyBxCdBr_APKE@dDBL`[iHEt`}{WRGzÁðÜ×ðôÈGÅÁäÞyLwzYpGl]@d_v]vEEUEg[FZr_UUUEsHEfOxKfBNl`BioxCk~_B[il@@Gd\hp{AFsHEfOxkaBG`~olE`dDBG`shpsK_BdZtFgKsHEF}GDZJd_NdyaDUeo[CZA`jjJHsHEF}GX\]|S@_uPhF|T_\ZUb@@GDn{wC~BsÁðÜ×ðôÈHÅÁäÞEfOxWgBK`~oZyW[{]F`}IK|K_BDhyAxxLwzYpGp__u[`q@@qzjzj{BZy_UUuwLwzyBx_dbxS@_[ShF|T_LYC_x{Q\HaNsHEF}G@]}AH@V_ZSo|W`kGzIIa}GNtDDXxLwzYp{_Y[`QtBe{jZf{Cfs_UUUEsHÁðÜ×ðôÈEÅÁäÞfODpaBpS@_WoGyCK}_tZ]x{Qri|avLwzyBDHeBIH@fwfTPChW@d{Nv^BXCbDAXJsHEF}{g\_Id_^nI}{jzW@x{Y}_UUuwLwzyBDDgBS@xkgyCKv_dDXx{QVixatLwzyBDd`BvwyHjDQChn[CE}v^BXCndBxÁðÜ×ðôÈtÅÁäÞLwzyBDtd`v[`AQEK{jZoGEFM`jjjzLwzYp{S]}uS@fcgyCkD`[AmTx[cNWD^MsHEF}{cY]}wE|cxQCHS@dxF{v^BXCYUBXyLwzYp{}^Jd_Ab|TDUe[@XYv_UUUEsHEfODRebuS@QkWxC\~oUfNMxqBXjnPH@~ÁðÜ×ðôÈLÅÁäÞwzYp{M\}LH@Z]gXPCHn{EYLIa}GNkTGXqLwzyBDjg`p[`^q~HEUeigAft_UUUEsHEfODz`BrS@QkOyC\KPJZ^BxqBxX~~vEsHEfODFdBAH@j]oHQCHW@xxA@Ia}g\ws{GAsHEfODVb`~[`nlGO{jZhW@FO`jjjzLwzÁðÜ×ðôÈYÅÁäÞp{qY]pS@vZ`F|c{ombnFxqBxXn~wwLwzyBDnaBtwuVROn|w`gBisv^BxQmr|gCsHEfOD~e@fdWbKHzjzU@hyEv_UUUEsHEfODacbzS@ez_F|C@PB\JsGN}gUaAuJsHEF}{nX}MH@rJPOn|w`gFfxv^BXcA]AxÁðÜ×ðôÈqÅÁäÞLwzyBDI``S[@hEKHzjzU@h|ew_UUUEsHEfODYdbAl@ZEHyC\JP\XrtGN}gUqar_~LwzYp{F]}xwmGZon|WY@XzQCIa}g\LC{GCsHEfODef`ndWVzwDUenwBZp_UUUEsHEfODuab~S@~|gF|CHPtYPpGN}gUyPp}LwÁðÜ×ðôÈzÅÁäÞYp{rZ}JH@B_oPQCHT@h{y~v\B`RZ_GtLwzyBD]c@X[@h~wDUenwEzN`jjjzLwzYp{|X}@l@mMdxC\|o[ULGN}GgZnH@|LwzYp{\_}IH@|[Rwn|whWCANIc}_j_GpLwzyBDsd@ddWitwDUE\@p{eI`jjjzLwzÁðÜ×ðôÈYÅÁäÞp{T]]Gl@{CLxC\{ogR~HxqBXjrOK@JsHEF}{dY}OH@\ubpPCh[@H~~KIc}_J^{GCsHEfODGa`[[@hj|wDUenOAZE`jjJHsHEF}{hZ]vS@_oB\yC|poOR}wGN}gUCPv_LwzYp{H\]BH@laipQCH_@H|~tv\B@`MaDxtÁðÜ×ðôÈLwÅÁäÞzyBDog@^[@hBHH{jzcOGzF`jjJHsHEF}{@_}qS@_E{]F|c{oWoDxqBxXKQq{LwzYp[[]qwsuhHPCHaODvxv\B`RR^{grLwzyBdPb`cdWkyWEUeS@Pyes_UUUEsHEfOdHfB@l`iDJxC|G`wOCxqBxX{Qr}LÁðÜ×ðôÈwÅÁäÞzYp[W^}vwK_ghQChnwCRKIc}_B_{gKsHEF}[GZddWWNhzjz^@PzuH`jjjzLwzYp[[\}@l`SDzyC\G`{MoLxqBXj`oH@KsHEF}[kX]HH@dg`HQChewE\KIc}_|_{GLwzYp[s__[[@h@EhzjZl_DJ~_UUuwLwzyÁðÜ×ðôÈBÅÁäÞd\dbvS@oeAfyC\C`sM]IxqBXJoNK@wLwzyBd|bBpw{LoXQChjO@xGIc}_mcaDXOsHEF}[]Y_Z[@HgGhzjZl_Aj_UUuwLwzyBdrabuS@ohIvyC\L`CLutGN}guhps_HsHEF}[uZ}AH@xSZko|WhODhpv\B@`s`DXvÁðÜ×ðôÈLÅÁäÞwzyBdZc`adwL{WDUee_GJ|_UUuwLwzyBdFgBHlpNNnyC\O`MHaLxqBXJKwN@IsHEF}[Y_}~wg|otQCHX@p_GIc}_mKaDxzLwzYp[I[ldwRsWDUEW@@}UG`jjJHsHEF}[Q]]pS@w_DnyC|}_FpzIxqBXJCWO`OsHEÁðÜ×ðôÈFÅÁäÞ}[aY]JH@hCXKn|WU@pF@pv\B@`[`DxCsHEfOdAa@T[@HyOh{jzhEJF`jjJHsHEF}[nZ}yS@wvD^yC\K`IHi@xqBxxZhwKsHEF}[N\]wwX\Co|w]@p~HIc}_D_{GwLwzyBdig`Q[@H^~gEUEE@@@jy_UUuwLwzyÁðÜ×ðôÈBÅÁäÞdy`bAlhD@nyC|}_AqarGN}gunYr_KsHEF}[z[]MH@pGgrPCH`O@`xv\B`Rx^{g|LwzYp[j]_`dwy~gEUEE@@BRK`jjjzLwzYp[rY]qS@WlEAxC\G`VOz~GN}GGvfK@EsHEfOdmabGH@P_kJPChZ@H~Otv\B@`gaDxzLÁðÜ×ðôÈwzÅÁäÞYp[BZX[@HB{gEUEE@@Eru_UUUEsHEfOdccbMlX|EQyC|L`jKHKxqBXJ\GM@IsHEF}[lX}zwoGezQChhwBtsv\B@`w`DXqLwzyBdK``ddwkJXzjZH@@GRx_UUuwLwzyBd[dBDlXmHayK\D@hxsBxqBxxwxw_LwÁðÜ×ðôÈzÅÁäÞYp[D]}OH@`jfVQCHZ@HyCDIc}_mO`@xEsHEfOdgf`Y[@HPOXzjZH@`BRN`jjjzLwzYp[ diff --git a/test/sample.rtcm2.chk b/test/sample.rtcm2.chk new file mode 100644 index 0000000..c962093 --- /dev/null +++ b/test/sample.rtcm2.chk @@ -0,0 +1,611 @@ +H 9 268 249.6 1 5 0 +S 13 0 3 249.6 -26.120 0.068 +S 2 0 73 249.6 1.220 -0.080 +S 8 0 22 249.6 23.760 0.030 +. +H 9 268 250.8 2 4 0 +S 19 0 186 250.8 -58.560 -0.256 +S 11 1 2 250.8 -39.900 0.174 +. +H 9 268 252.0 3 5 0 +S 27 0 62 252.0 -39.680 -0.016 +S 7 0 15 252.0 25.660 0.026 +S 26 0 128 252.0 12.840 0.118 +. +H 9 268 252.6 4 5 0 +S 13 0 3 252.6 -25.940 0.066 +S 2 0 73 252.6 0.920 -0.080 +S 8 0 22 252.6 23.820 0.014 +. +H 9 268 253.8 5 4 0 +S 19 0 186 253.8 -59.520 -0.224 +S 11 1 2 253.8 -39.260 0.206 +. +H 9 268 255.0 6 5 0 +S 27 0 62 255.0 -39.700 -0.018 +S 7 0 15 255.0 25.740 0.026 +S 26 0 128 255.0 13.240 0.128 +. +H 9 268 255.6 7 5 0 +S 2 0 73 255.6 0.680 -0.092 +S 13 0 3 255.6 -25.680 0.084 +S 8 0 22 255.6 23.880 0.000 +. +H 9 268 256.8 0 4 0 +S 19 0 186 256.8 -60.560 -0.244 +S 11 1 2 256.8 -38.620 0.222 +. +H 9 268 258.0 1 5 0 +S 27 0 62 258.0 -39.680 -0.002 +S 7 0 15 258.0 25.880 0.030 +S 26 0 128 258.0 13.700 0.124 +. +H 9 268 258.6 2 5 0 +S 2 0 73 258.6 0.440 -0.094 +S 13 0 3 258.6 -25.460 0.080 +S 8 0 22 258.6 23.920 -0.020 +. +H 9 268 259.8 3 4 0 +S 19 0 186 259.8 -61.260 -0.212 +S 11 1 2 259.8 -37.840 0.242 +. +H 9 268 261.0 4 5 0 +S 27 0 62 261.0 -39.740 -0.006 +S 7 0 15 261.0 25.980 0.034 +S 26 0 128 261.0 14.040 0.116 +. +H 9 268 261.6 5 5 0 +S 2 0 73 261.6 0.120 -0.088 +S 8 0 22 261.6 23.760 -0.040 +S 13 0 3 261.6 -25.220 0.090 +. +H 9 268 262.8 6 4 0 +S 19 0 186 262.8 -61.820 -0.212 +S 11 1 2 262.8 -36.800 0.256 +. +H 9 268 264.0 7 5 0 +S 27 0 62 264.0 -39.780 0.002 +S 7 0 15 264.0 26.060 0.032 +S 26 0 128 264.0 14.380 0.120 +. +H 9 268 264.6 0 5 0 +S 2 0 73 264.6 -0.180 -0.084 +S 8 0 22 264.6 23.620 -0.058 +S 13 0 3 264.6 -24.980 0.094 +. +H 9 268 265.8 1 4 0 +S 19 0 186 265.8 -62.540 -0.166 +S 11 1 2 265.8 -35.840 0.288 +. +H 9 268 267.0 2 5 0 +S 27 0 62 267.0 -39.820 0.002 +S 7 0 15 267.0 26.140 0.020 +S 26 0 128 267.0 14.700 0.116 +. +H 9 268 267.6 3 5 0 +S 2 0 73 267.6 -0.420 -0.078 +S 8 0 22 267.6 23.380 -0.078 +S 13 0 3 267.6 -24.640 0.108 +. +H 9 268 268.8 4 4 0 +S 19 0 186 268.8 -63.000 -0.152 +S 11 1 2 268.8 -35.200 0.288 +. +H 9 268 270.0 5 5 0 +S 27 0 62 270.0 -39.760 0.010 +S 7 0 15 270.0 26.180 0.016 +S 26 0 128 270.0 15.020 0.112 +. +H 9 268 270.6 6 5 0 +S 2 0 73 270.6 -0.680 -0.066 +S 8 0 22 270.6 23.140 -0.092 +S 13 0 3 270.6 -24.320 0.124 +. +H 9 268 271.8 7 4 0 +S 19 0 186 271.8 -63.500 -0.120 +S 11 1 2 271.8 -34.240 0.288 +. +H 9 268 273.0 0 5 0 +S 27 0 62 273.0 -39.860 0.004 +S 7 0 15 273.0 26.140 0.004 +S 26 0 128 273.0 15.280 0.106 +. +H 9 268 273.6 1 5 0 +S 2 0 73 273.6 -0.980 -0.060 +S 8 0 22 273.6 22.720 -0.108 +S 13 0 3 273.6 -24.120 0.120 +. +H 9 268 274.8 2 4 0 +S 19 0 186 274.8 -63.920 -0.116 +S 11 1 2 274.8 -33.280 0.320 +. +H 9 268 276.0 3 5 0 +S 27 0 62 276.0 -39.920 0.006 +S 26 0 128 276.0 15.520 0.100 +S 7 0 15 276.0 26.060 -0.004 +. +H 9 268 276.6 4 5 0 +S 2 0 73 276.6 -1.220 -0.050 +S 8 0 22 276.6 22.300 -0.122 +S 13 0 3 276.6 -23.780 0.120 +. +H 9 268 277.8 5 4 0 +S 19 0 186 277.8 -64.220 -0.088 +S 11 1 2 277.8 -32.320 0.352 +. +H 9 268 279.0 6 5 0 +S 27 0 62 279.0 -39.780 0.004 +S 26 0 128 279.0 15.860 0.098 +S 7 0 15 279.0 26.120 -0.012 +. +H 9 268 279.6 7 5 0 +S 2 0 73 279.6 -1.280 -0.040 +S 8 0 22 279.6 22.040 -0.136 +S 13 0 3 279.6 -23.320 0.120 +. +H 9 268 280.8 0 4 0 +S 19 0 186 280.8 -64.280 -0.056 +S 11 1 2 280.8 -31.040 0.352 +. +H 9 268 282.0 1 5 0 +S 27 0 62 282.0 -39.860 -0.006 +S 26 0 128 282.0 16.240 0.088 +S 7 0 15 282.0 26.100 -0.004 +. +H 9 268 282.6 2 5 0 +S 2 0 73 282.6 -1.400 -0.034 +S 8 0 22 282.6 21.580 -0.142 +S 13 0 3 282.6 -23.000 0.124 +. +H 9 268 283.8 3 4 0 +S 19 0 186 283.8 -64.480 -0.042 +S 11 1 2 283.8 -30.080 0.320 +. +H 9 268 285.0 4 5 0 +S 27 0 62 285.0 -39.880 0.000 +S 26 0 128 285.0 16.420 0.086 +S 7 0 15 285.0 25.980 -0.016 +. +H 9 268 285.6 5 5 0 +S 2 0 73 285.6 -1.560 -0.022 +S 8 0 22 285.6 21.120 -0.156 +S 13 0 3 285.6 -22.620 0.122 +. +H 9 268 286.8 6 4 0 +S 19 0 186 286.8 -64.540 -0.018 +S 11 1 2 286.8 -29.120 0.352 +. +H 9 268 288.0 7 5 0 +S 27 0 62 288.0 -39.900 0.000 +S 26 0 128 288.0 16.660 0.088 +S 7 0 15 288.0 25.940 -0.024 +. +H 9 268 288.6 0 5 0 +S 2 0 73 288.6 -1.660 -0.020 +S 8 0 22 288.6 20.600 -0.164 +S 13 0 3 288.6 -22.340 0.124 +. +H 9 268 289.8 1 4 0 +S 19 0 186 289.8 -64.620 0.008 +S 11 1 2 289.8 -27.840 0.352 +. +H 9 268 291.0 2 5 0 +S 27 0 62 291.0 -40.040 -0.006 +S 26 0 128 291.0 16.880 0.096 +S 7 0 15 291.0 25.760 -0.030 +. +H 9 268 291.6 3 5 0 +S 2 0 73 291.6 -1.800 -0.010 +S 8 0 22 291.6 20.000 -0.176 +S 13 0 3 291.6 -22.040 0.120 +. +H 9 268 292.8 4 4 0 +S 19 0 186 292.8 -64.620 0.048 +S 11 1 2 292.8 -26.880 0.352 +. +H 9 268 294.0 5 5 0 +S 27 0 62 294.0 -40.040 -0.008 +S 26 0 128 294.0 17.220 0.098 +S 7 0 15 294.0 25.700 -0.040 +. +H 9 268 294.6 6 5 0 +S 2 0 73 294.6 -1.800 -0.002 +S 8 0 22 294.6 19.520 -0.182 +S 13 0 3 294.6 -21.620 0.124 +. +H 9 268 295.8 7 4 0 +S 19 0 186 295.8 -64.420 0.074 +S 11 1 2 295.8 -25.920 0.352 +. +H 9 268 297.0 0 5 0 +S 27 0 62 297.0 -40.060 -0.020 +S 26 0 128 297.0 17.500 0.104 +S 7 0 15 297.0 25.560 -0.056 +. +H 9 268 297.6 1 5 0 +S 2 0 73 297.6 -1.820 0.000 +S 8 0 22 297.6 18.960 -0.188 +S 13 0 3 297.6 -21.240 0.122 +. +H 9 268 298.8 2 4 0 +S 19 0 186 298.8 -64.180 0.092 +S 11 1 2 298.8 -24.640 0.352 +. +H 9 268 300.0 3 5 0 +S 27 0 62 300.0 -40.160 -0.012 +S 26 0 128 300.0 17.780 0.090 +S 7 0 15 300.0 25.380 -0.062 +. +H 9 268 300.6 4 5 0 +S 2 0 73 300.6 -1.800 0.004 +S 8 0 22 300.6 18.400 -0.190 +S 13 0 3 300.6 -20.940 0.112 +. +H 9 268 301.8 5 4 0 +S 19 0 186 301.8 -63.920 0.122 +S 11 1 2 301.8 -23.680 0.352 +. +H 9 268 303.0 6 5 0 +S 27 0 62 303.0 -40.120 -0.022 +S 26 0 128 303.0 18.180 0.084 +S 7 0 15 303.0 25.260 -0.068 +. +H 9 268 303.6 7 5 0 +S 2 0 73 303.6 -1.700 0.020 +S 8 0 22 303.6 17.840 -0.204 +S 13 0 3 303.6 -20.500 0.120 +. +H 9 268 304.8 0 4 0 +S 19 0 186 304.8 -63.380 0.140 +S 11 1 2 304.8 -22.400 0.352 +. +H 9 268 306.0 1 5 0 +S 27 0 62 306.0 -40.240 -0.022 +S 26 0 128 306.0 18.460 0.078 +S 7 0 15 306.0 25.020 -0.080 +. +H 9 268 306.6 2 5 0 +S 8 0 22 306.6 17.260 -0.204 +S 2 0 73 306.6 -1.620 0.022 +S 13 0 3 306.6 -20.040 0.130 +. +H 9 268 307.8 3 4 0 +S 19 0 186 307.8 -62.840 0.166 +S 11 1 2 307.8 -21.120 0.384 +. +H 9 268 309.0 4 5 0 +S 27 0 62 309.0 -40.280 -0.030 +S 26 0 128 309.0 18.660 0.064 +S 7 0 15 309.0 24.800 -0.084 +. +H 9 268 309.6 5 5 0 +S 8 0 22 309.6 16.580 -0.216 +S 2 0 73 309.6 -1.580 0.034 +S 13 0 3 309.6 -19.800 0.136 +. +H 9 268 310.8 6 4 0 +S 19 0 186 310.8 -62.440 0.190 +S 11 1 2 310.8 -20.160 0.384 +. +H 9 268 312.0 7 5 0 +S 27 0 62 312.0 -40.400 -0.026 +S 26 0 128 312.0 18.880 0.054 +S 7 0 15 312.0 24.520 -0.082 +. +H 9 268 312.6 0 5 0 +S 8 0 22 312.6 15.940 -0.222 +S 2 0 73 312.6 -1.480 0.040 +S 13 0 3 312.6 -19.320 0.148 +. +H 9 268 313.8 1 4 0 +S 19 0 186 313.8 -61.800 0.210 +S 11 1 2 313.8 -18.880 0.384 +. +H 9 268 315.0 2 5 0 +S 27 0 62 315.0 -40.580 -0.026 +S 26 0 128 315.0 18.960 0.044 +S 7 0 15 315.0 24.180 -0.094 +. +H 9 268 315.6 3 5 0 +S 8 0 22 315.6 15.200 -0.226 +S 2 0 73 315.6 -1.460 0.038 +S 13 0 3 315.6 -18.940 0.164 +. +H 9 268 316.8 4 4 0 +S 19 0 186 316.8 -61.280 0.214 +S 11 1 2 316.8 -17.920 0.384 +. +H 9 268 318.0 5 5 0 +S 27 0 62 318.0 -40.680 -0.024 +S 7 0 15 318.0 23.920 -0.094 +S 26 0 128 318.0 19.080 0.032 +. +H 9 268 318.6 6 5 0 +S 8 0 22 318.6 14.540 -0.232 +S 2 0 73 318.6 -1.340 0.038 +S 13 0 3 318.6 -18.360 0.174 +. +H 9 268 319.8 7 4 0 +S 19 0 186 319.8 -60.520 0.236 +S 11 1 2 319.8 -16.640 0.384 +. +H 9 268 321.0 0 5 0 +S 27 0 62 321.0 -40.680 -0.014 +S 7 0 15 321.0 23.720 -0.098 +S 26 0 128 321.0 19.220 0.008 +. +H 9 268 321.6 1 5 0 +S 8 0 22 321.6 13.900 -0.238 +S 2 0 73 321.6 -1.140 0.030 +S 13 0 3 321.6 -17.760 0.194 +. +H 9 268 322.8 2 4 0 +S 19 0 186 322.8 -59.660 0.242 +S 11 1 2 322.8 -15.360 0.384 +. +H 9 268 324.0 3 5 0 +S 27 0 62 324.0 -40.600 -0.006 +S 7 0 15 324.0 23.460 -0.094 +S 26 0 128 324.0 19.300 0.000 +. +H 9 268 324.6 4 5 0 +S 8 0 22 324.6 13.160 -0.242 +S 2 0 73 324.6 -1.080 0.036 +S 13 0 3 324.6 -17.180 0.204 +. +H 9 268 325.8 5 4 0 +S 19 0 186 325.8 -58.880 0.256 +S 11 1 2 325.8 -14.400 0.352 +. +H 9 268 327.0 6 5 0 +S 27 0 62 327.0 -40.740 0.006 +S 7 0 15 327.0 23.060 -0.108 +S 26 0 128 327.0 19.120 -0.012 +. +H 9 268 327.6 7 5 0 +S 8 0 22 327.6 12.360 -0.242 +S 2 0 73 327.6 -1.060 0.024 +S 13 0 3 327.6 -16.620 0.232 +. +H 9 268 328.8 0 4 0 +S 19 0 186 328.8 -57.920 0.256 +S 11 1 2 328.8 -13.440 0.352 +. +H 9 268 330.0 1 5 0 +S 27 0 62 330.0 -40.740 0.018 +S 7 0 15 330.0 22.720 -0.110 +S 26 0 128 330.0 19.040 -0.022 +. +H 9 268 330.6 2 5 0 +S 8 0 22 330.6 11.580 -0.246 +S 2 0 73 330.6 -1.020 0.028 +S 13 0 3 330.6 -15.880 0.242 +. +H 9 268 331.8 3 4 0 +S 19 0 186 331.8 -57.280 0.288 +S 11 1 2 331.8 -12.160 0.352 +. +H 9 268 333.0 4 5 0 +S 27 0 62 333.0 -40.640 0.026 +S 7 0 15 333.0 22.320 -0.126 +S 26 0 128 333.0 18.900 -0.034 +. +H 9 268 333.6 5 5 0 +S 8 0 22 333.6 10.860 -0.246 +S 2 0 73 333.6 -0.940 0.024 +S 13 0 3 333.6 -14.720 0.256 +. +H 9 268 334.8 6 4 0 +S 19 0 186 334.8 -56.320 0.288 +S 11 1 2 334.8 -11.200 0.352 +. +H 9 268 336.0 7 5 0 +S 27 0 62 336.0 -40.520 0.036 +S 7 0 15 336.0 21.960 -0.142 +S 26 0 128 336.0 18.800 -0.048 +. +H 9 268 336.6 0 5 0 +S 8 0 22 336.6 10.140 -0.238 +S 2 0 73 336.6 -0.840 0.032 +S 13 0 3 336.6 -14.080 0.256 +. +H 9 268 337.8 1 4 0 +S 19 0 186 337.8 -55.680 0.288 +S 11 1 2 337.8 -9.920 0.352 +. +H 9 268 339.0 2 5 0 +S 27 0 62 339.0 -40.420 0.048 +S 7 0 15 339.0 21.540 -0.160 +S 26 0 128 339.0 18.700 -0.052 +. +H 9 268 339.6 3 5 0 +S 8 0 22 339.6 9.380 -0.244 +S 2 0 73 339.6 -0.720 0.032 +S 13 0 3 339.6 -13.120 0.288 +. +H 9 268 340.8 4 4 0 +S 19 0 186 340.8 -54.720 0.288 +S 11 1 2 340.8 -8.960 0.352 +. +H 9 268 342.0 5 5 0 +S 27 0 62 342.0 -40.300 0.058 +S 7 0 15 342.0 21.060 -0.176 +S 26 0 128 342.0 18.540 -0.040 +. +H 9 268 342.6 6 5 0 +S 8 0 22 342.6 8.640 -0.242 +S 2 0 73 342.6 -0.680 0.032 +S 13 0 3 342.6 -12.480 0.288 +. +H 9 268 343.8 7 4 0 +S 19 0 186 343.8 -54.080 0.288 +S 11 1 2 343.8 -8.000 0.352 +. +H 9 268 345.0 0 5 0 +S 27 0 62 345.0 -40.100 0.070 +S 7 0 15 345.0 20.480 -0.190 +S 26 0 128 345.0 18.360 -0.042 +. +H 9 268 345.6 1 5 0 +S 8 0 22 345.6 7.880 -0.240 +S 2 0 73 345.6 -0.620 0.026 +S 13 0 3 345.6 -11.840 0.288 +. +H 9 268 346.8 2 4 0 +S 19 0 186 346.8 -53.120 0.320 +S 11 1 2 346.8 -6.720 0.352 +. +H 9 268 348.0 3 5 0 +S 27 0 62 348.0 -39.960 0.080 +S 7 0 15 348.0 19.820 -0.194 +S 26 0 128 348.0 18.240 -0.038 +. +H 9 268 348.6 4 5 0 +S 8 0 22 348.6 7.040 -0.234 +S 2 0 73 348.6 -0.680 0.018 +S 13 0 3 348.6 -10.880 0.288 +. +H 9 268 349.8 5 4 0 +S 19 0 186 349.8 -52.160 0.320 +S 11 1 2 349.8 -6.080 0.320 +. +H 9 268 351.0 6 5 0 +S 27 0 62 351.0 -39.820 0.094 +S 7 0 15 351.0 19.140 -0.196 +S 26 0 128 351.0 17.980 -0.048 +. +H 9 268 351.6 7 5 0 +S 8 0 22 351.6 6.320 -0.238 +S 2 0 73 351.6 -0.700 0.014 +S 13 0 3 351.6 -10.240 0.288 +. +H 9 268 352.8 0 4 0 +S 19 0 186 352.8 -51.520 0.320 +S 11 1 2 352.8 -4.800 0.320 +. +H 9 268 354.0 1 5 0 +S 27 0 62 354.0 -39.460 0.102 +S 7 0 15 354.0 18.500 -0.210 +S 26 0 128 354.0 17.800 -0.052 +. +H 9 268 354.6 2 5 0 +S 8 0 22 354.6 5.620 -0.230 +S 2 0 73 354.6 -0.640 0.006 +S 13 0 3 354.6 -9.280 0.288 +. +H 9 268 355.8 3 4 0 +S 19 0 186 355.8 -50.240 0.320 +S 11 1 2 355.8 -3.840 0.320 +. +H 9 268 357.0 4 5 0 +S 27 0 62 357.0 -39.100 0.110 +S 7 0 15 357.0 17.940 -0.214 +S 26 0 128 357.0 17.700 -0.062 +. +H 9 268 357.6 5 5 0 +S 8 0 22 357.6 4.980 -0.216 +S 2 0 73 357.6 -0.620 0.004 +S 13 0 3 357.6 -8.320 0.288 +. +H 9 268 358.8 6 4 0 +S 19 0 186 358.8 -49.280 0.352 +S 11 1 2 358.8 -2.880 0.320 +. +H 9 268 360.0 7 5 0 +S 27 0 62 360.0 -38.760 0.118 +S 7 0 15 360.0 17.280 -0.224 +S 26 0 128 360.0 17.460 -0.074 +. +H 9 268 360.6 0 5 0 +S 8 0 22 360.6 4.320 -0.210 +S 2 0 73 360.6 -0.640 0.000 +S 13 0 3 360.6 -7.360 0.288 +. +H 9 268 361.8 1 4 0 +S 19 0 186 361.8 -48.320 0.352 +S 11 1 2 361.8 -1.920 0.320 +. +H 9 268 363.0 2 5 0 +S 27 0 62 363.0 -38.400 0.118 +S 7 0 15 363.0 16.620 -0.216 +S 26 0 128 363.0 17.300 -0.082 +. +H 9 268 363.6 3 5 0 +S 8 0 22 363.6 3.680 -0.210 +S 2 0 73 363.6 -0.560 -0.002 +S 13 0 3 363.6 -6.400 0.288 +. +H 9 268 364.8 4 4 0 +S 19 0 186 364.8 -47.360 0.352 +S 11 1 2 364.8 -0.960 0.320 +. +H 9 268 366.0 5 5 0 +S 27 0 62 366.0 -38.040 0.122 +S 7 0 15 366.0 16.000 -0.220 +S 26 0 128 366.0 17.020 -0.096 +. +H 9 268 366.6 6 5 0 +S 8 0 22 366.6 3.120 -0.196 +S 2 0 73 366.6 -0.560 0.000 +S 13 0 3 366.6 -5.760 0.288 +. +H 9 268 367.8 7 4 0 +S 19 0 186 367.8 -46.080 0.384 +S 11 1 2 367.8 0.000 0.320 +. +H 9 268 369.0 0 5 0 +S 27 0 62 369.0 -37.680 0.118 +S 7 0 15 369.0 15.260 -0.226 +S 26 0 128 369.0 16.720 -0.102 +. +H 9 268 369.6 1 5 0 +S 8 0 22 369.6 2.480 -0.180 +S 2 0 73 369.6 -0.640 0.000 +S 13 0 3 369.6 -4.800 0.288 +. +H 9 268 370.8 2 4 0 +S 19 0 186 370.8 -45.120 0.384 +S 11 1 2 370.8 0.640 0.288 +. +H 9 268 372.0 3 5 0 +S 27 0 62 372.0 -37.260 0.128 +S 7 0 15 372.0 14.540 -0.234 +S 26 0 128 372.0 16.440 -0.100 +. +H 9 268 372.6 4 5 0 +S 8 0 22 372.6 1.900 -0.176 +S 2 0 73 372.6 -0.720 0.002 +S 13 0 3 372.6 -4.160 0.288 +. +H 9 268 373.8 5 4 0 +S 19 0 186 373.8 -43.840 0.384 +S 11 1 2 373.8 1.600 0.288 +. +H 9 268 375.0 6 5 0 +S 27 0 62 375.0 -36.980 0.138 +S 7 0 15 375.0 13.720 -0.252 +S 26 0 128 375.0 15.940 -0.118 +. +H 9 268 375.6 7 5 0 +S 8 0 22 375.6 1.340 -0.162 +S 2 0 73 375.6 -0.760 0.010 +S 13 0 3 375.6 -3.200 0.288 +. +H 9 268 376.8 0 4 0 +S 19 0 186 376.8 -42.880 0.384 +S 11 1 2 376.8 2.240 0.288 +. +H 9 268 378.0 1 5 0 +S 27 0 62 378.0 -36.680 0.134 +S 7 0 15 378.0 12.800 -0.224 +S 26 0 128 378.0 15.540 -0.128 +. +H 9 268 378.6 2 5 0 +S 8 0 22 378.6 0.840 -0.150 +S 2 0 73 378.6 -0.740 0.014 +S 13 0 3 378.6 -2.560 0.256 +. +H 9 268 379.8 3 4 0 +S 19 0 186 379.8 -41.600 0.384 +S 11 1 2 379.8 3.200 0.288 +. diff --git a/test/synthetic-ais.json b/test/synthetic-ais.json new file mode 100644 index 0000000..81d717a --- /dev/null +++ b/test/synthetic-ais.json @@ -0,0 +1,48 @@ +# Synthetic test load designed to exercise the AIS JSON parser +# These are JSON dumps of the packets in the Schwehr testload, +# via gpsdecode -j -u +#include +#include +#include "bits.h" + +/*@ -duplicatequals -formattype */ +typedef unsigned long long ubig; + +static unsigned char buf[80]; +static union int_float i_f; +static union long_double l_d; +static char sb1, sb2; +static unsigned char ub1, ub2; +static short sw1, sw2; +static unsigned short uw1, uw2; +static int sl1, sl2; +static unsigned int ul1, ul2; +static long long sL1, sL2; +static unsigned long long uL1, uL2; +static float f1; +static double d1; + + +static char /*@ observer @*/ *hexdump(const void *binbuf, size_t len) +{ + static char hexbuf[BUFSIZ]; + size_t i, j = 0; + const char *ibuf = (const char *)binbuf; + const char *hexchar = "0123456789abcdef"; + + /*@ -shiftimplementation @*/ + for (i = 0; i < len; i++) { + hexbuf[j++] = hexchar[(ibuf[i] & 0xf0) >> 4]; + hexbuf[j++] = hexchar[ibuf[i] & 0x0f]; + } + /*@ +shiftimplementation @*/ + hexbuf[j] = '\0'; + return hexbuf; +} + +static void bedumpall(void) +{ + (void)printf("getsb: %016llx %016llx %016llx %016llx\n", + (ubig) sb1, (ubig) sb2, + (ubig) getsb(buf, 0), (ubig) getsb(buf, 8)); + (void)printf("getub: %016llx %016llx %016llx %016llx\n", + (ubig) ub1, (ubig) ub2, + (ubig) getub(buf, 0), (ubig) getub(buf, 8)); + (void)printf("getbesw: %016llx %016llx %016llx %016llx\n", + (ubig) sw1, (ubig) sw2, + (ubig) getbesw(buf, 0), (ubig) getbesw(buf, 8)); + (void)printf("getbeuw: %016llx %016llx %016llx %016llx\n", + (ubig) uw1, (ubig) uw2, + (ubig) getbeuw(buf, 0), (ubig) getbeuw(buf, 8)); + (void)printf("getbesl: %016llx %016llx %016llx %016llx\n", + (ubig) sl1, (ubig) sl2, + (ubig) getbesl(buf, 0), (ubig) getbesl(buf, 8)); + (void)printf("getbeul: %016llx %016llx %016llx %016llx\n", + (ubig) ul1, (ubig) ul2, + (ubig) getbeul(buf, 0), (ubig) getbeul(buf, 8)); + (void)printf("getbesL: %016llx %016llx %016llx %016llx\n", + (ubig) sL1, (ubig) sL2, + (ubig) getbesL(buf, 0), (ubig) getbesL(buf, 8)); + (void)printf("getbeuL: %016llx %016llx %016llx %016llx\n", + (ubig) uL1, (ubig) uL2, + (ubig) getbeuL(buf, 0), (ubig) getbeuL(buf, 8)); + (void)printf("getbef: %f %f\n", f1, getbef(buf, 24)); + (void)printf("getbed: %.16f %.16f\n", d1, getbed(buf, 16)); +} + +static void ledumpall(void) +{ + (void)printf("getsb: %016llx %016llx %016llx %016llx\n", + (ubig) sb1, (ubig) sb2, + (ubig) getsb(buf, 0), (ubig) getsb(buf, 8)); + (void)printf("getub: %016llx %016llx %016llx %016llx\n", + (ubig) ub1, (ubig) ub2, + (ubig) getub(buf, 0), (ubig) getub(buf, 8)); + (void)printf("getlesw: %016llx %016llx %016llx %016llx\n", + (ubig) sw1, (ubig) sw2, + (ubig) getlesw(buf, 0), (ubig) getlesw(buf, 8)); + (void)printf("getleuw: %016llx %016llx %016llx %016llx\n", + (ubig) uw1, (ubig) uw2, + (ubig) getleuw(buf, 0), (ubig) getleuw(buf, 8)); + (void)printf("getlesl: %016llx %016llx %016llx %016llx\n", + (ubig) sl1, (ubig) sl2, + (ubig) getlesl(buf, 0), (ubig) getlesl(buf, 8)); + (void)printf("getleul: %016llx %016llx %016llx %016llx\n", + (ubig) ul1, (ubig) ul2, + (ubig) getleul(buf, 0), (ubig) getleul(buf, 8)); + (void)printf("getlesL: %016llx %016llx %016llx %016llx\n", + (ubig) sL1, (ubig) sL2, + (ubig) getlesL(buf, 0), (ubig) getlesL(buf, 8)); + (void)printf("getleuL: %016llx %016llx %016llx %016llx\n", + (ubig) uL1, (ubig) uL2, + (ubig) getleuL(buf, 0), (ubig) getleuL(buf, 8)); + (void)printf("getlef: %f %f\n", f1, getlef(buf, 24)); + (void)printf("getled: %.16f %.16f\n", d1, getled(buf, 16)); +} + +struct unsigned_test +{ + unsigned char *buf; + unsigned int start, width; + unsigned long long expected; + char *description; +}; + +/*@ -duplicatequals +ignorequals @*/ +int main(void) +{ + /*@ -observertrans -usereleased @*/ + struct unsigned_test *up, unsigned_tests[] = { + /* tests using the big buffer */ + {buf, 0, 1, 0, "first bit of first byte"}, + {buf, 0, 8, 0x01, "first 8 bits"}, + {buf, 32, 7, 2, "first seven bits of fifth byte"}, + {buf, 56, 12, 0x8f, "12 bits crossing 7th to 8th bytes (0x08ff)"}, + {buf, 78, 4, 11, "2 bits crossing 8th to 9th byte (0xfefd)"}, + /* sporadic tests based on found bugs */ + {(unsigned char *)"\x19\x23\f6", + 7, 2, 2, "2 bits crossing 1st to 2nd byte (0x1923)"}, + }; + + unsigned char *sp; + + memcpy(buf, "\x01\x02\x03\x04\x05\x06\x07\x08", 8); + memcpy(buf + 8, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8", 8); + memcpy(buf + 16, "\x40\x09\x21\xfb\x54\x44\x2d\x18", 8); + memcpy(buf + 24, "\x40\x49\x0f\xdb", 4); + /*@ +observertrans +usereleased @*/ + + (void)fputs("Test data:", stdout); + for (sp = buf; sp < buf + 28; sp++) + (void)printf(" %02x", *sp); + (void)putc('\n', stdout); + + /* big-endian test */ + /*@-type@*/ + printf("Big-endian:\n"); + sb1 = getsb(buf, 0); + sb2 = getsb(buf, 8); + ub1 = getub(buf, 0); + ub2 = getub(buf, 8); + sw1 = getbesw(buf, 0); + sw2 = getbesw(buf, 8); + uw1 = getbeuw(buf, 0); + uw2 = getbeuw(buf, 8); + sl1 = getbesl(buf, 0); + sl2 = getbesl(buf, 8); + ul1 = getbeul(buf, 0); + ul2 = getbeul(buf, 8); + sL1 = getbesL(buf, 0); + sL2 = getbesL(buf, 8); + uL1 = getbeuL(buf, 0); + uL2 = getbeuL(buf, 8); + f1 = getbef(buf, 24); + d1 = getbed(buf, 16); + /*@+type@*/ + bedumpall(); + + /* little-endian test */ + printf("Little-endian:\n"); + /*@-type@*/ + sb1 = getsb(buf, 0); + sb2 = getsb(buf, 8); + ub1 = getub(buf, 0); + ub2 = getub(buf, 8); + sw1 = getlesw(buf, 0); + sw2 = getlesw(buf, 8); + uw1 = getleuw(buf, 0); + uw2 = getleuw(buf, 8); + sl1 = getlesl(buf, 0); + sl2 = getlesl(buf, 8); + ul1 = getleul(buf, 0); + ul2 = getleul(buf, 8); + sL1 = getlesL(buf, 0); + sL2 = getlesL(buf, 8); + uL1 = getleuL(buf, 0); + uL2 = getleuL(buf, 8); + f1 = getlef(buf, 24); + d1 = getled(buf, 16); + /*@+type@*/ + ledumpall(); + + + (void)printf("Testing bitfield extraction:\n"); + for (up = unsigned_tests; + up < + unsigned_tests + sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); + up++) { + unsigned long long res = ubits((char *)buf, up->start, up->width); + (void)printf("ubits(%s, %d, %d) %s should be %llu, is %llu: %s\n", + hexdump(buf, strlen((char *)buf)), + up->start, up->width, up->description, up->expected, res, + res == up->expected ? "succeeded" : "FAILED"); + } + + exit(0); +} diff --git a/test_float.c b/test_float.c new file mode 100644 index 0000000..6271ced --- /dev/null +++ b/test_float.c @@ -0,0 +1,259 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include + +/* + * Copyright (c) 2006 Chris Kuethe + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * this simple program tests to see whether your system can do proper + * single and double precision floating point. This is apparently Very + * Hard To Do(tm) on embedded systems, judging by the number of broken + * ARM toolchains I've seen... :( + * + * compile with: gcc -O -o test_float test_float.c + * (use whatever -O level you like) + */ + +int main( void ); +int test_single( void ); +int test_double( void ); + +int main() { + int i, j; + + if ((i = test_single())) + printf("WARNING: Single-precision " + "floating point math might be broken\n"); + + if ((j = test_double())) + printf("WARNING: Double-precision " + "floating point math might be broken\n"); + + i += j; + if (i == 0) + printf("floating point math appears to work\n"); + return i; +} + +int test_single() { + static float f; + static int i; + static int e = 0; + + /* addition test */ + f = 1.0; + for(i = 0; i < 10; i++) + f += (1< +#include +#include +#include + +#include "gpsd.h" + +int main(int argc, char **argv) +{ + double lat, lon; + + if (argc != 3) { + fprintf(stderr, "Usage: %s lat lon\n", argv[0]); + return 1; + } + + lat = atof(argv[1]); + lon = atof(argv[2]); + + if (lat > 90. || lat < -90.) { + fprintf(stderr, " -90 <= lat=%s(%.f) <= 90 ?\n", argv[1], lat); + return 1; + } + + if (lon > 180. || lat < -180.) { + fprintf(stderr, " -180 <= lon=%s(%.f) <= 180 ?\n", argv[2], lon); + return 1; + } + + printf(" lat= %f lon= %f geoid correction= %f\n", + lat, lon, wgs84_separation(lat, lon)); + + return 0; +} diff --git a/test_gpsmm.cpp b/test_gpsmm.cpp new file mode 100644 index 0000000..f30fdfa --- /dev/null +++ b/test_gpsmm.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2005 Alfredo Pironti + * + * This software is distributed under a BSD-style license. See the + * file "COPYING" in the top-level directory of the distribution for details. + * + */ + +/* This simple program shows the basic functionality of the C++ wrapper class */ +#include +#include +#include + +#include "libgpsmm.h" + +using namespace std; + +#ifdef SAMPLE_USAGE +static void callback(struct gps_data_t* p, char* buf, size_t len); +#endif + +int main(void) { + gpsmm gps_rec; + struct gps_data_t *resp; + + resp=gps_rec.open(); + if (resp==NULL) { + cout << "Error opening gpsd\n"; + return (1); + } + +#ifdef SAMPLE_USAGE + cout << "Going to set the callback...\n"; + if (gps_rec.set_callback(callback)!=0 ) { + cout << "Error setting callback.\n"; + return (1); + } + + cout << "Callback setted, sleeping...\n"; + sleep(10); + cout << "Exited from sleep...\n"; +#endif + +#ifdef SAMPLE_USAGE + if (gps_rec.del_callback()!=0) { + cout << "Error deleting callback\n"; + return (1); + } + cout << "Sleeping again, to make sure the callback is disabled\n"; + sleep(4); +#endif + + cout << "Exiting\n"; + return 0; +} + +#ifdef SAMPLE_USAGE +static void callback(struct gps_data_t* p, char* buf, size_t len) { + if (p==NULL) { + cout << "Error polling gpsd\n"; + return; + } + cout << "Online:\t" << p->online << "\n"; + cout << "Status:\t" << p->status << "\n"; + cout << "Mode:\t" << p->fix.mode << "\n"; + if (p->fix.mode>=MODE_2D) { + if (p->set & LATLON_SET) { + cout << "LatLon changed\n"; + } + else { + cout << "LatLon unchanged\n"; + } + cout << "Longitude:\t" << p->fix.longitude <<"\n"; + cout << "Latitude:\t" << p->fix.latitude <<"\n"; + } +} +#endif diff --git a/test_json.c b/test_json.c new file mode 100644 index 0000000..b656c4b --- /dev/null +++ b/test_json.c @@ -0,0 +1,295 @@ +/* json.c - unit test for JSON partsing into fixed-extent structures + * + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ + +#include +#include +#include +#include +#include + +#include "gpsd.h" +#include "gps_json.h" + +#include "strl.c" + +static void assert_case(int num, int status) +{ + if (status != 0) { + (void)fprintf(stderr, "case %d FAILED, status %d (%s).\n", num, + status, json_error_string(status)); + exit(1); + } +} + +static void assert_string(char *attr, char *fld, char *val) +{ + if (strcmp(fld, val)) { + (void)fprintf(stderr, + "'%s' string attribute eval failed, value = %s.\n", + attr, fld); + exit(1); + } +} + +static void assert_integer(char *attr, int fld, int val) +{ + if (fld != val) { + (void)fprintf(stderr, + "'%s' integer attribute eval failed, value = %d.\n", + attr, fld); + exit(1); + } +} + +static void assert_uinteger(char *attr, uint fld, uint val) +{ + if (fld != val) { + (void)fprintf(stderr, + "'%s' integer attribute eval failed, value = %u.\n", + attr, fld); + exit(1); + } +} + +static void assert_boolean(char *attr, bool fld, bool val) +{ + /*@-boolcompare@*/ + if (fld != val) { + (void)fprintf(stderr, + "'%s' boolean attribute eval failed, value = %s.\n", + attr, fld ? "true" : "false"); + exit(1); + } + /*@+boolcompare@*/ +} + +/* + * Floating point comparisons are iffy, but at least if any of these fail + * the output will make it clear whether it was a precision issue + */ +static void assert_real(char *attr, double fld, double val) +{ + if (fld != val) { + (void)fprintf(stderr, + "'%s' real attribute eval failed, value = %f.\n", attr, + fld); + exit(1); + } +} + +/*@ -fullinitblock @*/ + +static struct gps_data_t gpsdata; + +/* Case 1: TPV report */ + +/* *INDENT-OFF* */ +static const char json_str1[] = "{\"class\":\"TPV\",\ + \"device\":\"GPS#1\",\"tag\":\"MID2\", \ + \"time\":1119197561.890,\"lon\":46.498203637,\"lat\":7.568074350,\ + \"alt\":1327.780,\"epx\":21.000,\"epy\":23.000,\"epv\":124.484,\"mode\":3}"; + +/* Case 2: SKY report */ + +static const char *json_str2 = "{\"class\":\"SKY\",\ + \"tag\":\"MID4\",\"time\":1119197562.890, \ + \"satellites\":[\ + {\"PRN\":10,\"el\":45,\"az\":196,\"ss\":34,\"used\":true},\ + {\"PRN\":29,\"el\":67,\"az\":310,\"ss\":40,\"used\":true},\ + {\"PRN\":28,\"el\":59,\"az\":108,\"ss\":42,\"used\":true},\ + {\"PRN\":26,\"el\":51,\"az\":304,\"ss\":43,\"used\":true},\ + {\"PRN\":8,\"el\":44,\"az\":58,\"ss\":41,\"used\":true},\ + {\"PRN\":27,\"el\":16,\"az\":66,\"ss\":39,\"used\":true},\ + {\"PRN\":21,\"el\":10,\"az\":301,\"ss\":0,\"used\":false}]}"; + +/* Case 3: String list syntax */ + +static const char *json_str3 = "[\"foo\",\"bar\",\"baz\"]"; + +static char *stringptrs[3]; +static char stringstore[256]; +static int stringcount; + +/*@-type@*/ +static const struct json_array_t json_array_3 = { + .element_type = t_string, + .arr.strings.ptrs = stringptrs, + .arr.strings.store = stringstore, + .arr.strings.storelen = sizeof(stringstore), + .count = &stringcount, + .maxlen = sizeof(stringptrs)/sizeof(stringptrs[0]), +}; +/*@+type@*/ + +/* Case 4: test defaulting of unspecified attributes */ + +static const char *json_str4 = "{\"flag1\":true,\"flag2\":false}"; + +static bool flag1, flag2; +static double dftreal; +static int dftinteger; +static unsigned int dftuinteger; + +static const struct json_attr_t json_attrs_4[] = { + {"dftint", t_integer, .addr.integer = &dftinteger, .dflt.integer = -5}, + {"dftuint", t_integer, .addr.uinteger = &dftuinteger, .dflt.uinteger = 10}, + {"dftreal", t_real, .addr.real = &dftreal, .dflt.real = 23.17}, + {"flag1", t_boolean, .addr.boolean = &flag1,}, + {"flag2", t_boolean, .addr.boolean = &flag2,}, + {NULL}, +}; + +/* Case 5: test DEVICE parsing */ + +static const char *json_str5 = "{\"class\":\"DEVICE\",\ + \"path\":\"/dev/ttyUSB0\",\ + \"flags\":5,\ + \"driver\":\"Foonly\",\"subtype\":\"Foonly Frob\"\ + }"; + +/* Case 6: test parsing of subobject list into array of structures */ + +static const char *json_str6 = "{\"parts\":[\ + {\"name\":\"Urgle\", \"flag\":true, \"count\":3},\ + {\"name\":\"Burgle\",\"flag\":false,\"count\":1},\ + {\"name\":\"Witter\",\"flag\":true, \"count\":4},\ + {\"name\":\"Thud\", \"flag\":false,\"count\":1}]}"; + +struct dumbstruct_t { + char name[64]; + bool flag; + int count; +}; +static struct dumbstruct_t dumbstruck[5]; +static int dumbcount; + +/*@-type@*/ +static const struct json_attr_t json_attrs_6_subtype[] = { + {"name", t_string, .addr.offset = offsetof(struct dumbstruct_t, name), + .len = 64}, + {"flag", t_boolean, .addr.offset = offsetof(struct dumbstruct_t, flag),}, + {"count", t_integer, .addr.offset = offsetof(struct dumbstruct_t, count),}, + {NULL}, +}; + +static const struct json_attr_t json_attrs_6[] = { + {"parts", t_array, .addr.array.element_type = t_structobject, + .addr.array.arr.objects.base = (char*)&dumbstruck, + .addr.array.arr.objects.stride = sizeof(struct dumbstruct_t), + .addr.array.arr.objects.subtype = json_attrs_6_subtype, + .addr.array.count = &dumbcount, + .addr.array.maxlen = sizeof(dumbstruck)/sizeof(dumbstruck[0])}, + {NULL}, +}; +/*@+type@*/ + +/* Case 7: test parsing of version response */ + +static const char *json_str7 = "{\"class\":\"VERSION\",\ + \"release\":\"2.40dev\",\"rev\":\"dummy-revision\",\ + \"proto_major\":3,\"proto_minor\":1}"; + +/* Case 8: test parsing arrays of enumerated types */ + +static const char *json_str8 = "{\"fee\":\"FOO\",\"fie\":\"BAR\",\"foe\":\"BAZ\"}"; +static const struct json_enum_t enum_table[] = { + {"BAR", 6}, {"FOO", 3}, {"BAZ", 14}, {NULL} +}; + +static int fee, fie, foe; +static const struct json_attr_t json_attrs_8[] = { + {"fee", t_integer, .addr.integer = &fee, .map=enum_table}, + {"fie", t_integer, .addr.integer = &fie, .map=enum_table}, + {"foe", t_integer, .addr.integer = &foe, .map=enum_table}, + {NULL}, +}; +/*@ +fullinitblock @*/ +/* *INDENT-ON* */ + +int main(int argc UNUSED, char *argv[]UNUSED) +{ + int status = 0; + + (void)fprintf(stderr, "JSON unit test "); + + status = libgps_json_unpack(json_str1, &gpsdata, NULL); + assert_case(1, status); + assert_string("device", gpsdata.dev.path, "GPS#1"); + assert_string("tag", gpsdata.tag, "MID2"); + assert_integer("mode", gpsdata.fix.mode, 3); + assert_real("time", gpsdata.fix.time, 1119197561.890); + assert_real("lon", gpsdata.fix.longitude, 46.498203637); + assert_real("lat", gpsdata.fix.latitude, 7.568074350); + + status = libgps_json_unpack(json_str2, &gpsdata, NULL); + assert_case(2, status); + assert_string("tag", gpsdata.tag, "MID4"); + assert_integer("used", gpsdata.satellites_used, 6); + assert_integer("PRN[0]", gpsdata.PRN[0], 10); + assert_integer("el[0]", gpsdata.elevation[0], 45); + assert_integer("az[0]", gpsdata.azimuth[0], 196); + assert_real("ss[0]", gpsdata.ss[0], 34); + assert_integer("used[0]", gpsdata.used[0], 10); + assert_integer("used[5]", gpsdata.used[5], 27); + assert_integer("PRN[6]", gpsdata.PRN[6], 21); + assert_integer("el[6]", gpsdata.elevation[6], 10); + assert_integer("az[6]", gpsdata.azimuth[6], 301); + assert_real("ss[6]", gpsdata.ss[6], 0); + + status = json_read_array(json_str3, &json_array_3, NULL); + assert_case(3, status); + assert(stringcount == 3); + assert(strcmp(stringptrs[0], "foo") == 0); + assert(strcmp(stringptrs[1], "bar") == 0); + assert(strcmp(stringptrs[2], "baz") == 0); + + status = json_read_object(json_str4, json_attrs_4, NULL); + assert_case(4, status); + assert_integer("dftint", dftinteger, -5); /* did the default work? */ + assert_uinteger("dftuint", dftuinteger, 10); /* did the default work? */ + assert_real("dftreal", dftreal, 23.17); /* did the default work? */ + assert_boolean("flag1", flag1, true); + assert_boolean("flag2", flag2, false); + + status = libgps_json_unpack(json_str5, &gpsdata, NULL); + assert_case(5, status); + assert_string("path", gpsdata.dev.path, "/dev/ttyUSB0"); + assert_integer("flags", gpsdata.dev.flags, 5); + assert_string("driver", gpsdata.dev.driver, "Foonly"); + + status = json_read_object(json_str6, json_attrs_6, NULL); + assert_case(6, status); + assert_integer("dumbcount", dumbcount, 4); + assert_string("dumbstruck[0].name", dumbstruck[0].name, "Urgle"); + assert_string("dumbstruck[1].name", dumbstruck[1].name, "Burgle"); + assert_string("dumbstruck[2].name", dumbstruck[2].name, "Witter"); + assert_string("dumbstruck[3].name", dumbstruck[3].name, "Thud"); + assert_boolean("dumbstruck[0].flag", dumbstruck[0].flag, true); + assert_boolean("dumbstruck[1].flag", dumbstruck[1].flag, false); + assert_boolean("dumbstruck[2].flag", dumbstruck[2].flag, true); + assert_boolean("dumbstruck[3].flag", dumbstruck[3].flag, false); + assert_integer("dumbstruck[0].count", dumbstruck[0].count, 3); + assert_integer("dumbstruck[1].count", dumbstruck[1].count, 1); + assert_integer("dumbstruck[2].count", dumbstruck[2].count, 4); + assert_integer("dumbstruck[3].count", dumbstruck[3].count, 1); + + status = libgps_json_unpack(json_str7, &gpsdata, NULL); + assert_case(7, status); + assert_string("release", gpsdata.version.release, "2.40dev"); + assert_string("rev", gpsdata.version.rev, "dummy-revision"); + assert_integer("proto_major", gpsdata.version.proto_major, 3); + assert_integer("proto_minor", gpsdata.version.proto_minor, 1); + + status = json_read_object(json_str8, json_attrs_8, NULL); + assert_case(8, status); + assert_integer("fee", fee, 3); + assert_integer("fie", fie, 6); + assert_integer("foe", foe, 14); + + (void)fprintf(stderr, "succeeded.\n"); + + exit(0); +} diff --git a/test_mkgmtime.c b/test_mkgmtime.c new file mode 100644 index 0000000..b4ad4fd --- /dev/null +++ b/test_mkgmtime.c @@ -0,0 +1,114 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include + +#include "gps.h" + +/*@-type@*/ +static struct +{ + struct tm t; + time_t result; +} tests[] = { + /* *INDENT-OFF* */ + /* sec, min, h, md, mon, year, wd, yd, isdst, gmtoff, zone timestamp what */ + {{ 0, 0, 0, 1, 0, 70, 0, 0, 0, 0, 0, }, 0 }, + {{ 0, 0, 0, 1, 0, 70, 0, 0, 0, 0, 0, }, 0 }, /* lower limit */ + {{ 7, 14, 3, 19, 0, 138, 0, 0, 0, 0, 0, }, 0x7fffffff }, /* upper limit */ + {{ 0, 0, 12, 1, 0, 99, 0, 0, 0, 0, 0, }, 915192000 }, /* leap year */ + {{ 0, 0, 12, 1, 1, 99, 0, 0, 0, 0, 0, }, 917870400 }, /* leap year */ + {{ 0, 0, 12, 1, 2, 99, 0, 0, 0, 0, 0, }, 920289600 }, /* leap year */ + {{ 0, 0, 12, 1, 8, 99, 0, 0, 0, 0, 0, }, 936187200 }, /* leap year */ + {{ 0, 0, 12, 1, 0, 100, 0, 0, 0, 0, 0, }, 946728000 }, /* leap year */ + {{ 0, 0, 12, 1, 1, 100, 0, 0, 0, 0, 0, }, 949406400 }, /* leap year */ + {{ 0, 0, 12, 1, 2, 100, 0, 0, 0, 0, 0, }, 951912000 }, /* leap year */ + {{ 0, 0, 12, 1, 8, 100, 0, 0, 0, 0, 0, }, 967809600 }, /* leap year */ + {{ 0, 0, 12, 1, 0, 101, 0, 0, 0, 0, 0, }, 978350400 }, /* leap year */ + {{ 0, 0, 12, 1, 1, 101, 0, 0, 0, 0, 0, }, 981028800 }, /* leap year */ + {{ 0, 0, 12, 1, 2, 101, 0, 0, 0, 0, 0, }, 983448000 }, /* leap year */ + {{ 0, 0, 12, 1, 8, 101, 0, 0, 0, 0, 0, }, 999345600 }, /* leap year */ + {{ 0, 0, 12, 1, 0, 102, 0, 0, 0, 0, 0, }, 1009886400 }, /* leap year */ + {{ 0, 0, 12, 1, 1, 102, 0, 0, 0, 0, 0, }, 1012564800 }, /* leap year */ + {{ 0, 0, 12, 1, 2, 102, 0, 0, 0, 0, 0, }, 1014984000 }, /* leap year */ + {{ 0, 0, 12, 1, 8, 102, 0, 0, 0, 0, 0, }, 1030881600 }, /* leap year */ + {{ 0, 0, 12, 1, 0, 103, 0, 0, 0, 0, 0, }, 1041422400 }, /* leap year */ + {{ 0, 0, 12, 1, 1, 103, 0, 0, 0, 0, 0, }, 1044100800 }, /* leap year */ + {{ 0, 0, 12, 1, 2, 103, 0, 0, 0, 0, 0, }, 1046520000 }, /* leap year */ + {{ 0, 0, 12, 1, 8, 103, 0, 0, 0, 0, 0, }, 1062417600 }, /* leap year */ + {{ 0, 0, 12, 1, 0, 104, 0, 0, 0, 0, 0, }, 1072958400 }, /* leap year */ + {{ 0, 0, 12, 1, 1, 104, 0, 0, 0, 0, 0, }, 1075636800 }, /* leap year */ + {{ 0, 0, 12, 1, 2, 104, 0, 0, 0, 0, 0, }, 1078142400 }, /* leap year */ + {{ 0, 0, 12, 1, 8, 104, 0, 0, 0, 0, 0, }, 1094040000 }, /* leap year */ + {{ 0, 0, 12, 1, 0, 108, 0, 0, 0, 0, 0, }, 1199188800 }, /* leap year */ + {{ 0, 0, 12, 1, 1, 108, 0, 0, 0, 0, 0, }, 1201867200 }, /* leap year */ + {{ 0, 0, 12, 1, 2, 108, 0, 0, 0, 0, 0, }, 1204372800 }, /* leap year */ + {{ 0, 0, 12, 1, 8, 108, 0, 0, 0, 0, 0, }, 1220270400 }, /* leap year */ + {{ 59, 59, 23, 31, 12, 110, 0, 0, 0, 0, 0, }, 1296518399 }, /* year wrap */ + {{ 0, 0, 0, 1, 0, 111, 0, 0, 0, 0, 0, }, 1293840000 }, /* year wrap */ + {{ 59, 59, 23, 31, 12, 111, 0, 0, 0, 0, 0, }, 1328054399 }, /* year wrap */ + {{ 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, }, 1325376000 }, /* year wrap */ + {{ 59, 59, 23, 31, 12, 112, 0, 0, 0, 0, 0, }, 1359676799 }, /* year wrap */ + {{ 0, 0, 0, 1, 0, 113, 0, 0, 0, 0, 0, }, 1356998400 }, /* year wrap */ + {{ 59, 59, 23, 31, 0, 115, 0, 0, 0, 0, 0, }, 1422748799 }, /* month wrap */ + {{ 0, 0, 0, 1, 1, 115, 0, 0, 0, 0, 0, }, 1422748800 }, /* month wrap */ + {{ 59, 59, 23, 28, 1, 115, 0, 0, 0, 0, 0, }, 1425167999 }, /* month wrap */ + {{ 0, 0, 0, 1, 2, 115, 0, 0, 0, 0, 0, }, 1425168000 }, /* month wrap */ + {{ 59, 59, 23, 31, 2, 115, 0, 0, 0, 0, 0, }, 1427846399 }, /* month wrap */ + {{ 0, 0, 0, 1, 3, 115, 0, 0, 0, 0, 0, }, 1427846400 }, /* month wrap */ + {{ 59, 59, 23, 30, 3, 115, 0, 0, 0, 0, 0, }, 1430438399 }, /* month wrap */ + {{ 0, 0, 0, 1, 4, 115, 0, 0, 0, 0, 0, }, 1430438400 }, /* month wrap */ + {{ 59, 59, 23, 31, 4, 115, 0, 0, 0, 0, 0, }, 1433116799 }, /* month wrap */ + {{ 0, 0, 0, 1, 5, 115, 0, 0, 0, 0, 0, }, 1433116800 }, /* month wrap */ + {{ 59, 59, 23, 30, 5, 115, 0, 0, 0, 0, 0, }, 1435708799 }, /* month wrap */ + {{ 0, 0, 0, 1, 6, 115, 0, 0, 0, 0, 0, }, 1435708800 }, /* month wrap */ + {{ 59, 59, 23, 31, 6, 115, 0, 0, 0, 0, 0, }, 1438387199 }, /* month wrap */ + {{ 0, 0, 0, 1, 7, 115, 0, 0, 0, 0, 0, }, 1438387200 }, /* month wrap */ + {{ 59, 59, 23, 31, 7, 115, 0, 0, 0, 0, 0, }, 1441065599 }, /* month wrap */ + {{ 0, 0, 0, 1, 8, 115, 0, 0, 0, 0, 0, }, 1441065600 }, /* month wrap */ + {{ 59, 59, 23, 30, 8, 115, 0, 0, 0, 0, 0, }, 1443657599 }, /* month wrap */ + {{ 0, 0, 0, 1, 9, 115, 0, 0, 0, 0, 0, }, 1443657600 }, /* month wrap */ + {{ 59, 59, 23, 31, 9, 115, 0, 0, 0, 0, 0, }, 1446335999 }, /* month wrap */ + {{ 0, 0, 0, 1, 10, 115, 0, 0, 0, 0, 0, }, 1446336000 }, /* month wrap */ + {{ 59, 59, 23, 30, 10, 115, 0, 0, 0, 0, 0, }, 1448927999 }, /* month wrap */ + {{ 0, 0, 0, 1, 11, 115, 0, 0, 0, 0, 0, }, 1448928000 }, /* month wrap */ + {{ 59, 59, 23, 31, 11, 115, 0, 0, 0, 0, 0, }, 1451606399 }, /* month wrap */ + {{ 0, 0, 0, 1, 0, 116, 0, 0, 0, 0, 0, }, 1451606400 }, /* month wrap */ + /* *INDENT-ON* */ +}; + +/*@-type@*/ + +/*@+longunsignedintegral*/ +int main(int argc, char *argv[]) +{ + int i; + char tbuf[128]; + time_t ts; + bool failed = false; + + (void)setenv("TZ", "GMT", 1); + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { +#if 0 /* use this to calculate with glibc */ + ts = mktime(&tests[i].t); +#else + ts = mkgmtime(&tests[i].t); +#endif + if (ts != tests[i].result) { + failed = true; + (void)strftime(tbuf, sizeof(tbuf), "%F %T", &tests[i].t); + (void)printf("test %2d failed. " + "Time returned from: %s should be %lu (but was: %lu)\n", + i, tbuf, (unsigned long)tests[i].result, + (unsigned long)ts); + } + } + return (int)failed; +} + +/*@-longunsignedintegral*/ diff --git a/test_packet.c b/test_packet.c new file mode 100644 index 0000000..d9109d6 --- /dev/null +++ b/test_packet.c @@ -0,0 +1,350 @@ +/* + * This file is Copyright (c) 2010 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + */ +#include +#include +#include +#include +#include +#include +#ifndef S_SPLINT_S +#include +#endif /* S_SPLINT_S */ +#include +#include +#include + +#include "gpsd.h" + +static int verbose = 0; + +void gpsd_report(int errlevel, const char *fmt, ...) +/* assemble command in printf(3) style, use stderr or syslog */ +{ + if (errlevel <= verbose) { + char buf[BUFSIZ]; + va_list ap; + + buf[0] = '\0'; + va_start(ap, fmt); + (void)vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, + ap); + va_end(ap); + + (void)fputs(buf, stderr); + } +} + +struct map +{ + char *legend; + char test[MAX_PACKET_LENGTH + 1]; + size_t testlen; + int garbage_offset; + int type; +}; + +/* *INDENT-OFF* */ +/*@ -initallelements +charint -usedef @*/ +static struct map singletests[] = { + /* NMEA tests */ + { + .legend = "NMEA packet with checksum (1)", + .test = "$GPVTG,308.74,T,,M,0.00,N,0.0,K*68\r\n", + .testlen = 36, + .garbage_offset = 0, + NMEA_PACKET, + }, + { + .legend = "NMEA packet with checksum (2)", + .test = "$GPGGA,110534.994,4002.1425,N,07531.2585,W,0,00,50.0,172.7,M,-33.8,M,0.0,0000*7A\r\n", + .testlen = 82, + .garbage_offset = 0, + .type = NMEA_PACKET, + }, + { + .legend = "NMEA packet with checksum and 4 chars of leading garbage", + .test = "\xff\xbf\x00\xbf$GPVTG,308.74,T,,M,0.00,N,0.0,K*68\r\n", + .testlen = 40, + .garbage_offset = 4, + .type = NMEA_PACKET, + }, + { + .legend = "NMEA packet without checksum", + .test = "$PSRF105,1\r\n", + .testlen = 12, + .garbage_offset = 0, + .type = NMEA_PACKET, + }, + { + .legend = "NMEA packet with wrong checksum", + .test = "$GPVTG,308.74,T,,M,0.00,N,0.0,K*28\r\n", + .testlen = 36, + .garbage_offset = 0, + .type = BAD_PACKET, + }, + /* SiRF tests */ + { + .legend = "SiRF WAAS version ID", + .test = { + 0xA0, 0xA2, 0x00, 0x15, + 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44, + 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53, + 0x4D, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x82, 0xB0, 0xB3}, + .testlen = 29, + .garbage_offset = 0, + .type = SIRF_PACKET, + }, + { + .legend = "SiRF WAAS version ID with 3 chars of leading garbage", + .test = { + 0xff, 0x00, 0xff, + 0xA0, 0xA2, 0x00, 0x15, + 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44, + 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53, + 0x4D, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x82, 0xB0, 0xB3}, + .testlen = 32, + .garbage_offset = 3, + .type = SIRF_PACKET, + }, + { + .legend = "SiRF WAAS version ID with wrong checksum", + .test = { + 0xA0, 0xA2, 0x00, 0x15, + 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44, + 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53, + 0x4D, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0xB0, 0xB3}, + .testlen = 29, + .garbage_offset = 0, + .type = BAD_PACKET, + }, + { + .legend = "SiRF WAAS version ID with bad length", + .test = { + 0xA0, 0xA2, 0xff, 0x15, + 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44, + 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53, + 0x4D, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x82, 0xB0, 0xB3}, + .testlen = 29, + .garbage_offset = 0, + .type = BAD_PACKET, + }, + /* Zodiac tests */ + { + .legend = "Zodiac binary 1000 Geodetic Status Output Message", + .test = { + 0xff, 0x81, 0xe8, 0x03, 0x31, 0x00, 0x00, 0x00, 0xe8, 0x79, + 0x74, 0x0e, 0x00, 0x00, 0x24, 0x00, 0x24, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x03, 0x23, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x06, 0x00, + 0xcd, 0x07, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x7b, 0x0d, + 0x00, 0x00, 0x12, 0x6b, 0xa7, 0x04, 0x41, 0x75, 0x32, 0xf8, + 0x03, 0x1f, 0x00, 0x00, 0xe6, 0xf2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0xf6, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, + 0xd9, 0x12, 0x90, 0xd0, 0x03, 0x00, 0x00, 0xa3, 0xe1, 0x11, + 0x10, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0xe1, 0x11, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0x04, 0x00, 0x04, 0xaa}, + .testlen = 110, + .garbage_offset = 0, + .type = ZODIAC_PACKET, + }, + /* EverMore tests */ + { + .legend = "EverMore status packet 0x20", + .test = { + 0x10, 0x02, 0x0D, 0x20, 0xE1, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x1E, 0x00, 0x32, 0x00, 0x5b, 0x10, + 0x03}, + .testlen = 17, + .garbage_offset = 0, + .type = EVERMORE_PACKET, + }, + { + .legend = "EverMore packet 0x04 with 0x10 0x10 sequence", + .test = { + 0x10, 0x02, 0x0f, 0x04, 0x00, 0x00, 0x10, 0x10, + 0xa7, 0x13, 0x03, 0x2c, 0x26, 0x24, 0x0a, 0x17, + 0x00, 0x68, 0x10, 0x03}, + .testlen = 20, + .garbage_offset = 0, + .type = EVERMORE_PACKET, + }, + { + .legend = "EverMore packet 0x04 with 0x10 0x10 sequence, some noise before packet data", + .test = { + 0x10, 0x03, 0xff, 0x10, 0x02, 0x0f, 0x04, 0x00, + 0x00, 0x10, 0x10, 0xa7, 0x13, 0x03, 0x2c, 0x26, + 0x24, 0x0a, 0x17, 0x00, 0x68, 0x10, 0x03}, + .testlen = 23, + .garbage_offset = 3, + .type = EVERMORE_PACKET, + }, + { + .legend = "EverMore packet 0x04, 0x10 and some other data at the beginning", + .test = { + 0x10, 0x12, 0x10, 0x03, 0xff, 0x10, 0x02, 0x0f, + 0x04, 0x00, 0x00, 0x10, 0x10, 0xa7, 0x13, 0x03, + 0x2c, 0x26, 0x24, 0x0a, 0x17, 0x00, 0x68, 0x10, + 0x03}, + .testlen = 25, + .garbage_offset = 5, + .type = EVERMORE_PACKET, + }, + { + .legend = "EverMore packet 0x04, 0x10 three times at the beginning", + .test = { + 0x10, 0x10, 0x10, + 0x10, 0x02, 0x0f, 0x04, 0x00, 0x00, 0x10, 0x10, + 0xa7, 0x13, 0x03, 0x2c, 0x26, 0x24, 0x0a, 0x17, + 0x00, 0x68, 0x10, 0x03}, + .testlen = 23, + .garbage_offset = 3, + .type = EVERMORE_PACKET, + }, + { + .legend = "RTCM104V3 type 1005 packet", + /* + * Reference Station Id = 2003 + * GPS Service supported, but not GLONASS or Galileo + * ARP ECEF-X = 1114104.5999 meters + * ARP ECEF-Y = -4850729.7108 meters + * ARP ECEF-Z = 3975521.4643 meters + */ + .test = { + 0xD3, 0x00, 0x13, 0x3E, 0xD7, 0xD3, 0x02, 0x02, + 0x98, 0x0E, 0xDE, 0xEF, 0x34, 0xB4, 0xBD, 0x62, + 0xAC, 0x09, 0x41, 0x98, 0x6F, 0x33, 0x36, 0x0B, + 0x98, + }, + .testlen = 25, + .garbage_offset = 0, + .type = RTCM3_PACKET, + }, + { + .legend = "RTCM104V3 type 1005 packet with 4th byte garbled", + .test = { + 0xD3, 0x00, 0x13, 0x3F, 0xD7, 0xD3, 0x02, 0x02, + 0x98, 0x0E, 0xDE, 0xEF, 0x34, 0xB4, 0xBD, 0x62, + 0xAC, 0x09, 0x41, 0x98, 0x6F, 0x33, 0x36, 0x0B, + 0x98, + }, + .testlen = 25, + .garbage_offset = 0, + .type = BAD_PACKET, + }, +}; +/*@ +initallelements -charint +usedef @*/ +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +/*@ -initallelements +charint -usedef @*/ +static struct map runontests[] = { + /* NMEA tests */ + { + .legend = "Double NMEA packet with checksum", + .test = "$GPVTG,308.74,T,,M,0.00,N,0.0,K*68\r\n$GPGGA,110534.994,4002.1425,N,07531.2585,W,0,00,50.0,172.7,M,-33.8,M,0.0,0000*7A\r\n", + .testlen = 118, + 0, + NMEA_PACKET, + }, +}; +/*@ +initallelements -charint +usedef @*/ +/* *INDENT-ON* */ + +static int packet_test(struct map *mp) +{ + struct gps_packet_t packet; + int failure = 0; + + packet_init(&packet); + /*@i@*/ memcpy(packet.inbufptr = packet.inbuffer, mp->test, mp->testlen); + packet.inbuflen = mp->testlen; + /*@ -compdef -uniondef -usedef -formatcode @*/ + packet_parse(&packet); + if (packet.type != mp->type) + printf("%2zi: %s test FAILED (packet type %d wrong).\n", + mp - singletests + 1, mp->legend, packet.type); + else if (memcmp + (mp->test + mp->garbage_offset, packet.outbuffer, + packet.outbuflen)) { + printf("%2zi: %s test FAILED (data garbled).\n", mp - singletests + 1, + mp->legend); + ++failure; + } else + printf("%2zi: %s test succeeded.\n", mp - singletests + 1, + mp->legend); +#ifdef DUMPIT + for (cp = packet.outbuffer; + cp < packet.outbuffer + packet.outbuflen; cp++) { + if (lexer->type != NMEA_PACKET) + (void)printf(" 0x%02x", *cp); + else if (*cp == '\r') + (void)fputs("\\r", stdout); + else if (*cp == '\n') + (void)fputs("\\n", stdout); + else if (isprint(*cp)) + (void)putchar(*cp); + else + (void)printf("\\x%02x", *cp); + } + (void)putchar('\n'); +#endif /* DUMPIT */ + /*@ +compdef +uniondef +usedef +formatcode @*/ + + return failure; +} + +static void runon_test(struct map *mp) +{ + struct gps_packet_t packet; + int nullfd = open("/dev/null", O_RDONLY); + ssize_t st; + + packet_init(&packet); + /*@i@*/ memcpy(packet.inbufptr = packet.inbuffer, mp->test, mp->testlen); + packet.inbuflen = mp->testlen; + /*@ -compdef -uniondef -usedef -formatcode @*/ + (void)fputs(mp->test, stdout); + do { + st = packet_get(nullfd, &packet); + printf("packet_parse() returned %zd\n", st); + } while (st > 0); + /*@ +compdef +uniondef +usedef +formatcode @*/ +} + +int main(int argc, char *argv[]) +{ + struct map *mp; + int failcount = 0; + int option, singletest = 0; + + verbose = 0; + while ((option = getopt(argc, argv, "t:v:")) != -1) { + switch (option) { + case 't': + singletest = atoi(optarg); + break; + case 'v': + verbose = atoi(optarg); + break; + } + } + + if (singletest) + failcount += packet_test(singletests + singletest - 1); + else { + (void)fputs("=== Packet identification tests\n ===", stdout); + for (mp = singletests; + mp < singletests + sizeof(singletests) / sizeof(singletests[0]); + mp++) + failcount += packet_test(mp); + (void)fputs("=== EOF with buffer nonempty test ===\n", stdout); + runon_test(&runontests[0]); + } + exit(failcount > 0 ? 1 : 0); +} diff --git a/test_trig.c b/test_trig.c new file mode 100644 index 0000000..760dd0e --- /dev/null +++ b/test_trig.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006 Chris Kuethe + * Copyright (c) 2009 BBN Technologies (Greg Troxel) + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This program provides a way to check sin/cos. + */ + +#include +#include + +int test_trig(void); + +int main(void) { + test_trig(); + + /* For now, no evaluation. */ + return 0; +} + +#define Deg2Rad(x) ((x) * (2 * M_PI / 360.0)) + +int test_trig(void) { + int i; + double arg; + double res; + + for (i = 0; i <= 360; i++) { + arg = Deg2Rad(i); + res = sin(arg); + printf("sin(%.30f) = %.30f\n", arg, res); + } + + for (i = 0; i <= 360; i++) { + arg = Deg2Rad(i); + res = cos(arg); + printf("cos(%.30f) = %.30f\n", arg, res); + } + + /* Always claim success. */ + return 0; +} diff --git a/timebase.h b/timebase.h new file mode 100644 index 0000000..9c8e045 --- /dev/null +++ b/timebase.h @@ -0,0 +1,51 @@ +#ifndef _GPSD_TIMEBASE_H_ +#define _GPSD_TIMEBASE_H_ + +/* timebase.h -- constants that will require patching over time */ +/* + * The current (fixed) leap-second correction, and the future Unix + * time after which to start hunting leap-second corrections from GPS + * subframe data if the GPS doesn't supply them any more readily. + * + * Deferring the check is a hack to speed up fix acquisition -- + * subframe data is bulky enough to substantially increase latency. + * To update LEAP_SECONDS and START_SUBFRAME, see the IERS leap-second + * bulletin page at: + * + * + * You can use the Python expression + * time.mktime(time.strptime(... , "%d %b %Y %H:%M:%S")) + * to generate an integer value for START_SUBFRAME, or use the + * -n option of devtools/leapsecond.py in the source distribution + */ + +/* + * This constant is used to get UTC from chipsets that report GPS time only. + * + * It's not a disaster if it's wrong; most such chips get the offset + * from some report abstracted from the subframe data, so their worst + * case is their time info will be incorrect for the remainder of an + * entire GPS message cycle (about 22 minutes) if you start gpsd up + * right after a leap-second. + * + * This value is only critical if the chipset gets GPS time only and + * not the offset; in this case gpsd will always report UTC that is exactly + * as incorrect as the constant. Currently this is true only for the + * Evermore chipset. + */ +#define LEAP_SECONDS 15 + +/* Date of next possible leap second adjustment, according to IERS + */ +#define START_SUBFRAME 1293857999 /* 31 Dec 2010 23:59:59 */ + +/* + * This is used only when an NMEA device issues a two-digit year in a GPRMC + * and there has been no previous ZDA to set the year. We used to + * query the system clock for this, but there's no good way to cope + * with the mess if the system clock has been zeroed. + */ +#define CENTURY_BASE 2000 + +/* timebase.h ends here */ +#endif /* _GPSD_TIMEBASE_H_ */ diff --git a/valgrind-audit b/valgrind-audit new file mode 100755 index 0000000..5c3420c --- /dev/null +++ b/valgrind-audit @@ -0,0 +1,101 @@ +#!/usr/bin/python2.6 +# +# This is a valgrind torture test for the gpsd daemon. +# It's not really expected to spot anything as long as we aren't using +# malloc and friends in the daemon. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +import sys, gps.fake + +debuglevel=1 + +invocation="valgrind --tool=memcheck --gen-suppressions=yes --leak-check=yes --suppressions=valgrind-suppressions" +test = gps.fake.TestSession(prefix=invocation, options="-D %d" % debuglevel) +test.progress = sys.stderr.write + +try: + test.spawn() + print "\n*** Test #1: Normal single-client-session behavior." + print "**** Add a GPS.\n" + gps1 = test.gps_add("test/daemon/bu303-moving.log") + + print "\n**** Add and remove a client.\n" + c1 = test.client_add("w\n") + test.gather(3) + test.client_remove(c1) + + print "\n**** Remove the GPS." + test.gps_remove(gps1) + print "*** Test #1 complete.\n" + test.wait(3) + + ###################################################################### + + print "\n*** Test #2: Successive non-overlapping client sessions." + print "**** Add a GPS.\n" + gps1 = test.gps_add("test/daemon/bu303-climbing.log") + + print "\n**** Add and remove first client.\n" + c1 = test.client_add("w\n") + test.gather(3) + test.client_remove(c1) + test.wait(3) + + print "\n**** Add and remove second client.\n" + c2 = test.client_add("w\n") + test.gather(3) + test.client_remove(c2) + test.wait(3) + + print "\n**** Remove the GPS." + test.gps_remove(gps1) + print "*** Test #2 complete.\n" + test.wait(3) + + ###################################################################### + + print "\n*** Test #3: Overlapping client sessions." + print "**** Add a GPS.\n" + gps1 = test.gps_add("test/daemon/bu303-climbing.log") + + print "\n**** Add first client.\n" + c1 = test.client_add("w\n") + test.gather(2) + print "\n**** Add second client.\n" + c2 = test.client_add("w\n") + test.gather(3) + print "\n**** Remove first client.\n" + test.client_remove(c1) + test.gather(2) + print "\n**** Remove second client.\n" + test.client_remove(c2) + + print "\n**** Remove the GPS." + test.gps_remove(gps1) + print "*** Test #3 complete.\n" + + ###################################################################### + + print "\n*** Test #4: GPS removed while client still active." + print "**** Add a GPS.\n" + gps1 = test.gps_add("test/daemon/bu303-moving.log") + + print "\n**** Add a client.\n" + c1 = test.client_add("w\n") + test.gather(3) + print "\n**** Remove the GPS." + test.gps_remove(gps1) + test.wait(3) + print "\n**** Remove the client.\n" + test.client_remove(c1) + + print "*** Test #4 complete.\n" +finally: + test.cleanup(); + +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:python +# End: diff --git a/valgrind-audit.in b/valgrind-audit.in new file mode 100644 index 0000000..3f76e81 --- /dev/null +++ b/valgrind-audit.in @@ -0,0 +1,101 @@ +#!@PYTHON@ +# +# This is a valgrind torture test for the gpsd daemon. +# It's not really expected to spot anything as long as we aren't using +# malloc and friends in the daemon. +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +import sys, gps.fake + +debuglevel=1 + +invocation="valgrind --tool=memcheck --gen-suppressions=yes --leak-check=yes --suppressions=valgrind-suppressions" +test = gps.fake.TestSession(prefix=invocation, options="-D %d" % debuglevel) +test.progress = sys.stderr.write + +try: + test.spawn() + print "\n*** Test #1: Normal single-client-session behavior." + print "**** Add a GPS.\n" + gps1 = test.gps_add("test/daemon/bu303-moving.log") + + print "\n**** Add and remove a client.\n" + c1 = test.client_add("w\n") + test.gather(3) + test.client_remove(c1) + + print "\n**** Remove the GPS." + test.gps_remove(gps1) + print "*** Test #1 complete.\n" + test.wait(3) + + ###################################################################### + + print "\n*** Test #2: Successive non-overlapping client sessions." + print "**** Add a GPS.\n" + gps1 = test.gps_add("test/daemon/bu303-climbing.log") + + print "\n**** Add and remove first client.\n" + c1 = test.client_add("w\n") + test.gather(3) + test.client_remove(c1) + test.wait(3) + + print "\n**** Add and remove second client.\n" + c2 = test.client_add("w\n") + test.gather(3) + test.client_remove(c2) + test.wait(3) + + print "\n**** Remove the GPS." + test.gps_remove(gps1) + print "*** Test #2 complete.\n" + test.wait(3) + + ###################################################################### + + print "\n*** Test #3: Overlapping client sessions." + print "**** Add a GPS.\n" + gps1 = test.gps_add("test/daemon/bu303-climbing.log") + + print "\n**** Add first client.\n" + c1 = test.client_add("w\n") + test.gather(2) + print "\n**** Add second client.\n" + c2 = test.client_add("w\n") + test.gather(3) + print "\n**** Remove first client.\n" + test.client_remove(c1) + test.gather(2) + print "\n**** Remove second client.\n" + test.client_remove(c2) + + print "\n**** Remove the GPS." + test.gps_remove(gps1) + print "*** Test #3 complete.\n" + + ###################################################################### + + print "\n*** Test #4: GPS removed while client still active." + print "**** Add a GPS.\n" + gps1 = test.gps_add("test/daemon/bu303-moving.log") + + print "\n**** Add a client.\n" + c1 = test.client_add("w\n") + test.gather(3) + print "\n**** Remove the GPS." + test.gps_remove(gps1) + test.wait(3) + print "\n**** Remove the client.\n" + test.client_remove(c1) + + print "*** Test #4 complete.\n" +finally: + test.cleanup(); + +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:python +# End: diff --git a/valgrind-suppressions b/valgrind-suppressions new file mode 100644 index 0000000..d31a609 --- /dev/null +++ b/valgrind-suppressions @@ -0,0 +1,22 @@ +# Suppress known C library errors in valgrind. +# This is good under gcc 3.4.2, glibc 2.3.4, using -g and -O2 +{ + suppress1 + Memcheck:Cond + fun:strlen + fun:vsnprintf + fun:gpsd_report + fun:main +} +{ + suppress2 + Memcheck:Value8 + fun:vfprintf + fun:vsnprintf + fun:gpsd_report + fun:sirf_parse + fun:sirfbin_parse_input + fun:gpsd_poll + fun:main +} + diff --git a/xgps b/xgps new file mode 100755 index 0000000..79902c2 --- /dev/null +++ b/xgps @@ -0,0 +1,682 @@ +#!/usr/bin/env python +''' +xgps -- test client for gpsd + +usage: xgps [-D level] [-hV?] [-l degmfmt] [-u units] [server[:port[:device]]] +''' + +gui_about = '''\ +This is xgps, a test client for the gpsd daemon. + +By Eric S. Raymond for the GPSD project, December 2009 +''' +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. + +import sys, os, re, math, time, exceptions, getopt, socket + +import gobject, pygtk +pygtk.require('2.0') +import gtk + +import gps, gps.clienthelpers + +class unit_adjustments: + "Encapsulate adjustments for unit systems." + def __init__(self, units=None): + self.altfactor = gps.METERS_TO_FEET + self.altunits = "ft" + self.speedfactor = gps.MPS_TO_MPH + self.speedunits = "mph" + if units is None: + units = gps.clienthelpers.gpsd_units() + if units in (gps.clienthelpers.unspecified, gps.clienthelpers.imperial, "imperial", "i"): + pass + elif units in (gps.clienthelpers.nautical, "nautical", "n"): + self.altfactor = gps.METERS_TO_FEET + self.altunits = "ft" + self.speedfactor = gps.MPS_TO_KNOTS + self.speedunits = "knots" + elif units in (gps.clienthelpers.metric, "metric", "m"): + self.altfactor = 1 + self.altunits = "m" + self.speedfactor = gps.MPS_TO_KPH + self.speedunits = "kph" + else: + raise ValueError # Should never happen + +class SkyView(gtk.DrawingArea): + "Satellite skyview, encapsulates pygtk's draw-on-expose behavior." + # See + HORIZON_PAD = 20 # How much whitespace to leave around horizon + SAT_RADIUS = 5 # Diameter of satellite circle + GPS_PRNMAX = 32 # above this number are SBAS satellites + def __init__(self): + gtk.DrawingArea.__init__(self) + self.set_size_request(400, 400) + self.gc = None # initialized in realize-event handler + self.width = 0 # updated in size-allocate handler + self.height = 0 # updated in size-allocate handler + self.connect('size-allocate', self.on_size_allocate) + self.connect('expose-event', self.on_expose_event) + self.connect('realize', self.on_realize) + self.pangolayout = self.create_pango_layout("") + self.satellites = [] + + def on_realize(self, widget): + self.gc = widget.window.new_gc() + self.gc.set_line_attributes(1, gtk.gdk.LINE_SOLID, + gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) + + def on_size_allocate(self, widget, allocation): + self.width = allocation.width + self.height = allocation.height + self.diameter = min(self.width, self.height) - SkyView.HORIZON_PAD + + def set_color(self, spec): + "Set foreground color for draweing." + self.gc.set_rgb_fg_color(gtk.gdk.color_parse(spec)) + + def draw_circle(self, widget, x, y, diam, filled=False): + "Draw a circle centered on the specified midpoint." + widget.window.draw_arc(self.gc, filled, + x - diam / 2, y - diam / 2, + diam, diam, 0, 360 * 64) + + def draw_line(self, widget, x1, y1, x2, y2): + "Draw a line between specified points." + widget.window.draw_lines(self.gc, [(x1, y1), (x2, y2)]) + + def draw_square(self, widget, x, y, diam, filled=False): + "Draw a square centered on the specified midpoint." + widget.window.draw_rectangle(self.gc, filled, + x - diam / 2, y - diam / 2, + diam, diam) + + def draw_string(self, widget, x, y, letter, centered=True): + "Draw a letter on the skyview." + self.pangolayout.set_text(letter) + if centered: + (w, h) = self.pangolayout.get_pixel_size() + x -= w/2 + y -= h/2 + self.window.draw_layout(self.gc, x, y, self.pangolayout) + + def pol2cart(self, az, el): + "Polar to Cartesian coordinates within the horizon circle." + az *= (math.pi/180) # Degrees to radians + # Exact spherical projection would be like this: + # el = sin((90.0 - el) * DEG_2_RAD); + el = ((90.0 - el) / 90.0); + xout = int((self.width / 2) + math.sin(az) * el * (self.diameter / 2)) + yout = int((self.height / 2) - math.cos(az) * el * (self.diameter / 2)) + return (xout, yout) + + def on_expose_event(self, widget, event): + self.set_color("white") + widget.window.draw_rectangle(self.gc, True, 0,0, self.width,self.height) + # The zenith marker + self.set_color("gray") + self.draw_circle(widget, self.width / 2, self.height / 2, 6) + # The circle corresponding to 45 degrees elevation. + # There are two ways we could plot this. Projecting the sphere + # on the display plane, the circle would have a diameter of + # sin(45) ~ 0.7. But the naive linear mapping, just splitting + # the horizon diameter in half, seems to work better visually. + self.draw_circle(widget, self.width / 2, self.height / 2, + int(self.diameter * 0.5)) + self.set_color("black") + # The horizon circle + self.draw_circle(widget, self.width / 2, self.height / 2, + self.diameter) + self.set_color("gray") + (x1, y1) = self.pol2cart(0, 0) + (x2, y2) = self.pol2cart(180, 0) + self.draw_line(widget, x1, y1, x2, y2) + (x1, y1) = self.pol2cart(90, 0) + (x2, y2) = self.pol2cart(270, 0) + self.draw_line(widget, x1, y1, x2, y2) + # The compass-point letters + self.set_color("black") + (x, y) = self.pol2cart(0, 0) + self.draw_string(widget, x, y+10, "N") + (x, y) = self.pol2cart(90, 0) + self.draw_string(widget, x-10, y, "E") + (x, y) = self.pol2cart(180, 0) + self.draw_string(widget, x, y-10, "S") + (x, y) = self.pol2cart(270, 0) + self.draw_string(widget, x+10, y, "W") + # The satellites + for sat in self.satellites: + (x, y) = self.pol2cart(sat.az, sat.el) + if sat.ss < 10: + self.set_color("Black") + elif sat.ss < 30: + self.set_color("Red") + elif sat.ss < 35: + self.set_color("Yellow"); + elif sat.ss < 40: + self.set_color("Green3"); + else: + self.set_color("Green1"); + if sat.PRN > SkyView.GPS_PRNMAX: + self.draw_square(widget, + x-SkyView.SAT_RADIUS, y-SkyView.SAT_RADIUS, + 2 * SkyView.SAT_RADIUS + 1, sat.used); + else: + self.draw_circle(widget, + x-SkyView.SAT_RADIUS, y-SkyView.SAT_RADIUS, + 2 * SkyView.SAT_RADIUS + 1, sat.used); + self.set_color("Black") + self.draw_string(widget, x, y, str(sat.PRN), centered=False) + def redraw(self, satellites): + "Redraw the skyview." + self.satellites = satellites + self.queue_draw() + +class AISView: + "Encapsulate store and view objects for watching AIS data." + AIS_ENTRIES = 10 + DWELLTIME = 360 + def __init__(self, deg_type): + "Initialize the store and view." + self.deg_type = deg_type + self.name_to_mmsi = {} + self.named = {} + self.store = gtk.ListStore(str,str,str,str,str,str) + self.widget = gtk.ScrolledWindow() + self.widget.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.view = gtk.TreeView(model=self.store) + self.widget.set_size_request(-1, 300) + self.widget.add_with_viewport(self.view) + + for (i, label) in enumerate(('#', 'Name:','Callsign:','Destination:', "Lat/Lon:", "Information")): + column = gtk.TreeViewColumn(label) + renderer = gtk.CellRendererText() + column.pack_start(renderer) + column.add_attribute(renderer, 'text', i) + self.view.append_column(column) + + def enter(self, ais, name): + "Add a named object (ship or station) to the store." + if ais.mmsi in self.named: + return False + else: + ais.entry_time = time.time() + self.named[ais.mmsi] = ais + self.name_to_mmsi[name] = ais.mmsi + # Garbage-collect old entries + try: + for i in range(len(self.store)): + here = self.store.get_iter(i) + name = self.store.get_value(here, 1) + mmsi = self.name_to_mmsi[name] + if self.named[mmsi].entry_time < time.time() - AISView.DWELLTIME: + del self.named[mmsi] + if name in self.name_to_mmsi: + del self.name_to_mmsi[name] + self.store.remove(here) + except (ValueError, KeyError): # Invalid TreeIters throw these + pass + return True + + def latlon(self, lat, lon): + "Latitude/longitude display in nice format." + if lat < 0: + latsuff = "S" + elif lat > 0: + latsuff = "N" + else: + latsuff = "" + lat = abs(lat) + lat = gps.clienthelpers.deg_to_str(self.deg_type, lat) + if lon < 0: + lonsuff = "W" + elif lon > 0: + lonsuff = "E" + else: + lonsuff = "" + lon = abs(lon) + lon = gps.clienthelpers.deg_to_str(gps.clienthelpers.deg_ddmmss, lon) + return lat + latsuff + "/" + lon + lonsuff + + def update(self, ais): + "Update the AIS data fields." + if ais.type in (1, 2, 3, 18): + if ais.mmsi in self.named: + for i in range(len(self.store)): + here = self.store.get_iter(i) + name = self.store.get_value(here, 1) + if name in self.name_to_mmsi: + mmsi = self.name_to_mmsi[name] + if mmsi == ais.mmsi: + latlon = self.latlon(ais.lat, ais.lon) + self.store.set_value(here, 4, latlon) + elif ais.type == 4: + if self.enter(ais, ais.mmsi): + where = self.latlon(ais.lat, ais.lon) + self.store.prepend( + (ais.type, ais.mmsi, "(shore)", ais.timestamp, where, ais.epfd)) + elif ais.type == 5: + if self.enter(ais, ais.shipname): + self.store.prepend( + (ais.type, ais.shipname, ais.callsign, ais.destination, "", ais.shiptype)) + elif ais.type == 12: + sender = ais.mmsi + if sender in self.named: + sender = self.named[sender].shipname + recipient = ais.dest_mmsi + if recipient in self.named and hasattr(self.named[recipient], "shipname"): + recipient = self.named[recipient].shipname + self.store.prepend( + (ais.type, sender, "", recipient, "", ais.text)) + elif ais.type == 14: + sender = ais.mmsi + if sender in self.named: + sender = self.named[sender].shipname + self.store.prepend( + (ais.type, sender, "", "(broadcast)", "", ais.text)) + elif ais.type in (19, 24): + if self.enter(ais, ais.shipname): + self.store.prepend( + (ais.type, ais.shipname, "(class B)", "", "", ais.shiptype)) + elif ais.type == 21: + if self.enter(ais, ais.name): + where = self.latlon(ais.lat, ais.lon) + self.store.prepend( + (ais.type, ais.name, "(%s navaid)" % ais.epfd, "", where, ais.aid_type)) + +class Base: + gpsfields = ( + # First column + ("Time", lambda s, r: s.update_time(r)), + ("Latitude", lambda s, r: s.update_latitude(r)), + ("Longitude", lambda s, r: s.update_longitude(r)), + ("Altitude", lambda s, r: s.update_altitude(r)), + ("Speed", lambda s, r: s.update_speed(r)), + ("Climb", lambda s, r: s.update_climb(r)), + ("Track", lambda s, r: s.update_track(r)), + # Second column + ("Status", lambda s, r: s.update_status(r)), + ("EPX", lambda s, r: s.update_err(r, "epx")), + ("EPY", lambda s, r: s.update_err(r, "epy")), + ("EPV", lambda s, r: s.update_err(r, "epv")), + ("EPS", lambda s, r: s.update_err(r, "eps")), + ("EPC", lambda s, r: s.update_err(r, "epc")), + ("EPD", lambda s, r: s.update_err(r, "epd")), + ) + def __init__(self, deg_type): + self.deg_type = deg_type + self.conversions = unit_adjustments() + self.saved_mode = -1 + self.ais_latch = False + + self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.window.set_title("xgps") + self.window.connect("delete_event", self.delete_event) + self.window.set_resizable(False) + + vbox = gtk.VBox(False, 0) + self.window.add(vbox) + + self.window.connect("destroy", lambda w: gtk.main_quit()) + + self.uimanager = gtk.UIManager() + self.accelgroup = self.uimanager.get_accel_group() + self.window.add_accel_group(self.accelgroup) + self.actiongroup = gtk.ActionGroup('xgps') + self.actiongroup.add_actions( + [('Quit', gtk.STOCK_QUIT, '_Quit', None, + 'Quit the Program', lambda w: gtk.main_quit()), + ('File', None, '_File'), + ('View', None, '_View'), + ('Units', None, '_Units')]) + self.actiongroup.add_toggle_actions( + [('Skyview', None, '_Skyview', 's', + 'Enable Skyview', lambda a: self.view_toggle(a)), + ('Responses', None, '_Responses', 'r', + 'Enable Response Reports', lambda a: self.view_toggle(a)), + ('GPS', None, '_GPS Data', 'g', + 'Enable GPS Data', lambda a: self.view_toggle(a)), + ('AIS', None, '_AIS Data', 'a', + 'Enable AIS Data', lambda a: self.view_toggle(a)), + ]) + self.actiongroup.add_radio_actions( + [('Imperial', None, '_Imperial', 'i', + 'Imperial units', 0), + ('Nautical', None, '_Nautical', 'n', + 'Nautical units', 1), + ('Metric', None, '_Metric', 'm', + 'Metric Units', 2), + ], 0, lambda a, v: self.set_units(['i', 'n', 'm'][a.get_current_value()])) + self.uimanager.insert_action_group(self.actiongroup, 0) + self.uimanager.add_ui_from_string(''' + + + + + + + + + + + + + + + + + + +''') + self.uimanager.get_widget('/MenuBar/View/Skyview').set_active(True) + self.uimanager.get_widget('/MenuBar/View/Responses').set_active(True) + self.uimanager.get_widget('/MenuBar/View/GPS').set_active(True) + self.uimanager.get_widget('/MenuBar/View/AIS').set_active(True) + menubar = self.uimanager.get_widget('/MenuBar') + vbox.pack_start(menubar, False) + + self.satbox = gtk.HBox(False, 0) + vbox.add(self.satbox) + + skyframe = gtk.Frame(label="Satellite List") + self.satbox.add(skyframe) + + self.satlist = gtk.ListStore(str,str,str,str,str) + view = gtk.TreeView(model=self.satlist) + + for (i, label) in enumerate(('PRN:','Elev:','Azim:','SNR:','Used:')): + column = gtk.TreeViewColumn(label) + renderer = gtk.CellRendererText() + column.pack_start(renderer) + column.add_attribute(renderer, 'text', i) + view.append_column(column) + + self.row_iters = [] + for i in range(gps.MAXCHANNELS): + self.satlist.append(["", "", "", "", ""]) + self.row_iters.append(self.satlist.get_iter(i)) + + skyframe.add(view) + + viewframe = gtk.Frame(label="Skyview") + self.satbox.add(viewframe) + self.skyview = SkyView() + viewframe.add(self.skyview) + + self.rawdisplay = gtk.Entry() + self.rawdisplay.set_editable(False) + vbox.add(self.rawdisplay) + + self.dataframe = gtk.Frame(label="GPS data") + datatable = gtk.Table(7, 4, False) + self.dataframe.add(datatable) + gpswidgets = [] + for i in range(len(Base.gpsfields)): + if i < len(Base.gpsfields) / 2: + colbase = 0 + else: + colbase = 2 + label = gtk.Label(Base.gpsfields[i][0] + ": ") + # Wacky way to force right alignment + label.set_alignment(xalign=1, yalign=0.5) + datatable.attach(label, colbase, colbase+1, i % 7, i % 7 + 1) + entry = gtk.Entry() + datatable.attach(entry, colbase+1, colbase+2, i % 7, i % 7 + 1) + gpswidgets.append(entry) + vbox.add(self.dataframe) + + self.aisbox = gtk.HBox(False, 0) + vbox.add(self.aisbox) + + aisframe = gtk.Frame(label="AIS Data") + self.aisbox.add(aisframe) + + self.aisview = AISView(self.deg_type) + aisframe.add(self.aisview.widget) + + self.window.show_all() + # Hide the AIS window util user selects it. + self.uimanager.get_widget('/MenuBar/View/AIS').set_active(False) + self.aisbox.hide() + + self.view_name_to_widget = \ + {"Skyview": self.satbox, + "Responses": self.rawdisplay, + "GPS": self.dataframe, + "AIS": self.aisbox} + + # Discard field labels and associate data hooks with their widgets + Base.gpsfields = map(lambda ((label, hook), widget): (hook, widget), + zip(Base.gpsfields, gpswidgets)) + + def view_toggle(self, action): + #print "View toggle:", action.get_active(), action.get_name() + if hasattr(self, 'view_name_to_widget'): + if action.get_active(): + self.view_name_to_widget[action.get_name()].show() + else: + self.view_name_to_widget[action.get_name()].hide() + # The effect we're after is to make the top-level window + # resize itself to fit when we show or hide widgets. + # This is undocumented magic to do that. + self.window.resize(1, 1) + + def set_satlist_field(self, row, column, value): + "Set a specified field in the satellite list." + try: + self.satlist.set_value(self.row_iters[row], column, value) + except IndexError: + sys.stderr.write("xgps: channel = %d, MAXCHANNELS = %d\n" % (row, gps.MAXCHANNELS)) + + def delete_event(self, widget, event, data=None): + gtk.main_quit() + return False + + # State updates + + def update_time(self, data): + if hasattr(data, "time"): + return gps.isotime(data.time) + else: + return "n/a" + + def update_latitude(self, data): + if data.mode >= gps.MODE_2D: + lat = gps.clienthelpers.deg_to_str(self.deg_type, abs(data.lat)) + if data.lat < 0: + ns = 'S' + else: + ns = 'N' + return "%s %s" % (lat, ns) + else: + return "n/a" + + def update_longitude(self, data): + if data.mode >= gps.MODE_2D: + lon = gps.clienthelpers.deg_to_str(self.deg_type, abs(data.lon)) + if data.lon < 0: + ew = 'W' + else: + ew = 'E' + return "%s %s" % (lon, ew) + else: + return "n/a" + + def update_altitude(self, data): + if data.mode >= gps.MODE_3D: + return "%.3f %s" % ( + data.alt * self.conversions.altfactor, + self.conversions.altunits) + else: + return "n/a" + + def update_speed(self, data): + if hasattr(data, "speed"): + return "%.3f %s" % ( + data.speed * self.conversions.speedfactor, + self.conversions.speedunits) + else: + return "n/a" + + def update_climb(self, data): + if hasattr(data, "climb"): + return "%.3f %s" % ( + data.climb * self.conversions.speedfactor, + self.conversions.speedunits) + else: + return "n/a" + + def update_track(self, data): + if hasattr(data, "track"): + return gps.clienthelpers.deg_to_str(self.deg_type, abs(data.track)) + else: + return "n/a" + + def update_err(self, data, errtype): + if hasattr(data, errtype): + return "%.3f %s" % ( + getattr(data, errtype) * self.conversions.altfactor, + self.conversions.altunits) + else: + return "n/a" + + def update_status(self, data): + if data.mode == gps.MODE_2D: + status = "2D FIX" + elif data.mode == gps.MODE_3D: + status = "3D FIX" + else: + status = "NO FIX" + if data.mode != self.saved_mode: + self.last_transition = time.time() + self.saved_mode = data.mode + return status + " (%d secs)" % (time.time() - self.last_transition) + + def update_gpsdata(self, tpv): + "Update the GPS data fields." + for (hook, widget) in Base.gpsfields: + if hook: # Remove this guard when we have all hooks + widget.set_text(hook(self, tpv)) + + def update_skyview(self, data): + "Update the satellite list and skyview." + satellites = data.satellites + for (i, satellite) in enumerate(satellites): + self.set_satlist_field(i, 0, satellite.PRN) + self.set_satlist_field(i, 1, satellite.el) + self.set_satlist_field(i, 2, satellite.az) + self.set_satlist_field(i, 3, satellite.ss) + yesno = 'N' + if satellite.used: + yesno = 'Y' + self.set_satlist_field(i, 4, yesno) + for i in range(len(satellites), gps.MAXCHANNELS): + for j in range(0, 5): + self.set_satlist_field(i, j, "") + self.skyview.redraw(satellites) + + # Preferences + + def set_units(self, system): + "Change the display units." + self.conversions = unit_adjustments(system) + + # I/O monitoring and gtk housekeeping + + def watch(self, daemon, device): + "Set up monitoring of a daemon instance." + self.daemon = daemon + self.device = device + gobject.io_add_watch(daemon.sock, gobject.IO_IN, self.handle_response) + gobject.io_add_watch(daemon.sock, gobject.IO_ERR, self.handle_hangup) + gobject.io_add_watch(daemon.sock, gobject.IO_HUP, self.handle_hangup) + + def handle_response(self, source, condition): + "Handle ordinary I/O ready condition from the daemon." + if self.daemon.poll() == -1: + self.handle_hangup(source, condition) + if self.daemon.valid & gps.PACKET_SET: + if self.device and self.device != self.daemon.data["device"]: + return True + self.rawdisplay.set_text(self.daemon.response.strip()) + if self.daemon.data["class"] == "SKY": + self.update_skyview(self.daemon.data) + elif self.daemon.data["class"] == "TPV": + self.update_gpsdata(self.daemon.data) + elif self.daemon.data["class"] == "AIS": + self.aisview.update(self.daemon.data) + if self.ais_latch == False: + self.ais_latch = True + self.uimanager.get_widget('/MenuBar/View/AIS').set_active(True) + self.aisbox.show() + + return True + + def handle_hangup(self, source, condition): + "Handle hangup condition from the daemon." + w = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, + flags=gtk.DIALOG_DESTROY_WITH_PARENT, + buttons=gtk.BUTTONS_CANCEL) + w.connect("destroy", lambda w: gtk.main_quit()) + w.set_markup("gpsd has stopped sending data.") + w.run() + gtk.main_quit() + return True + + def main(self): + gtk.main() + +if __name__ == "__main__": + (options, arguments) = getopt.getopt(sys.argv[1:], "D:hl:u:V?", + ['verbose']) + debug = 0 + degreefmt = 'd' + unit_system = None + for (opt, val) in options: + if opt in '-D': + debug = int(val) + elif opt == '-l': + degreeformat = val + elif opt == '-u': + unit_system = val + elif opt in ('-?', '-h', '--help'): + print __doc__ + sys.exit(0) + elif opt == 'V': + sys.stderr.write("xgps 1.0\n") + sys.exit(0) + + degreefmt = {'d':gps.clienthelpers.deg_dd, + 'm':gps.clienthelpers.deg_ddmm, + 's':gps.clienthelpers.deg_ddmmss}[degreefmt] + + (host, port, device) = ("localhost", "2947", None) + if len(arguments): + args = arguments[0].split(":") + if len(args) >= 1: + host = args[0] + if len(args) >= 2: + port = args[1] + if len(args) >= 3: + device = args[2] + + base = Base(deg_type=degreefmt) + base.set_units(unit_system) + try: + daemon = gps.gps(host=host, + port=port, + mode=gps.WATCH_ENABLE|gps.WATCH_JSON|gps.WATCH_SCALED, + verbose=debug) + base.watch(daemon, device) + base.main() + except socket.error: + w = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, + flags=gtk.DIALOG_DESTROY_WITH_PARENT, + buttons=gtk.BUTTONS_CANCEL) + w.set_markup("gpsd is not running.") + w.run() + w.destroy() + diff --git a/xgpsspeed b/xgpsspeed new file mode 100755 index 0000000..7f12b8d --- /dev/null +++ b/xgpsspeed @@ -0,0 +1,455 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*- + +import pygtk +pygtk.require('2.0') +import gtk +import cairo +import gobject +from math import pi +from math import cos +from math import sin +from socket import error as SocketError + +__author__ = 'Robin Wittler ' +__license__ = 'BSD' +__version__ = '0.0.7' +# BSD terms apply: see the file COPYING in the distribution root for details. + +#TODO +# add getopts and handle it +# add configparser +# add a config menu entry +# write unit tests! +# testing! +# cleanup and sanitize code + +class Speedometer(gtk.DrawingArea): + def __init__(self, speed_unit=None): + gtk.DrawingArea.__init__(self) + self.connect('expose_event', self.expose_event) + self.long_ticks = (2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8) + self.short_ticks = (0.1, 0.2, 0.3, 0.4, 0.6, 0.7, 0.8, 0.9) + self.long_inset = lambda x: 0.1 * x + self.middle_inset = lambda x: self.long_inset(x) / 1.5 + self.short_inset = lambda x: self.long_inset(x) / 3 + self.res_div = 10.0 + self.res_div_mul = 1 + self.last_speed = 0 + self.MPS_TO_KPH = 3.6000000000000001 + self.MPS_TO_MPH = 2.2369363 + self.MPS_TO_KNOTS = 1.9438445 + self.MPH_UNIT_LABEL = 'mph' + self.KPH_UNIT_LABEL = 'kmh' + self.KNOTS_UNIT_LABEL = 'knots' + self.conversions = { + self.MPH_UNIT_LABEL: self.MPS_TO_MPH, + self.KPH_UNIT_LABEL: self.MPS_TO_KPH, + self.KNOTS_UNIT_LABEL: self.MPS_TO_KNOTS + } + self.speed_unit = speed_unit or self.MPH_UNIT_LABEL + if not self.speed_unit in self.conversions: + raise TypeError( + '%s is not a valid speed unit' + %(repr(speed_unit)) + ) + self.nums = { + -8: 0, + -7: 10, + -6: 20, + -5: 30, + -4: 40, + -3: 50, + -2: 60, + -1: 70, + 0: 80, + 1: 90, + 2: 100 + } + + + def expose_event(self, widget, event, data=None): + self.cr = self.window.cairo_create() + self.cr.rectangle( + event.area.x, + event.area.y, + event.area.width, + event.area.height + ) + self.cr.clip() + x, y = self.get_x_y() + width, height = self.window.get_size() + radius = self.get_radius(width, height) + self.cr.set_line_width(radius / 100) + self.draw_arc_and_ticks(width, height, radius, x, y) + self.draw_needle(self.last_speed, radius, x, y) + self.draw_speed_text(self.last_speed, radius, x, y) + + def draw_arc_and_ticks(self, width, height, radius, x, y): + self.cr.set_source_rgb(1.0, 1.0, 1.0) + self.cr.rectangle(0, 0, width, height) + self.cr.fill() + self.cr.set_source_rgb(0.0, 0.0, 0.0) + + #draw the speedometer arc + self.cr.arc_negative( + x, + y, + radius, + self.degrees_to_radians(60), + self.degrees_to_radians(120) + ) + self.cr.stroke() + long_inset = self.long_inset(radius) + middle_inset = self.middle_inset(radius) + short_inset = self.short_inset(radius) + + #draw the ticks + for i in self.long_ticks: + self.cr.move_to( + x + (radius - long_inset) * cos(i * pi / 6.0), + y + (radius - long_inset) * sin(i * pi / 6.0) + ) + self.cr.line_to( + x + (radius + (self.cr.get_line_width() / 2)) * cos(i * pi + / 6.0), + y + (radius + (self.cr.get_line_width() / 2)) * sin(i * pi + / 6.0) + ) + self.cr.select_font_face( + 'Georgia', + cairo.FONT_SLANT_NORMAL, + ) + self.cr.set_font_size(radius / 10) + self.cr.save() + _num = str(self.nums.get(i) * self.res_div_mul) + ( + x_bearing, + y_bearing, + t_width, + t_height, + x_advance, + y_advance + ) = self.cr.text_extents(_num) + + if i in (-8, -7, -6, -5, -4): + self.cr.move_to( + (x + (radius - long_inset - (t_width / 2)) * cos(i * pi + / 6.0)), + (y + (radius - long_inset - (t_height * 2)) * sin(i * pi + / 6.0)) + ) + elif i in (-2, -1, 0, 2, 1): + self.cr.move_to( + (x + (radius - long_inset - (t_width * 1.5 )) * cos(i * pi + / 6.0)), + (y + (radius - long_inset - (t_height * 2 )) * sin(i * pi + / 6.0)) + ) + elif i in (-3,): + self.cr.move_to( + (x - t_width / 2), (y - radius + + self.long_inset(radius) * 2 + t_height) + ) + self.cr.show_text(_num) + self.cr.restore() + + if i != self.long_ticks[0]: + self.cr.move_to( + x + (radius - middle_inset) * cos((i + 0.5) * pi / 6.0), + y + (radius - middle_inset) * sin((i + 0.5) * pi / 6.0) + ) + self.cr.line_to( + x + (radius + (self.cr.get_line_width() / 2)) * cos((i + + 0.5) * pi / 6.0), + y + (radius + (self.cr.get_line_width() / 2)) * sin((i + + 0.5) * pi / 6.0) + ) + + for z in self.short_ticks: + if i < 0: + self.cr.move_to( + x + (radius - short_inset) * cos((i + z) * pi / 6.0), + y + (radius - short_inset) * sin((i + z) * pi / 6.0) + ) + self.cr.line_to( + x + (radius + (self.cr.get_line_width() / 2)) * cos((i + + z) * pi / 6.0), + y + (radius + (self.cr.get_line_width() / 2)) * sin((i + + z) * pi / 6.0) + ) + else: + self.cr.move_to( + x + (radius - short_inset) * cos((i - z) * pi / 6.0), + y + (radius - short_inset) * sin((i - z) * pi / 6.0) + ) + self.cr.line_to( + x + (radius + (self.cr.get_line_width() / 2)) * cos((i + - z) * pi / 6.0), + y + (radius + (self.cr.get_line_width() / 2)) * sin((i + - z) * pi / 6.0) + ) + self.cr.stroke() + + def draw_needle(self, speed, radius, x, y): + self.cr.save() + inset = self.long_inset(radius) + speed = speed * self.conversions.get(self.speed_unit) + speed = speed / (self.res_div * self.res_div_mul) + actual = self.long_ticks[-1] + speed + if actual > self.long_ticks[0]: + #TODO test this in real conditions! ;) + self.res_div_mul += 1 + speed = speed / (self.res_div * self.res_div_mul) + actual = self.long_ticks[-1] + speed + self.cr.move_to(x, y) + self.cr.line_to( + x + (radius - (2 * inset)) * cos(actual * pi / 6.0), + y + (radius - (2 * inset)) * sin(actual * pi / 6.0) + ) + self.cr.stroke() + self.cr.restore() + + def draw_speed_text(self, speed, radius, x, y): + self.cr.save() + speed = '%.2f %s' %( + speed * self.conversions.get(self.speed_unit), + self.speed_unit + ) + self.cr.select_font_face( + 'Georgia', + cairo.FONT_SLANT_NORMAL, + #cairo.FONT_WEIGHT_BOLD + ) + self.cr.set_font_size(radius / 10) + x_bearing, y_bearing, t_width, t_height = self.cr.text_extents(speed)[:4] + self.cr.move_to((x - t_width / 2), (y + radius) - self.long_inset(radius)) + self.cr.show_text(speed) + self.cr.restore() + + + def degrees_to_radians(self, degrees): + return ((pi / 180) * degrees) + + def radians_to_degrees(self, radians): + return ((pi * 180) / radians) + + def get_x_y(self): + rect = self.get_allocation() + x = (rect.x + rect.width / 2.0) + y = (rect.y + rect.height / 2.0) - 20 + return x, y + + def get_radius(self, width, height): + return min(width / 2.0, height / 2.0) - 20 + + +class Main(object): + def __init__(self, host='localhost', port='2947', device=None, debug=0, speed_unit=None): + self.host = host + self.port = port + self.device = device + self.debug = debug + self.speed_unit = speed_unit + self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.window.set_title('xgpsspeed') + self.widget = Speedometer(speed_unit=self.speed_unit) + self.window.connect('delete_event', self.delete_event) + self.window.connect('destroy', self.destroy) + self.widget.show() + vbox = gtk.VBox(False, 0) + self.window.add(vbox) + + self.window.present() + self.uimanager = gtk.UIManager() + self.accelgroup = self.uimanager.get_accel_group() + self.window.add_accel_group(self.accelgroup) + self.actiongroup = gtk.ActionGroup('gpsspeed-ng') + self.actiongroup.add_actions( + [('Quit', gtk.STOCK_QUIT, '_Quit', None, + 'Quit the Program', lambda x: gtk.main_quit()), + ('File', None, '_File'), + ('Units', None, '_Units')] + ) + self.actiongroup.add_radio_actions( + [('Imperial', None, '_Imperial', 'i', + 'Imperial Units', 0), + ('Metric', None, '_Metric', 'm', + 'Metrical Units', 1), + ('Nautical', None, '_Nautical', 'n', + 'Nautical Units', 2) + ], + 0, lambda a, v: setattr(self.widget, 'speed_unit', ['mph', + 'kmh', 'knots'][a.get_current_value()]) + ) + + self.uimanager.insert_action_group(self.actiongroup, 0) + self.uimanager.add_ui_from_string(''' + + + + + + + + + + + + +''') + self.active_unit_map = { + 'mph': '/MenuBar/Units/Imperial', + 'kmh': '/MenuBar/Units/Metric', + 'knots': '/MenuBar/Units/Nautical' + } + menubar = self.uimanager.get_widget('/MenuBar') + self.uimanager.get_widget( + self.active_unit_map.get(self.speed_unit) + ).set_active(True) + vbox.pack_start(menubar, False, False, 0) + vbox.add(self.widget) + self.window.show_all() + + def watch(self, daemon, device): + self.daemon = daemon + self.device = device + gobject.io_add_watch(daemon.sock, gobject.IO_IN, self.handle_response) + gobject.io_add_watch(daemon.sock, gobject.IO_ERR, self.handle_hangup) + gobject.io_add_watch(daemon.sock, gobject.IO_HUP, self.handle_hangup) + return True + + def handle_response(self, source, condition): + if self.daemon.poll() == -1: + self.handle_hangup(source, condition) + if self.daemon.data['class'] == 'TPV': + self.update_speed(self.daemon.data) + return True + + def handle_hangup(self, source, condition): + w = gtk.MessageDialog( + type=gtk.MESSAGE_ERROR, + flags=gtk.DIALOG_DESTROY_WITH_PARENT, + buttons=gtk.BUTTONS_OK + ) + w.connect("destroy", lambda w: gtk.main_quit()) + w.set_title('gpsd error') + w.set_markup("gpsd has stopped sending data.") + w.run() + gtk.main_quit() + return True + + def update_speed(self, data): + if hasattr(data, 'speed'): + self.widget.last_speed = data.speed + self.widget.queue_draw() + + def delete_event(self, widget, event, data=None): + #TODO handle all cleanup operations here + return False + + def destroy(self, widget, data=None): + gtk.main_quit() + + def run(self): + import gps + try: + daemon = gps.gps( + host = self.host, + port = self.port, + mode = gps.WATCH_ENABLE|gps.WATCH_JSON|gps.WATCH_SCALED, + verbose = self.debug + ) + self.watch(daemon, self.device) + gtk.main() + except SocketError: + w = gtk.MessageDialog( + type=gtk.MESSAGE_ERROR, + flags=gtk.DIALOG_DESTROY_WITH_PARENT, + buttons=gtk.BUTTONS_OK + ) + w.set_title('socket error') + w.set_markup( + "could not connect to gpsd socket. make sure gpsd is running." + ) + w.run() + w.destroy() + except KeyboardInterrupt: + self.window.emit('delete_event', gtk.gdk.Event(gtk.gdk.NOTHING)) + + +if __name__ == '__main__': + from sys import argv, exit + from os.path import basename + from optparse import OptionParser + prog = basename(argv[0]) + usage = ('%s [-V|--version] [-h|--help] [--debug] [--host] ' + + '[--port] [--device] [--speedunits {[mph] [kmh] [knots]}] ' + + '[host [:port [:device]]]') %(prog) + epilog = 'BSD terms apply: see the file COPYING in the distribution root for details.' + version = '%s %s' %(prog, __version__) + + parser = OptionParser(usage=usage, epilog=epilog) + parser.add_option( + '--host', + dest='host', + default='localhost', + help='The host to connect. [Default localhost]' + ) + parser.add_option( + '--port', + dest='port', + default='2947', + help='The port to connect. [Default 2947]' + ) + parser.add_option( + '--device', + dest='device', + default=None, + help='The device to connet. [Default None]' + ) + parser.add_option( + '--speedunits', + dest='speedunits', + default='mph', + help='The unit of speed. Possible units are: mph, kmh, knots. [Default mph]' + ) + parser.add_option( + '--debug', + dest='debug', + default=0, + action='store', + type='int', + help='Set level of debug. Must be integer. [Default 0]' + ) + parser.add_option( + '-V', + '--version', + action='store_true', + default=False, + dest='version', + help='show program\'s version number and exit' + ) + (options, args) = parser.parse_args() + if options.version: + print version + exit(0) + if args: + arg = args[0].split(':') + len_arg = len(arg) + if len_arg == 1: + (options.host,) = arg + elif len_arg == 2: + (options.host, options.port) = arg + elif len_arg == 3: + (options.host, options.port, options.device) = arg + else: + parser.print_help() + exit(0) + Main( + host=options.host, + port=options.port, + device=options.device, + speed_unit=options.speedunits, + debug=options.debug + ).run() -- 2.7.4