From: Tu Truong Date: Sat, 19 May 2012 01:24:46 +0000 (-0700) Subject: "Initial commit to Gerrit" X-Git-Tag: "2.95-05182012"^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a55304a6fd31bb558967776c7a16d6c9e226b35a;p=profile%2Fivi%2Fgpsd.git "Initial commit to Gerrit" --- a55304a6fd31bb558967776c7a16d6c9e226b35a 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 0000000..83ca308 Binary files /dev/null and b/packaging/X11/gpsd-logo.png differ 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 0000000..a25a3b0 Binary files /dev/null and b/test/daemon/ac12_binary.log differ diff --git a/test/daemon/ac12_binary.log.chk b/test/daemon/ac12_binary.log.chk new file mode 100644 index 0000000..f4af876 Binary files /dev/null and b/test/daemon/ac12_binary.log.chk differ 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 0000000..83ca2fd Binary files /dev/null and b/test/daemon/bu303-climbing.log differ diff --git a/test/daemon/bu303-climbing.log.chk b/test/daemon/bu303-climbing.log.chk new file mode 100644 index 0000000..f046e16 --- /dev/null +++ b/test/daemon/bu303-climbing.log.chk @@ -0,0 +1,199 @@ +$GPGSV,2,1,07,10,45,196,10,29,67,310,42,28,59,108,40,26,51,304,44*70 +$GPGSV,2,2,07,08,44,058,43,27,16,066,37,21,10,301,00*4A +{"class":"SKY","tag":"MID4","time":1119197546.890,"satellites":[{"PRN":10,"el":45,"az":196,"ss":10,"used":false},{"PRN":29,"el":67,"az":310,"ss":42,"used":false},{"PRN":28,"el":59,"az":108,"ss":40,"used":false},{"PRN":26,"el":51,"az":304,"ss":44,"used":false},{"PRN":8,"el":44,"az":58,"ss":43,"used":false},{"PRN":27,"el":16,"az":66,"ss":37,"used":false},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161226,4629.8923,N,00734.0837,E,1,05,3.20,1327.69,M,48.183,M,,*7D +$GPRMC,161226,A,4629.8923,N,00734.0837,E,0.1673,180.000,190605,,*29 +$GPGSA,A,3,29,28,26,08,27,,,,,,,,0.0,3.2,0.0*3B +{"class":"TPV","tag":"MID2","time":1119197546.890,"ept":0.005,"lat":46.498204497,"lon":7.568061439,"alt":1327.689,"track":180.0000,"speed":0.086,"climb":-0.091,"mode":3} +$GPGSV,2,1,07,10,45,196,08,29,67,310,41,28,59,108,40,26,51,304,43*7D +$GPGSV,2,2,07,08,44,058,42,27,16,066,36,21,10,301,00*4A +{"class":"SKY","tag":"MID4","time":1119197547.890,"xdop":1.02,"ydop":1.14,"vdop":5.41,"tdop":4.30,"hdop":1.53,"gdop":7.08,"pdop":5.62,"satellites":[{"PRN":10,"el":45,"az":196,"ss":8,"used":false},{"PRN":29,"el":67,"az":310,"ss":41,"used":true},{"PRN":28,"el":59,"az":108,"ss":40,"used":true},{"PRN":26,"el":51,"az":304,"ss":43,"used":true},{"PRN":8,"el":44,"az":58,"ss":42,"used":true},{"PRN":27,"el":16,"az":66,"ss":36,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161227,4629.8923,N,00734.0837,E,1,05,3.20,1327.69,M,48.183,M,,*7C +$GPRMC,161227,A,4629.8923,N,00734.0837,E,0.1776,10.380,190605,,*1F +$GPGSA,A,3,29,28,26,08,27,,,,,,,,5.6,3.2,5.4*39 +{"class":"TPV","tag":"MID2","time":1119197547.890,"ept":0.005,"lat":46.498204497,"lon":7.568061439,"alt":1327.689,"epx":15.319,"epy":17.054,"epv":124.484,"track":10.3797,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,07,10,45,196,33,29,67,310,42,28,59,108,42,26,51,304,43*74 +$GPGSV,2,2,07,08,44,058,44,27,16,066,36,21,10,301,00*4C +{"class":"SKY","tag":"MID4","time":1119197548.890,"xdop":1.02,"ydop":1.14,"vdop":5.41,"tdop":4.30,"hdop":1.53,"gdop":7.08,"pdop":5.62,"satellites":[{"PRN":10,"el":45,"az":196,"ss":33,"used":false},{"PRN":29,"el":67,"az":310,"ss":42,"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":44,"used":true},{"PRN":27,"el":16,"az":66,"ss":36,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161228,4629.8923,N,00734.0837,E,1,06,1.40,1327.69,M,48.183,M,,*74 +$GPRMC,161228,A,4629.8923,N,00734.0837,E,0.1673,180.000,190605,,*27 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,5.6,1.4,5.4*3C +{"class":"TPV","tag":"MID2","time":1119197548.890,"ept":0.005,"lat":46.498204497,"lon":7.568061439,"alt":1327.689,"epx":15.319,"epy":17.054,"epv":124.484,"track":180.0000,"speed":0.086,"climb":-0.091,"mode":3} +$GPGSV,2,1,07,10,45,196,31,29,67,310,43,28,59,108,42,26,51,304,45*71 +$GPGSV,2,2,07,08,44,058,46,27,16,066,42,21,10,301,00*4D +{"class":"SKY","tag":"MID4","time":1119197549.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":31,"used":true},{"PRN":29,"el":67,"az":310,"ss":43,"used":true},{"PRN":28,"el":59,"az":108,"ss":42,"used":true},{"PRN":26,"el":51,"az":304,"ss":45,"used":true},{"PRN":8,"el":44,"az":58,"ss":46,"used":true},{"PRN":27,"el":16,"az":66,"ss":42,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161229,4629.8923,N,00734.0837,E,1,06,1.40,1327.69,M,48.183,M,,*75 +$GPRMC,161229,A,4629.8923,N,00734.0837,E,0.0000,0.000,190605,,*2C +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197549.890,"ept":0.005,"lat":46.498204497,"lon":7.568061439,"alt":1327.689,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,33,29,67,310,40,28,59,108,41,26,51,304,43*75 +$GPGSV,2,2,07,08,44,058,44,27,16,066,40,21,10,301,00*4D +{"class":"SKY","tag":"MID4","time":1119197550.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":33,"used":true},{"PRN":29,"el":67,"az":310,"ss":40,"used":true},{"PRN":28,"el":59,"az":108,"ss":41,"used":true},{"PRN":26,"el":51,"az":304,"ss":43,"used":true},{"PRN":8,"el":44,"az":58,"ss":44,"used":true},{"PRN":27,"el":16,"az":66,"ss":40,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161230,4629.8919,N,00734.0837,E,1,06,1.40,1326.96,M,48.183,M,,*75 +$GPRMC,161230,A,4629.8919,N,00734.0837,E,0.1673,180.000,190605,,*27 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197550.890,"ept":0.005,"lat":46.498198306,"lon":7.568061439,"alt":1326.964,"epx":15.279,"epy":16.167,"epv":58.845,"track":180.0000,"speed":0.086,"climb":-0.091,"mode":3} +$GPGSV,2,1,07,10,45,196,34,29,67,310,40,28,59,108,43,26,51,304,43*70 +$GPGSV,2,2,07,08,44,058,42,27,16,066,39,21,10,301,00*45 +{"class":"SKY","tag":"MID4","time":1119197551.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"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":43,"used":true},{"PRN":26,"el":51,"az":304,"ss":43,"used":true},{"PRN":8,"el":44,"az":58,"ss":42,"used":true},{"PRN":27,"el":16,"az":66,"ss":39,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161231,4629.8919,N,00734.0837,E,1,06,1.40,1326.96,M,48.183,M,,*74 +$GPRMC,161231,A,4629.8919,N,00734.0837,E,0.0000,0.000,190605,,*2C +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197551.890,"ept":0.005,"lat":46.498198306,"lon":7.568061439,"alt":1326.964,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,35,29,67,310,39,28,59,108,43,26,51,304,43*7F +$GPGSV,2,2,07,08,44,058,42,27,16,066,38,21,10,301,00*44 +{"class":"SKY","tag":"MID4","time":1119197552.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":35,"used":true},{"PRN":29,"el":67,"az":310,"ss":39,"used":true},{"PRN":28,"el":59,"az":108,"ss":43,"used":true},{"PRN":26,"el":51,"az":304,"ss":43,"used":true},{"PRN":8,"el":44,"az":58,"ss":42,"used":true},{"PRN":27,"el":16,"az":66,"ss":38,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161232,4629.8919,N,00734.0837,E,1,06,1.40,1326.96,M,48.183,M,,*77 +$GPRMC,161232,A,4629.8919,N,00734.0837,E,0.0000,0.000,190605,,*2F +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197552.890,"ept":0.005,"lat":46.498198306,"lon":7.568061439,"alt":1326.964,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,37,29,67,310,40,28,59,108,45,26,51,304,42*74 +$GPGSV,2,2,07,08,44,058,42,27,16,066,38,21,10,301,00*44 +{"class":"SKY","tag":"MID4","time":1119197553.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":37,"used":true},{"PRN":29,"el":67,"az":310,"ss":40,"used":true},{"PRN":28,"el":59,"az":108,"ss":45,"used":true},{"PRN":26,"el":51,"az":304,"ss":42,"used":true},{"PRN":8,"el":44,"az":58,"ss":42,"used":true},{"PRN":27,"el":16,"az":66,"ss":38,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161233,4629.8919,N,00734.0837,E,1,06,1.40,1326.96,M,48.183,M,,*76 +$GPRMC,161233,A,4629.8919,N,00734.0837,E,0.0000,0.000,190605,,*2E +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197553.890,"ept":0.005,"lat":46.498198306,"lon":7.568061439,"alt":1326.964,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,37,29,67,310,41,28,59,108,44,26,51,304,43*75 +$GPGSV,2,2,07,08,44,058,42,27,16,066,38,21,10,301,00*44 +{"class":"SKY","tag":"MID4","time":1119197554.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":37,"used":true},{"PRN":29,"el":67,"az":310,"ss":41,"used":true},{"PRN":28,"el":59,"az":108,"ss":44,"used":true},{"PRN":26,"el":51,"az":304,"ss":43,"used":true},{"PRN":8,"el":44,"az":58,"ss":42,"used":true},{"PRN":27,"el":16,"az":66,"ss":38,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161234,4629.8918,N,00734.0845,E,1,06,1.40,1327.05,M,48.183,M,,*7E +$GPRMC,161234,A,4629.8918,N,00734.0845,E,0.0000,0.000,190605,,*2D +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197554.890,"ept":0.005,"lat":46.498197446,"lon":7.568074350,"alt":1327.054,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,36,29,67,310,40,28,59,108,43,26,51,304,42*73 +$GPGSV,2,2,07,08,44,058,42,27,16,066,38,21,10,301,00*44 +{"class":"SKY","tag":"MID4","time":1119197555.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":36,"used":true},{"PRN":29,"el":67,"az":310,"ss":40,"used":true},{"PRN":28,"el":59,"az":108,"ss":43,"used":true},{"PRN":26,"el":51,"az":304,"ss":42,"used":true},{"PRN":8,"el":44,"az":58,"ss":42,"used":true},{"PRN":27,"el":16,"az":66,"ss":38,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161235,4629.8918,N,00734.0845,E,1,06,1.40,1327.05,M,48.183,M,,*7F +$GPRMC,161235,A,4629.8918,N,00734.0845,E,0.0000,0.000,190605,,*2C +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197555.890,"ept":0.005,"lat":46.498197446,"lon":7.568074350,"alt":1327.054,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,35,29,67,310,40,28,59,108,43,26,51,304,41*73 +$GPGSV,2,2,07,08,44,058,41,27,16,066,39,21,10,301,00*46 +{"class":"SKY","tag":"MID4","time":1119197556.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":35,"used":true},{"PRN":29,"el":67,"az":310,"ss":40,"used":true},{"PRN":28,"el":59,"az":108,"ss":43,"used":true},{"PRN":26,"el":51,"az":304,"ss":41,"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}]} +$GPGGA,161236,4629.8918,N,00734.0845,E,1,06,1.40,1327.05,M,48.183,M,,*7C +$GPRMC,161236,A,4629.8918,N,00734.0845,E,0.0000,0.000,190605,,*2F +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197556.890,"ept":0.005,"lat":46.498197446,"lon":7.568074350,"alt":1327.054,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,34,29,67,310,40,28,59,108,43,26,51,304,42*71 +$GPGSV,2,2,07,08,44,058,41,27,16,066,39,21,10,301,00*46 +{"class":"SKY","tag":"MID4","time":1119197557.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"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":43,"used":true},{"PRN":26,"el":51,"az":304,"ss":42,"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}]} +$GPGGA,161237,4629.8918,N,00734.0845,E,1,06,1.40,1327.05,M,48.183,M,,*7D +$GPRMC,161237,A,4629.8918,N,00734.0845,E,0.0000,0.000,190605,,*2E +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197557.890,"ept":0.005,"lat":46.498197446,"lon":7.568074350,"alt":1327.054,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,33,29,67,310,40,28,59,108,44,26,51,304,42*71 +$GPGSV,2,2,07,08,44,058,41,27,16,066,38,21,10,301,00*47 +{"class":"SKY","tag":"MID4","time":1119197558.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":33,"used":true},{"PRN":29,"el":67,"az":310,"ss":40,"used":true},{"PRN":28,"el":59,"az":108,"ss":44,"used":true},{"PRN":26,"el":51,"az":304,"ss":42,"used":true},{"PRN":8,"el":44,"az":58,"ss":41,"used":true},{"PRN":27,"el":16,"az":66,"ss":38,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161238,4629.8922,N,00734.0845,E,1,06,1.40,1327.78,M,48.183,M,,*71 +$GPRMC,161238,A,4629.8922,N,00734.0845,E,0.0000,0.000,190605,,*28 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197558.890,"ept":0.005,"lat":46.498203638,"lon":7.568074350,"alt":1327.780,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,34,29,67,310,40,28,59,108,43,26,51,304,43*70 +$GPGSV,2,2,07,08,44,058,41,27,16,066,40,21,10,301,00*48 +{"class":"SKY","tag":"MID4","time":1119197559.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"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":43,"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":40,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161239,4629.8922,N,00734.0845,E,1,06,1.40,1327.78,M,48.183,M,,*70 +$GPRMC,161239,A,4629.8922,N,00734.0845,E,0.0000,0.000,190605,,*29 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197559.890,"ept":0.005,"lat":46.498203638,"lon":7.568074350,"alt":1327.780,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,34,29,67,310,40,28,59,108,43,26,51,304,44*77 +$GPGSV,2,2,07,08,44,058,41,27,16,066,40,21,10,301,00*48 +{"class":"SKY","tag":"MID4","time":1119197560.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"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":43,"used":true},{"PRN":26,"el":51,"az":304,"ss":44,"used":true},{"PRN":8,"el":44,"az":58,"ss":41,"used":true},{"PRN":27,"el":16,"az":66,"ss":40,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161240,4629.8922,N,00734.0845,E,1,06,1.40,1327.78,M,48.183,M,,*7E +$GPRMC,161240,A,4629.8922,N,00734.0845,E,0.0000,0.000,190605,,*27 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197560.890,"ept":0.005,"lat":46.498203638,"lon":7.568074350,"alt":1327.780,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,34,29,67,310,40,28,59,108,43,26,51,304,44*77 +$GPGSV,2,2,07,08,44,058,42,27,16,066,40,21,10,301,00*4B +{"class":"SKY","tag":"MID4","time":1119197561.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"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":43,"used":true},{"PRN":26,"el":51,"az":304,"ss":44,"used":true},{"PRN":8,"el":44,"az":58,"ss":42,"used":true},{"PRN":27,"el":16,"az":66,"ss":40,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161241,4629.8925,N,00734.0852,E,1,06,1.40,1328.60,M,48.183,M,,*78 +$GPRMC,161241,A,4629.8925,N,00734.0852,E,0.0000,0.000,190605,,*27 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197561.890,"ept":0.005,"lat":46.498208970,"lon":7.568087260,"alt":1328.596,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,07,10,45,196,31,29,67,310,37,28,59,108,38,26,51,304,41*7B +$GPGSV,2,2,07,08,44,058,39,27,16,066,37,21,10,301,00*47 +{"class":"SKY","tag":"MID4","time":1119197562.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":31,"used":true},{"PRN":29,"el":67,"az":310,"ss":37,"used":true},{"PRN":28,"el":59,"az":108,"ss":38,"used":true},{"PRN":26,"el":51,"az":304,"ss":41,"used":true},{"PRN":8,"el":44,"az":58,"ss":39,"used":true},{"PRN":27,"el":16,"az":66,"ss":37,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161242,4629.8925,N,00734.0852,E,1,06,1.40,1328.60,M,48.183,M,,*7B +$GPRMC,161242,A,4629.8925,N,00734.0852,E,0.1776,190.380,190605,,*20 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197562.890,"ept":0.005,"lat":46.498208970,"lon":7.568087260,"alt":1328.596,"epx":15.279,"epy":16.167,"epv":58.845,"track":190.3797,"speed":0.091,"climb":0.085,"mode":3} +$GPGSV,2,1,07,10,45,196,41,29,67,310,43,28,59,108,39,26,51,304,44*7B +$GPGSV,2,2,07,08,44,058,39,27,16,066,21,21,10,301,00*40 +{"class":"SKY","tag":"MID4","time":1119197563.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":41,"used":true},{"PRN":29,"el":67,"az":310,"ss":43,"used":true},{"PRN":28,"el":59,"az":108,"ss":39,"used":true},{"PRN":26,"el":51,"az":304,"ss":44,"used":true},{"PRN":8,"el":44,"az":58,"ss":39,"used":true},{"PRN":27,"el":16,"az":66,"ss":21,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161243,4629.8929,N,00734.0852,E,1,06,1.40,1329.32,M,48.183,M,,*70 +$GPRMC,161243,A,4629.8929,N,00734.0852,E,0.1673,0.000,190605,,*2A +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197563.890,"ept":0.005,"lat":46.498215161,"lon":7.568087260,"alt":1329.321,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.086,"climb":0.091,"mode":3} +$GPGSV,2,1,07,10,45,196,44,29,67,310,44,28,59,108,44,26,51,304,42*75 +$GPGSV,2,2,07,08,44,058,42,27,16,066,36,21,10,301,00*4A +{"class":"SKY","tag":"MID4","time":1119197564.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":44,"used":true},{"PRN":29,"el":67,"az":310,"ss":44,"used":true},{"PRN":28,"el":59,"az":108,"ss":44,"used":true},{"PRN":26,"el":51,"az":304,"ss":42,"used":true},{"PRN":8,"el":44,"az":58,"ss":42,"used":true},{"PRN":27,"el":16,"az":66,"ss":36,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161244,4629.8933,N,00734.0853,E,1,06,1.40,1328.64,M,48.183,M,,*7F +$GPRMC,161244,A,4629.8933,N,00734.0853,E,0.1673,0.000,190605,,*27 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197564.890,"ept":0.005,"lat":46.498221628,"lon":7.568088976,"alt":1328.639,"epx":15.279,"epy":16.167,"epv":58.845,"track":0.0000,"speed":0.086,"climb":0.091,"mode":3} +$GPGSV,2,1,07,10,45,196,44,29,67,310,44,28,59,108,45,26,51,304,43*75 +$GPGSV,2,2,07,08,44,058,42,27,16,066,39,21,10,301,00*45 +{"class":"SKY","tag":"MID4","time":1119197565.890,"xdop":1.02,"ydop":1.08,"vdop":2.56,"tdop":1.96,"hdop":1.48,"gdop":3.55,"pdop":2.96,"satellites":[{"PRN":10,"el":45,"az":196,"ss":44,"used":true},{"PRN":29,"el":67,"az":310,"ss":44,"used":true},{"PRN":28,"el":59,"az":108,"ss":45,"used":true},{"PRN":26,"el":51,"az":304,"ss":43,"used":true},{"PRN":8,"el":44,"az":58,"ss":42,"used":true},{"PRN":27,"el":16,"az":66,"ss":39,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161245,4629.8933,N,00734.0853,E,1,06,1.40,1328.64,M,48.183,M,,*7E +$GPRMC,161245,A,4629.8933,N,00734.0853,E,0.2420,95.505,190605,,*1D +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197565.890,"ept":0.005,"lat":46.498221628,"lon":7.568088976,"alt":1328.639,"epx":15.279,"epy":16.167,"epv":58.845,"track":95.5047,"speed":0.124,"climb":0.011,"mode":3} +$GPGSV,2,1,07,10,45,196,43,29,67,312,46,28,59,108,45,26,51,304,43*72 +$GPGSV,2,2,07,08,44,058,45,27,16,066,39,21,10,301,00*42 +{"class":"SKY","tag":"MID4","time":1119197566.890,"xdop":1.02,"ydop":1.07,"vdop":2.55,"tdop":1.96,"hdop":1.48,"gdop":3.54,"pdop":2.95,"satellites":[{"PRN":10,"el":45,"az":196,"ss":43,"used":true},{"PRN":29,"el":67,"az":312,"ss":46,"used":true},{"PRN":28,"el":59,"az":108,"ss":45,"used":true},{"PRN":26,"el":51,"az":304,"ss":43,"used":true},{"PRN":8,"el":44,"az":58,"ss":45,"used":true},{"PRN":27,"el":16,"az":66,"ss":39,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161246,4629.8933,N,00734.0853,E,1,06,1.40,1328.64,M,48.183,M,,*7D +$GPRMC,161246,A,4629.8933,N,00734.0853,E,0.1776,190.380,190605,,*22 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197566.890,"ept":0.005,"lat":46.498221628,"lon":7.568088976,"alt":1328.639,"epx":15.296,"epy":16.119,"epv":58.728,"track":190.3797,"speed":0.091,"climb":0.085,"mode":3} +$GPGSV,2,1,07,10,45,196,44,29,67,312,47,28,59,108,45,26,51,304,41*76 +$GPGSV,2,2,07,08,44,058,46,27,16,066,40,21,10,301,00*4F +{"class":"SKY","tag":"MID4","time":1119197567.890,"xdop":1.02,"ydop":1.07,"vdop":2.55,"tdop":1.96,"hdop":1.48,"gdop":3.54,"pdop":2.95,"satellites":[{"PRN":10,"el":45,"az":196,"ss":44,"used":true},{"PRN":29,"el":67,"az":312,"ss":47,"used":true},{"PRN":28,"el":59,"az":108,"ss":45,"used":true},{"PRN":26,"el":51,"az":304,"ss":41,"used":true},{"PRN":8,"el":44,"az":58,"ss":46,"used":true},{"PRN":27,"el":16,"az":66,"ss":40,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161247,4629.8929,N,00734.0852,E,1,06,1.40,1329.32,M,48.183,M,,*74 +$GPRMC,161247,A,4629.8929,N,00734.0852,E,0.1776,190.380,190605,,*29 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197567.890,"ept":0.005,"lat":46.498215161,"lon":7.568087260,"alt":1329.321,"epx":15.296,"epy":16.119,"epv":58.728,"track":190.3797,"speed":0.091,"climb":0.085,"mode":3} +$GPGSV,2,1,07,10,45,196,45,29,67,312,47,28,59,108,45,26,51,304,40*76 +$GPGSV,2,2,07,08,44,058,46,27,16,066,38,21,10,301,00*40 +{"class":"SKY","tag":"MID4","time":1119197568.890,"xdop":1.02,"ydop":1.07,"vdop":2.55,"tdop":1.96,"hdop":1.48,"gdop":3.54,"pdop":2.95,"satellites":[{"PRN":10,"el":45,"az":196,"ss":45,"used":true},{"PRN":29,"el":67,"az":312,"ss":47,"used":true},{"PRN":28,"el":59,"az":108,"ss":45,"used":true},{"PRN":26,"el":51,"az":304,"ss":40,"used":true},{"PRN":8,"el":44,"az":58,"ss":46,"used":true},{"PRN":27,"el":16,"az":66,"ss":38,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161248,4629.8929,N,00734.0852,E,1,06,1.40,1329.32,M,48.183,M,,*7B +$GPRMC,161248,A,4629.8929,N,00734.0852,E,0.1776,190.380,190605,,*26 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197568.890,"ept":0.005,"lat":46.498215161,"lon":7.568087260,"alt":1329.321,"epx":15.296,"epy":16.119,"epv":58.728,"track":190.3797,"speed":0.091,"climb":0.085,"mode":3} +$GPGSV,2,1,07,10,45,196,45,29,67,312,47,28,59,108,43,26,51,304,41*71 +$GPGSV,2,2,07,08,44,058,46,27,16,066,39,21,10,301,00*41 +{"class":"SKY","tag":"MID4","time":1119197569.890,"xdop":1.02,"ydop":1.07,"vdop":2.55,"tdop":1.96,"hdop":1.48,"gdop":3.54,"pdop":2.95,"satellites":[{"PRN":10,"el":45,"az":196,"ss":45,"used":true},{"PRN":29,"el":67,"az":312,"ss":47,"used":true},{"PRN":28,"el":59,"az":108,"ss":43,"used":true},{"PRN":26,"el":51,"az":304,"ss":41,"used":true},{"PRN":8,"el":44,"az":58,"ss":46,"used":true},{"PRN":27,"el":16,"az":66,"ss":39,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161249,4629.8933,N,00734.0852,E,1,06,1.40,1330.05,M,48.183,M,,*7D +$GPRMC,161249,A,4629.8933,N,00734.0852,E,0.1776,190.380,190605,,*2C +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197569.890,"ept":0.005,"lat":46.498221352,"lon":7.568087260,"alt":1330.046,"epx":15.296,"epy":16.119,"epv":58.728,"track":190.3797,"speed":0.091,"climb":0.085,"mode":3} +$GPGSV,2,1,07,10,45,196,43,29,67,312,46,28,59,108,43,26,51,304,42*75 +$GPGSV,2,2,07,08,44,058,46,27,16,066,40,21,10,301,00*4F +{"class":"SKY","tag":"MID4","time":1119197570.890,"xdop":1.02,"ydop":1.07,"vdop":2.55,"tdop":1.96,"hdop":1.48,"gdop":3.54,"pdop":2.95,"satellites":[{"PRN":10,"el":45,"az":196,"ss":43,"used":true},{"PRN":29,"el":67,"az":312,"ss":46,"used":true},{"PRN":28,"el":59,"az":108,"ss":43,"used":true},{"PRN":26,"el":51,"az":304,"ss":42,"used":true},{"PRN":8,"el":44,"az":58,"ss":46,"used":true},{"PRN":27,"el":16,"az":66,"ss":40,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161250,4629.8929,N,00734.0851,E,1,06,1.40,1330.73,M,48.183,M,,*7C +$GPRMC,161250,A,4629.8929,N,00734.0851,E,0.1776,190.380,190605,,*2C +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197570.890,"ept":0.005,"lat":46.498214885,"lon":7.568085545,"alt":1330.729,"epx":15.296,"epy":16.119,"epv":58.728,"track":190.3797,"speed":0.091,"climb":0.085,"mode":3} +$GPGSV,2,1,07,10,45,196,44,29,67,312,46,28,59,108,46,26,51,304,46*73 +$GPGSV,2,2,07,08,44,058,47,27,16,066,38,21,10,301,00*41 +{"class":"SKY","tag":"MID4","time":1119197571.890,"xdop":1.02,"ydop":1.07,"vdop":2.55,"tdop":1.96,"hdop":1.48,"gdop":3.54,"pdop":2.95,"satellites":[{"PRN":10,"el":45,"az":196,"ss":44,"used":true},{"PRN":29,"el":67,"az":312,"ss":46,"used":true},{"PRN":28,"el":59,"az":108,"ss":46,"used":true},{"PRN":26,"el":51,"az":304,"ss":46,"used":true},{"PRN":8,"el":44,"az":58,"ss":47,"used":true},{"PRN":27,"el":16,"az":66,"ss":38,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161251,4629.8929,N,00734.0851,E,1,06,1.40,1330.73,M,48.183,M,,*7D +$GPRMC,161251,A,4629.8929,N,00734.0851,E,0.2420,275.505,190605,,*2D +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197571.890,"ept":0.005,"lat":46.498214885,"lon":7.568085545,"alt":1330.729,"epx":15.296,"epy":16.119,"epv":58.728,"track":275.5047,"speed":0.124,"climb":-0.011,"mode":3} +$GPGSV,2,1,07,10,45,196,45,29,67,312,47,28,59,108,44,26,51,304,46*71 +$GPGSV,2,2,07,08,44,058,45,27,16,066,39,21,10,301,00*42 +{"class":"SKY","tag":"MID4","time":1119197572.890,"xdop":1.02,"ydop":1.07,"vdop":2.55,"tdop":1.96,"hdop":1.48,"gdop":3.54,"pdop":2.95,"satellites":[{"PRN":10,"el":45,"az":196,"ss":45,"used":true},{"PRN":29,"el":67,"az":312,"ss":47,"used":true},{"PRN":28,"el":59,"az":108,"ss":44,"used":true},{"PRN":26,"el":51,"az":304,"ss":46,"used":true},{"PRN":8,"el":44,"az":58,"ss":45,"used":true},{"PRN":27,"el":16,"az":66,"ss":39,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161252,4629.8929,N,00734.0844,E,1,06,1.40,1330.64,M,48.183,M,,*7C +$GPRMC,161252,A,4629.8929,N,00734.0844,E,1.4953,310.306,190605,,*23 +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197572.890,"ept":0.005,"lat":46.498215744,"lon":7.568072634,"alt":1330.638,"epx":15.296,"epy":16.119,"epv":58.728,"track":310.3062,"speed":0.769,"climb":0.045,"mode":3} +$GPGSV,2,1,07,10,45,196,45,29,67,312,46,28,59,108,45,26,51,304,44*73 +$GPGSV,2,2,07,08,44,058,44,27,16,066,37,21,10,301,00*4D +{"class":"SKY","tag":"MID4","time":1119197573.890,"xdop":1.02,"ydop":1.07,"vdop":2.55,"tdop":1.96,"hdop":1.48,"gdop":3.54,"pdop":2.95,"satellites":[{"PRN":10,"el":45,"az":196,"ss":45,"used":true},{"PRN":29,"el":67,"az":312,"ss":46,"used":true},{"PRN":28,"el":59,"az":108,"ss":45,"used":true},{"PRN":26,"el":51,"az":304,"ss":44,"used":true},{"PRN":8,"el":44,"az":58,"ss":44,"used":true},{"PRN":27,"el":16,"az":66,"ss":37,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} +$GPGGA,161253,4629.8934,N,00734.0836,E,1,06,1.40,1331.27,M,48.183,M,,*72 +$GPRMC,161253,A,4629.8934,N,00734.0836,E,2.2921,306.984,190605,,*2C +$GPGSA,A,3,10,29,28,26,08,27,,,,,,,3.0,1.4,2.6*39 +{"class":"TPV","tag":"MID2","time":1119197573.890,"ept":0.005,"lat":46.498222795,"lon":7.568059724,"alt":1331.273,"epx":15.296,"epy":16.119,"epv":58.728,"track":306.9839,"speed":1.179,"climb":0.016,"mode":3} +$GPGSV,2,1,07,10,45,196,45,29,67,312,44,28,59,108,45,26,51,304,44*71 +$GPGSV,2,2,07,08,44,058,42,27,16,066,41,21,10,301,00*4A +{"class":"SKY","tag":"MID4","time":1119197574.890,"xdop":1.02,"ydop":1.07,"vdop":2.55,"tdop":1.96,"hdop":1.48,"gdop":3.54,"pdop":2.95,"satellites":[{"PRN":10,"el":45,"az":196,"ss":45,"used":true},{"PRN":29,"el":67,"az":312,"ss":44,"used":true},{"PRN":28,"el":59,"az":108,"ss":45,"used":true},{"PRN":26,"el":51,"az":304,"ss":44,"used":true},{"PRN":8,"el":44,"az":58,"ss":42,"used":true},{"PRN":27,"el":16,"az":66,"ss":41,"used":true},{"PRN":21,"el":10,"az":301,"ss":0,"used":false}]} diff --git a/test/daemon/bu303-moving.log b/test/daemon/bu303-moving.log new file mode 100644 index 0000000..fd9cd13 Binary files /dev/null and b/test/daemon/bu303-moving.log differ diff --git a/test/daemon/bu303-moving.log.chk b/test/daemon/bu303-moving.log.chk new file mode 100644 index 0000000..2d20e57 --- /dev/null +++ b/test/daemon/bu303-moving.log.chk @@ -0,0 +1,217 @@ +$GPGGA,143447,4629.8972,N,00734.0447,E,1,05,2.40,1342.40,M,48.183,M,,*7C +$GPRMC,143447,A,4629.8972,N,00734.0447,E,0.1776,10.379,090605,,*17 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,0.0,2.4,0.0*3E +{"class":"TPV","tag":"MID2","time":1118327687.280,"ept":0.005,"lat":46.498287178,"lon":7.567411672,"alt":1342.402,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,44,29,13,273,00*74 +$GPGSV,2,2,08,10,51,304,29,04,15,199,36,02,34,241,43,27,71,076,43*7C +{"class":"SKY","tag":"MID4","time":1118327688.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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}]} +$GPGGA,143448,4629.8976,N,00734.0447,E,1,05,2.40,1343.13,M,48.183,M,,*70 +$GPRMC,143448,A,4629.8976,N,00734.0447,E,0.1776,10.379,090605,,*1C +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327688.280,"ept":0.005,"lat":46.498293369,"lon":7.567411672,"alt":1343.127,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,44,29,13,273,00*74 +$GPGSV,2,2,08,10,51,304,28,04,15,199,37,02,34,241,43,27,71,076,43*7C +{"class":"SKY","tag":"MID4","time":1118327689.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":28,"used":true},{"PRN":4,"el":15,"az":199,"ss":37,"used":true},{"PRN":2,"el":34,"az":241,"ss":43,"used":true},{"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} +$GPGGA,143449,4629.8980,N,00734.0440,E,1,05,2.40,1342.35,M,48.183,M,,*7A +$GPRMC,143449,A,4629.8980,N,00734.0440,E,0.1776,10.379,090605,,*13 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327689.280,"ept":0.005,"lat":46.498300695,"lon":7.567400477,"alt":1342.354,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,44,29,13,273,00*74 +$GPGSV,2,2,08,10,51,304,27,04,15,199,35,02,34,241,42,27,71,076,42*71 +{"class":"SKY","tag":"MID4","time":1118327690.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":27,"used":true},{"PRN":4,"el":15,"az":199,"ss":35,"used":true},{"PRN":2,"el":34,"az":241,"ss":42,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143450,4629.8984,N,00734.0440,E,1,04,3.20,1343.08,M,48.183,M,,*7F +$GPRMC,143450,A,4629.8984,N,00734.0440,E,0.1776,10.379,090605,,*1F +$GPGSA,A,3,08,04,02,27,,,,,,,,,1.9,3.2,1.4*35 +{"class":"TPV","tag":"MID2","time":1118327690.280,"ept":0.005,"lat":46.498306887,"lon":7.567400477,"alt":1343.079,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,44,29,13,273,00*74 +$GPGSV,2,2,08,10,51,304,28,04,15,199,36,02,34,241,42,27,71,076,42*7D +{"class":"SKY","tag":"MID4","time":1118327691.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":28,"used":false},{"PRN":4,"el":15,"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,143451,4629.8984,N,00734.0440,E,1,05,2.40,1343.08,M,48.183,M,,*78 +$GPRMC,143451,A,4629.8984,N,00734.0440,E,0.1776,10.379,090605,,*1E +$GPGSA,A,3,08,10,04,02,27,,,,,,,,2.1,2.4,1.6*3A +{"class":"TPV","tag":"MID2","time":1118327691.280,"ept":0.005,"lat":46.498306887,"lon":7.567400477,"alt":1343.079,"epx":11.014,"epy":18.289,"epv":35.884,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,28,04,15,199,38,02,34,241,43,27,71,076,42*72 +{"class":"SKY","tag":"MID4","time":1118327692.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":28,"used":true},{"PRN":4,"el":15,"az":199,"ss":38,"used":true},{"PRN":2,"el":34,"az":241,"ss":43,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143452,4629.8992,N,00734.0441,E,1,05,2.40,1343.12,M,48.183,M,,*76 +$GPRMC,143452,A,4629.8992,N,00734.0441,E,0.1776,10.379,090605,,*1B +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327692.280,"ept":0.005,"lat":46.498319545,"lon":7.567402192,"alt":1343.122,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,29,04,15,199,37,02,34,241,42,27,71,076,42*7D +{"class":"SKY","tag":"MID4","time":1118327693.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":45,"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":37,"used":true},{"PRN":2,"el":34,"az":241,"ss":42,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143453,4629.8992,N,00734.0441,E,1,05,2.40,1343.12,M,48.183,M,,*77 +$GPRMC,143453,A,4629.8992,N,00734.0441,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":1118327693.280,"ept":0.005,"lat":46.498319545,"lon":7.567402192,"alt":1343.122,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,32,04,15,199,36,02,34,241,43,27,71,076,42*77 +{"class":"SKY","tag":"MID4","time":1118327694.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":32,"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":42,"used":true}]} +$GPGGA,143454,4629.8992,N,00734.0441,E,1,05,2.40,1343.12,M,48.183,M,,*70 +$GPRMC,143454,A,4629.8992,N,00734.0441,E,0.1776,10.379,090605,,*1D +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327694.280,"ept":0.005,"lat":46.498319545,"lon":7.567402192,"alt":1343.122,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,29,04,15,199,36,02,34,241,41,27,71,076,42*7F +{"class":"SKY","tag":"MID4","time":1118327695.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":45,"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":41,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143455,4629.8999,N,00734.0442,E,1,05,2.40,1343.17,M,48.183,M,,*7C +$GPRMC,143455,A,4629.8999,N,00734.0442,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":1118327695.280,"ept":0.005,"lat":46.498332203,"lon":7.567403907,"alt":1343.165,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,25,04,15,199,36,02,34,241,42,27,71,076,42*70 +{"class":"SKY","tag":"MID4","time":1118327696.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":25,"used":true},{"PRN":4,"el":15,"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,143456,4629.8999,N,00734.0442,E,1,04,3.20,1343.17,M,48.183,M,,*79 +$GPRMC,143456,A,4629.8999,N,00734.0442,E,0.1776,10.379,090605,,*17 +$GPGSA,A,3,08,04,02,27,,,,,,,,,1.9,3.2,1.4*35 +{"class":"TPV","tag":"MID2","time":1118327696.280,"ept":0.005,"lat":46.498332203,"lon":7.567403907,"alt":1343.165,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3788,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,46,29,13,273,00*76 +$GPGSV,2,2,08,10,51,304,32,04,15,199,36,02,34,241,42,27,71,076,42*76 +{"class":"SKY","tag":"MID4","time":1118327697.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":46,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":32,"used":false},{"PRN":4,"el":15,"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,143457,4629.9000,N,00734.0435,E,1,05,2.40,1343.07,M,48.183,M,,*77 +$GPRMC,143457,A,4629.9000,N,00734.0435,E,0.1776,10.379,090605,,*1E +$GPGSA,A,3,08,10,04,02,27,,,,,,,,2.1,2.4,1.6*3A +{"class":"TPV","tag":"MID2","time":1118327697.280,"ept":0.005,"lat":46.498333062,"lon":7.567390997,"alt":1343.075,"epx":11.014,"epy":18.289,"epv":35.884,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,46,29,13,273,00*76 +$GPGSV,2,2,08,10,51,304,31,04,15,199,37,02,34,241,42,27,71,076,43*75 +{"class":"SKY","tag":"MID4","time":1118327698.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":46,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":31,"used":true},{"PRN":4,"el":15,"az":199,"ss":37,"used":true},{"PRN":2,"el":34,"az":241,"ss":42,"used":true},{"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} +$GPGGA,143458,4629.9004,N,00734.0436,E,1,05,2.40,1342.39,M,48.183,M,,*73 +$GPRMC,143458,A,4629.9004,N,00734.0436,E,0.1776,10.379,090605,,*16 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327698.280,"ept":0.005,"lat":46.498339529,"lon":7.567392712,"alt":1342.392,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,46,29,13,273,00*76 +$GPGSV,2,2,08,10,51,304,30,04,15,199,34,02,34,241,43,27,71,076,43*76 +{"class":"SKY","tag":"MID4","time":1118327699.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":46,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":30,"used":true},{"PRN":4,"el":15,"az":199,"ss":34,"used":true},{"PRN":2,"el":34,"az":241,"ss":43,"used":true},{"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} +$GPGGA,143459,4629.9004,N,00734.0436,E,1,05,2.40,1342.39,M,48.183,M,,*72 +$GPRMC,143459,A,4629.9004,N,00734.0436,E,0.1776,10.379,090605,,*17 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327699.280,"ept":0.005,"lat":46.498339529,"lon":7.567392712,"alt":1342.392,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,25,04,15,199,36,02,34,241,40,27,71,076,42*72 +{"class":"SKY","tag":"MID4","time":1118327700.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":25,"used":true},{"PRN":4,"el":15,"az":199,"ss":36,"used":true},{"PRN":2,"el":34,"az":241,"ss":40,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143500,4629.9004,N,00734.0436,E,1,04,3.20,1342.39,M,48.183,M,,*79 +$GPRMC,143500,A,4629.9004,N,00734.0436,E,0.1776,10.379,090605,,*1A +$GPGSA,A,3,08,04,02,27,,,,,,,,,1.9,3.2,1.4*35 +{"class":"TPV","tag":"MID2","time":1118327700.280,"ept":0.005,"lat":46.498339529,"lon":7.567392712,"alt":1342.392,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,30,04,15,199,36,02,34,241,43,27,71,076,42*75 +{"class":"SKY","tag":"MID4","time":1118327701.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":30,"used":false},{"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":42,"used":true}]} +$GPGGA,143501,4629.9008,N,00734.0437,E,1,05,2.40,1341.71,M,48.183,M,,*7C +$GPRMC,143501,A,4629.9008,N,00734.0437,E,0.1776,10.379,090605,,*16 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,2.1,2.4,1.6*3A +{"class":"TPV","tag":"MID2","time":1118327701.280,"ept":0.005,"lat":46.498345996,"lon":7.567394427,"alt":1341.710,"epx":11.014,"epy":18.289,"epv":35.884,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,05,04,15,199,35,02,34,241,42,27,71,076,43*70 +{"class":"SKY","tag":"MID4","time":1118327702.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":5,"used":true},{"PRN":4,"el":15,"az":199,"ss":35,"used":true},{"PRN":2,"el":34,"az":241,"ss":42,"used":true},{"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} +$GPGGA,143502,4629.9008,N,00734.0429,E,1,04,3.20,1341.62,M,48.183,M,,*74 +$GPRMC,143502,A,4629.9008,N,00734.0429,E,0.1776,10.379,090605,,*1A +$GPGSA,A,3,08,04,02,27,,,,,,,,,1.9,3.2,1.4*35 +{"class":"TPV","tag":"MID2","time":1118327702.280,"ept":0.005,"lat":46.498346855,"lon":7.567381517,"alt":1341.619,"epx":10.972,"epy":15.581,"epv":32.321,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,00,04,15,199,34,02,34,241,42,27,71,076,43*74 +{"class":"SKY","tag":"MID4","time":1118327703.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":0,"used":false},{"PRN":4,"el":15,"az":199,"ss":34,"used":true},{"PRN":2,"el":34,"az":241,"ss":42,"used":true},{"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} +$GPGGA,143503,4629.9008,N,00734.0429,E,1,04,3.20,1341.62,M,48.183,M,,*75 +$GPRMC,143503,A,4629.9008,N,00734.0429,E,0.1776,10.379,090605,,*1B +$GPGSA,A,3,08,04,02,27,,,,,,,,,2.1,3.2,1.6*3C +{"class":"TPV","tag":"MID2","time":1118327703.280,"ept":0.005,"lat":46.498346855,"lon":7.567381517,"alt":1341.619,"epx":11.014,"epy":18.289,"epv":35.884,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,46,29,13,273,00*76 +$GPGSV,2,2,08,10,51,304,00,04,15,199,34,02,34,241,40,27,71,076,42*77 +{"class":"SKY","tag":"MID4","time":1118327704.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":46,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":0,"used":false},{"PRN":4,"el":15,"az":199,"ss":34,"used":true},{"PRN":2,"el":34,"az":241,"ss":40,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143504,4629.9008,N,00734.0429,E,1,04,3.20,1341.62,M,48.183,M,,*72 +$GPRMC,143504,A,4629.9008,N,00734.0429,E,0.1776,10.379,090605,,*1C +$GPGSA,A,3,08,04,02,27,,,,,,,,,2.1,3.2,1.6*3C +{"class":"TPV","tag":"MID2","time":1118327704.280,"ept":0.005,"lat":46.498346855,"lon":7.567381517,"alt":1341.619,"epx":11.014,"epy":18.289,"epv":35.884,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,00,04,15,199,35,02,34,241,40,27,71,076,43*77 +{"class":"SKY","tag":"MID4","time":1118327705.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":0,"used":false},{"PRN":4,"el":15,"az":199,"ss":35,"used":true},{"PRN":2,"el":34,"az":241,"ss":40,"used":true},{"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} +$GPGGA,143505,4629.9008,N,00734.0430,E,1,04,3.20,1340.21,M,48.183,M,,*7D +$GPRMC,143505,A,4629.9008,N,00734.0430,E,0.1776,10.379,090605,,*15 +$GPGSA,A,3,08,04,02,27,,,,,,,,,2.1,3.2,1.6*3C +{"class":"TPV","tag":"MID2","time":1118327705.280,"ept":0.005,"lat":46.498347131,"lon":7.567383232,"alt":1340.211,"epx":11.014,"epy":18.289,"epv":35.884,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,00,04,15,199,35,02,34,241,40,27,71,076,42*76 +{"class":"SKY","tag":"MID4","time":1118327706.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":0,"used":false},{"PRN":4,"el":15,"az":199,"ss":35,"used":true},{"PRN":2,"el":34,"az":241,"ss":40,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143506,4629.9008,N,00734.0430,E,1,04,3.20,1340.21,M,48.183,M,,*7E +$GPRMC,143506,A,4629.9008,N,00734.0430,E,0.1776,10.379,090605,,*16 +$GPGSA,A,3,08,04,02,27,,,,,,,,,2.1,3.2,1.6*3C +{"class":"TPV","tag":"MID2","time":1118327706.280,"ept":0.005,"lat":46.498347131,"lon":7.567383232,"alt":1340.211,"epx":11.014,"epy":18.289,"epv":35.884,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,00,04,15,199,36,02,34,241,40,27,71,076,42*75 +{"class":"SKY","tag":"MID4","time":1118327707.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":0,"used":false},{"PRN":4,"el":15,"az":199,"ss":36,"used":true},{"PRN":2,"el":34,"az":241,"ss":40,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143507,4629.9008,N,00734.0430,E,1,04,3.20,1340.21,M,48.183,M,,*7F +$GPRMC,143507,A,4629.9008,N,00734.0430,E,0.1776,10.379,090605,,*17 +$GPGSA,A,3,08,04,02,27,,,,,,,,,2.1,3.2,1.6*3C +{"class":"TPV","tag":"MID2","time":1118327707.280,"ept":0.005,"lat":46.498347131,"lon":7.567383232,"alt":1340.211,"epx":11.014,"epy":18.289,"epv":35.884,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,23,04,15,199,38,02,34,241,40,27,71,076,41*79 +{"class":"SKY","tag":"MID4","time":1118327708.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":23,"used":false},{"PRN":4,"el":15,"az":199,"ss":38,"used":true},{"PRN":2,"el":34,"az":241,"ss":40,"used":true},{"PRN":27,"el":71,"az":76,"ss":41,"used":true}]} +$GPGGA,143508,4629.9004,N,00734.0429,E,1,05,2.40,1340.89,M,48.183,M,,*70 +$GPRMC,143508,A,4629.9004,N,00734.0429,E,0.1776,10.379,090605,,*1C +$GPGSA,A,3,08,10,04,02,27,,,,,,,,2.1,2.4,1.6*3A +{"class":"TPV","tag":"MID2","time":1118327708.280,"ept":0.005,"lat":46.498340664,"lon":7.567381517,"alt":1340.894,"epx":11.014,"epy":18.289,"epv":35.884,"track":10.3787,"speed":0.091,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,44,29,13,273,00*74 +$GPGSV,2,2,08,10,51,304,34,04,15,199,38,02,34,241,41,27,71,076,42*7D +{"class":"SKY","tag":"MID4","time":1118327709.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":34,"used":true},{"PRN":4,"el":15,"az":199,"ss":38,"used":true},{"PRN":2,"el":34,"az":241,"ss":41,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143509,4629.9004,N,00734.0429,E,1,05,2.40,1340.89,M,48.183,M,,*71 +$GPRMC,143509,A,4629.9004,N,00734.0429,E,0.0000,0.000,090605,,*26 +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327709.280,"ept":0.005,"lat":46.498340664,"lon":7.567381517,"alt":1340.894,"epx":10.972,"epy":15.581,"epv":32.321,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,45,29,13,273,00*75 +$GPGSV,2,2,08,10,51,304,32,04,15,199,37,02,34,241,42,27,71,076,44*71 +{"class":"SKY","tag":"MID4","time":1118327710.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":45,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":32,"used":true},{"PRN":4,"el":15,"az":199,"ss":37,"used":true},{"PRN":2,"el":34,"az":241,"ss":42,"used":true},{"PRN":27,"el":71,"az":76,"ss":44,"used":true}]} +$GPGGA,143510,4629.9001,N,00734.0428,E,1,05,2.40,1341.58,M,48.183,M,,*70 +$GPRMC,143510,A,4629.9001,N,00734.0428,E,0.0000,0.000,090605,,*2A +$GPGSA,A,3,08,10,04,02,27,,,,,,,,1.9,2.4,1.4*33 +{"class":"TPV","tag":"MID2","time":1118327710.280,"ept":0.005,"lat":46.498334197,"lon":7.567379802,"alt":1341.576,"epx":10.972,"epy":15.581,"epv":32.321,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,39,29,13,273,00*7E +$GPGSV,2,2,08,10,51,304,25,04,15,199,29,02,34,241,20,27,71,076,38*77 +{"class":"SKY","tag":"MID4","time":1118327711.280,"xdop":0.73,"ydop":1.04,"vdop":1.41,"tdop":0.78,"hdop":1.27,"gdop":2.05,"pdop":1.89,"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":39,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":25,"used":true},{"PRN":4,"el":15,"az":199,"ss":29,"used":true},{"PRN":2,"el":34,"az":241,"ss":20,"used":true},{"PRN":27,"el":71,"az":76,"ss":38,"used":true}]} +$GPGGA,143511,4629.9000,N,00734.0436,E,1,04,3.20,1341.67,M,48.183,M,,*75 +$GPRMC,143511,A,4629.9000,N,00734.0436,E,0.3121,60.960,090605,,*1D +$GPGSA,A,3,08,04,02,27,,,,,,,,,1.9,3.2,1.4*35 +{"class":"TPV","tag":"MID2","time":1118327711.280,"ept":0.005,"lat":46.498333338,"lon":7.567392712,"alt":1341.667,"epx":10.972,"epy":15.581,"epv":32.321,"track":60.9597,"speed":0.161,"climb":-0.074,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,40,29,13,273,00*70 +$GPGSV,2,2,08,10,51,304,35,04,15,199,13,02,34,241,27,27,71,076,41*76 +{"class":"SKY","tag":"MID4","time":1118327712.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":40,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":35,"used":false},{"PRN":4,"el":15,"az":199,"ss":13,"used":true},{"PRN":2,"el":34,"az":241,"ss":27,"used":true},{"PRN":27,"el":71,"az":76,"ss":41,"used":true}]} +$GPGGA,143512,4629.8996,N,00734.0435,E,1,04,3.80,1342.35,M,48.183,M,,*7C +$GPRMC,143512,A,4629.8996,N,00734.0435,E,1.5556,157.529,090605,,*2D +$GPGSA,A,3,08,10,02,27,,,,,,,,,2.1,3.8,1.6*33 +{"class":"TPV","tag":"MID2","time":1118327712.280,"ept":0.005,"lat":46.498326871,"lon":7.567390997,"alt":1342.349,"epx":11.014,"epy":18.289,"epv":35.884,"track":157.5287,"speed":0.800,"climb":0.013,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,40,29,13,273,00*70 +$GPGSV,2,2,08,10,51,304,36,04,15,199,27,02,34,241,36,27,71,076,43*70 +{"class":"SKY","tag":"MID4","time":1118327713.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":40,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":36,"used":true},{"PRN":4,"el":15,"az":199,"ss":27,"used":false},{"PRN":2,"el":34,"az":241,"ss":36,"used":true},{"PRN":27,"el":71,"az":76,"ss":43,"used":true}]} +$GPGGA,143513,4629.8992,N,00734.0434,E,1,04,3.80,1343.03,M,48.183,M,,*7C +$GPRMC,143513,A,4629.8992,N,00734.0434,E,0.7149,141.014,090605,,*2C +$GPGSA,A,3,08,10,02,27,,,,,,,,,2.1,3.8,1.6*33 +{"class":"TPV","tag":"MID2","time":1118327713.280,"ept":0.005,"lat":46.498320404,"lon":7.567389282,"alt":1343.032,"epx":11.014,"epy":18.289,"epv":35.884,"track":141.0144,"speed":0.368,"climb":-0.073,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,29,29,13,273,00*7F +$GPGSV,2,2,08,10,51,304,31,04,15,199,27,02,34,241,34,27,71,076,42*74 +{"class":"SKY","tag":"MID4","time":1118327714.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":29,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":31,"used":true},{"PRN":4,"el":15,"az":199,"ss":27,"used":false},{"PRN":2,"el":34,"az":241,"ss":34,"used":true},{"PRN":27,"el":71,"az":76,"ss":42,"used":true}]} +$GPGGA,143514,4629.8984,N,00734.0440,E,1,04,3.80,1343.08,M,48.183,M,,*74 +$GPRMC,143514,A,4629.8984,N,00734.0440,E,0.5719,158.581,090605,,*2F +$GPGSA,A,3,08,10,02,27,,,,,,,,,2.1,3.8,1.6*33 +{"class":"TPV","tag":"MID2","time":1118327714.280,"ept":0.005,"lat":46.498306887,"lon":7.567400477,"alt":1343.079,"epx":11.014,"epy":18.289,"epv":35.884,"track":158.5811,"speed":0.294,"climb":-0.085,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,36,29,13,273,00*71 +$GPGSV,2,2,08,10,51,304,19,04,15,199,00,02,34,241,38,27,71,076,38*7A +{"class":"SKY","tag":"MID4","time":1118327715.280,"xdop":0.73,"ydop":1.22,"vdop":1.56,"tdop":0.79,"hdop":1.42,"gdop":2.25,"pdop":2.11,"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":36,"used":true},{"PRN":29,"el":13,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":19,"used":true},{"PRN":4,"el":15,"az":199,"ss":0,"used":false},{"PRN":2,"el":34,"az":241,"ss":38,"used":true},{"PRN":27,"el":71,"az":76,"ss":38,"used":true}]} +$GPGGA,143515,4629.8984,N,00734.0440,E,1,03,12.80,1343.08,M,48.183,M,,*42 +$GPRMC,143515,A,4629.8984,N,00734.0440,E,0.4207,150.233,090605,,*23 +$GPGSA,A,2,08,02,27,,,,,,,,,,2.1,12.8,1.6*03 +{"class":"TPV","tag":"MID2","time":1118327715.280,"ept":0.005,"lat":46.498306887,"lon":7.567400477,"epx":11.014,"epy":18.289,"track":150.2328,"speed":0.216,"mode":2} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,34,29,14,273,00*74 +$GPGSV,2,2,08,10,51,304,20,04,15,199,00,02,34,241,29,27,71,075,37*7C +{"class":"SKY","tag":"MID4","time":1118327716.280,"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":34,"used":true},{"PRN":29,"el":14,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":20,"used":false},{"PRN":4,"el":15,"az":199,"ss":0,"used":false},{"PRN":2,"el":34,"az":241,"ss":29,"used":true},{"PRN":27,"el":71,"az":75,"ss":37,"used":true}]} +$GPGGA,143516,4629.8980,N,00734.0439,E,1,04,3.80,1343.76,M,48.183,M,,*75 +$GPRMC,143516,A,4629.8980,N,00734.0439,E,0.3435,5.346,090605,,*28 +$GPGSA,A,3,08,10,02,27,,,,,,,,,0.0,3.8,0.0*37 +{"class":"TPV","tag":"MID2","time":1118327716.280,"ept":0.005,"lat":46.498300420,"lon":7.567398762,"alt":1343.762,"track":5.3456,"speed":0.177,"climb":0.005,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,37,29,14,273,00*77 +$GPGSV,2,2,08,10,51,304,30,04,15,199,31,02,34,241,26,27,71,075,33*74 +{"class":"SKY","tag":"MID4","time":1118327717.280,"xdop":0.74,"ydop":1.22,"vdop":1.57,"tdop":0.80,"hdop":1.43,"gdop":2.27,"pdop":2.12,"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":37,"used":true},{"PRN":29,"el":14,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":30,"used":true},{"PRN":4,"el":15,"az":199,"ss":31,"used":false},{"PRN":2,"el":34,"az":241,"ss":26,"used":true},{"PRN":27,"el":71,"az":75,"ss":33,"used":true}]} +$GPGGA,143517,4629.8976,N,00734.0438,E,1,04,2.80,1344.44,M,48.183,M,,*7B +$GPRMC,143517,A,4629.8976,N,00734.0438,E,0.0000,0.000,090605,,*24 +$GPGSA,A,3,08,10,04,27,,,,,,,,,2.1,2.8,1.6*34 +{"class":"TPV","tag":"MID2","time":1118327717.280,"ept":0.005,"lat":46.498293953,"lon":7.567397047,"alt":1344.444,"epx":11.098,"epy":18.270,"epv":36.204,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,08,23,06,084,00,28,07,160,00,08,66,189,41,29,14,273,00*76 +$GPGSV,2,2,08,10,51,304,35,04,15,199,23,02,34,241,37,27,71,075,41*77 +{"class":"SKY","tag":"MID4","time":1118327718.280,"xdop":0.74,"ydop":1.22,"vdop":1.57,"tdop":0.80,"hdop":1.43,"gdop":2.27,"pdop":2.12,"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":41,"used":true},{"PRN":29,"el":14,"az":273,"ss":0,"used":false},{"PRN":10,"el":51,"az":304,"ss":35,"used":true},{"PRN":4,"el":15,"az":199,"ss":23,"used":true},{"PRN":2,"el":34,"az":241,"ss":37,"used":false},{"PRN":27,"el":71,"az":75,"ss":41,"used":true}]} diff --git a/test/daemon/bu303-nofix.log b/test/daemon/bu303-nofix.log new file mode 100644 index 0000000..6cefa78 Binary files /dev/null and b/test/daemon/bu303-nofix.log differ 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 0000000..54e5404 Binary files /dev/null and b/test/daemon/bu303-stillfix.log differ 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 0000000..361d34c Binary files /dev/null and b/test/daemon/bu303b-nofix.log differ 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 0000000..4813b1a Binary files /dev/null and b/test/daemon/italk-binary.log differ diff --git a/test/daemon/italk-binary.log.chk b/test/daemon/italk-binary.log.chk new file mode 100644 index 0000000..54c5120 --- /dev/null +++ b/test/daemon/italk-binary.log.chk @@ -0,0 +1,201 @@ +$GPGGA,221300,5333.7947,N,11326.3773,W,1,05,,661.09,M,-19.872,M,,*65 +$GPRMC,221300,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*39 +$GPGSA,A,3,,,,,,,,,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"ITK-07","time":1246918380.144,"ept":0.005,"lat":53.563244879,"lon":-113.439622385,"alt":661.089,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,3,1,09,03,35,061,32,06,26,049,34,07,76,101,23,08,60,183,38*71 +$GPGSV,3,2,09,10,23,180,00,13,33,166,16,19,43,094,47,25,54,109,44*73 +$GPGSV,3,3,09,28,30,125,00*4F +{"class":"SKY","tag":"ITK-02","time":1246918380.322,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":32,"used":true},{"PRN":6,"el":26,"az":49,"ss":34,"used":true},{"PRN":7,"el":76,"az":101,"ss":23,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":0,"used":false},{"PRN":13,"el":33,"az":166,"ss":16,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":44,"used":true},{"PRN":28,"el":30,"az":125,"ss":0,"used":false}]} +$GPGGA,221301,5333.7947,N,11326.3773,W,1,05,7.74,661.09,M,-19.872,M,,*7E +$GPRMC,221301,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*38 +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221301,102.11,M,55.39,M,75.10,M*37 +{"class":"TPV","tag":"ITK-07","time":1246918381.145,"ept":0.005,"lat":53.563244879,"lon":-113.439622385,"alt":661.089,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGSV,3,1,09,03,35,061,31,06,26,049,34,07,76,101,00,08,60,183,38*73 +$GPGSV,3,2,09,10,23,180,05,13,33,166,12,19,43,094,47,25,54,109,44*72 +$GPGSV,3,3,09,28,30,125,00*4F +{"class":"SKY","tag":"ITK-02","time":1246918381.326,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":31,"used":true},{"PRN":6,"el":26,"az":49,"ss":34,"used":true},{"PRN":7,"el":76,"az":101,"ss":0,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":5,"used":false},{"PRN":13,"el":33,"az":166,"ss":12,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":44,"used":true},{"PRN":28,"el":30,"az":125,"ss":0,"used":false}]} +$GPGGA,221302,5333.7947,N,11326.3773,W,1,05,7.74,661.09,M,-19.872,M,,*7D +$GPRMC,221302,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3B +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221302,102.11,M,55.39,M,75.10,M*34 +{"class":"TPV","tag":"ITK-07","time":1246918382.146,"ept":0.005,"lat":53.563244812,"lon":-113.439622325,"alt":661.095,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGSV,3,1,09,03,35,061,31,06,26,049,34,07,76,101,00,08,60,183,38*73 +$GPGSV,3,2,09,10,23,180,22,13,33,166,00,19,43,094,47,25,54,109,44*74 +$GPGSV,3,3,09,28,30,125,09*46 +{"class":"SKY","tag":"ITK-02","time":1246918382.334,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":31,"used":true},{"PRN":6,"el":26,"az":49,"ss":34,"used":true},{"PRN":7,"el":76,"az":101,"ss":0,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":22,"used":false},{"PRN":13,"el":33,"az":166,"ss":0,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":44,"used":true},{"PRN":28,"el":30,"az":125,"ss":9,"used":false}]} +$GPGGA,221303,5333.7947,N,11326.3773,W,1,05,7.74,661.09,M,-19.872,M,,*7C +$GPRMC,221303,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3A +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221303,102.11,M,55.39,M,75.10,M*35 +{"class":"TPV","tag":"ITK-07","time":1246918383.146,"ept":0.005,"lat":53.563244812,"lon":-113.439622325,"alt":661.095,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.22,"mode":3} +$GPGSV,3,1,09,03,35,061,31,06,26,049,35,07,76,101,05,08,60,183,38*77 +$GPGSV,3,2,09,10,23,180,25,13,33,166,00,19,43,094,47,25,54,109,44*73 +$GPGSV,3,3,09,28,30,125,18*46 +{"class":"SKY","tag":"ITK-02","time":1246918383.482,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":31,"used":true},{"PRN":6,"el":26,"az":49,"ss":35,"used":true},{"PRN":7,"el":76,"az":101,"ss":5,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":25,"used":false},{"PRN":13,"el":33,"az":166,"ss":0,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":44,"used":true},{"PRN":28,"el":30,"az":125,"ss":18,"used":false}]} +$GPGGA,221304,5333.7947,N,11326.3773,W,1,05,7.74,661.09,M,-19.872,M,,*7B +$GPRMC,221304,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3D +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +{"class":"TPV","tag":"ITK-07","time":1246918384.147,"ept":0.005,"lat":53.563244812,"lon":-113.439622325,"alt":661.095,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGGA,221305,5333.7947,N,11326.3773,W,1,05,7.74,661.09,M,-19.872,M,,*7A +$GPRMC,221305,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3C +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +{"class":"TPV","tag":"ITK-07","time":1246918385.147,"ept":0.005,"lat":53.563244812,"lon":-113.439622325,"alt":661.095,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.22,"mode":3} +$GPGSV,3,1,09,03,35,061,31,06,26,049,34,07,76,101,26,08,60,183,38*77 +$GPGSV,3,2,09,10,23,180,00,13,33,166,15,19,43,094,48,25,54,109,44*7F +$GPGSV,3,3,09,28,30,125,27*4A +{"class":"SKY","tag":"ITK-02","time":1246918385.362,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":31,"used":true},{"PRN":6,"el":26,"az":49,"ss":34,"used":true},{"PRN":7,"el":76,"az":101,"ss":26,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":0,"used":false},{"PRN":13,"el":33,"az":166,"ss":15,"used":false},{"PRN":19,"el":43,"az":94,"ss":48,"used":true},{"PRN":25,"el":54,"az":109,"ss":44,"used":true},{"PRN":28,"el":30,"az":125,"ss":27,"used":false}]} +$GPGGA,221306,5333.7947,N,11326.3773,W,1,05,7.74,661.09,M,-19.872,M,,*79 +$GPRMC,221306,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3F +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +{"class":"TPV","tag":"ITK-07","time":1246918386.148,"ept":0.005,"lat":53.563244812,"lon":-113.439622325,"alt":661.095,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGSV,3,1,09,03,35,061,31,06,26,049,33,07,76,101,27,08,60,183,38*71 +$GPGSV,3,2,09,10,23,180,00,13,33,166,18,19,43,094,47,25,54,109,44*7D +$GPGSV,3,3,09,28,30,125,00*4F +{"class":"SKY","tag":"ITK-02","time":1246918386.328,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":31,"used":true},{"PRN":6,"el":26,"az":49,"ss":33,"used":true},{"PRN":7,"el":76,"az":101,"ss":27,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":0,"used":false},{"PRN":13,"el":33,"az":166,"ss":18,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":44,"used":true},{"PRN":28,"el":30,"az":125,"ss":0,"used":false}]} +$GPGGA,221307,5333.7947,N,11326.3773,W,1,05,7.74,661.09,M,-19.872,M,,*78 +$GPRMC,221307,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3E +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221307,102.11,M,55.39,M,75.10,M*31 +{"class":"TPV","tag":"ITK-07","time":1246918387.149,"ept":0.005,"lat":53.563244812,"lon":-113.439622325,"alt":661.095,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGSV,3,1,09,03,35,061,31,06,26,049,33,07,76,101,00,08,60,183,38*74 +$GPGSV,3,2,09,10,23,180,06,13,33,166,15,19,43,094,48,25,54,109,45*78 +$GPGSV,3,3,09,28,30,125,00*4F +{"class":"SKY","tag":"ITK-02","time":1246918387.331,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":31,"used":true},{"PRN":6,"el":26,"az":49,"ss":33,"used":true},{"PRN":7,"el":76,"az":101,"ss":0,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":6,"used":false},{"PRN":13,"el":33,"az":166,"ss":15,"used":false},{"PRN":19,"el":43,"az":94,"ss":48,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":0,"used":false}]} +$GPGGA,221308,5333.7947,N,11326.3773,W,1,05,7.74,661.10,M,-19.872,M,,*7F +$GPRMC,221308,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*31 +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221308,102.11,M,55.39,M,75.10,M*3E +{"class":"TPV","tag":"ITK-07","time":1246918388.149,"ept":0.005,"lat":53.563244746,"lon":-113.439622265,"alt":661.100,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.22,"mode":3} +$GPGSV,3,1,09,03,35,061,31,06,26,049,33,07,76,101,00,08,60,183,38*74 +$GPGSV,3,2,09,10,23,180,14,13,33,166,00,19,43,094,47,25,54,109,45*70 +$GPGSV,3,3,09,28,30,125,02*4D +{"class":"SKY","tag":"ITK-02","time":1246918388.336,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":31,"used":true},{"PRN":6,"el":26,"az":49,"ss":33,"used":true},{"PRN":7,"el":76,"az":101,"ss":0,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":14,"used":false},{"PRN":13,"el":33,"az":166,"ss":0,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":2,"used":false}]} +$GPGGA,221309,5333.7947,N,11326.3773,W,1,05,7.74,661.10,M,-19.872,M,,*7E +$GPRMC,221309,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*30 +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221309,102.11,M,55.39,M,75.10,M*3F +{"class":"TPV","tag":"ITK-07","time":1246918389.150,"ept":0.005,"lat":53.563244746,"lon":-113.439622265,"alt":661.100,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGSV,3,1,09,03,35,061,31,06,26,049,32,07,76,101,08,08,60,183,38*7D +$GPGSV,3,2,09,10,23,180,10,13,33,166,00,19,43,094,48,25,54,109,45*7B +$GPGSV,3,3,09,28,30,125,16*48 +{"class":"SKY","tag":"ITK-02","time":1246918389.358,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":31,"used":true},{"PRN":6,"el":26,"az":49,"ss":32,"used":true},{"PRN":7,"el":76,"az":101,"ss":8,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":10,"used":false},{"PRN":13,"el":33,"az":166,"ss":0,"used":false},{"PRN":19,"el":43,"az":94,"ss":48,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":16,"used":false}]} +$GPGGA,221310,5333.7947,N,11326.3773,W,1,05,7.74,661.10,M,-19.872,M,,*76 +$GPRMC,221310,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*38 +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +{"class":"TPV","tag":"ITK-07","time":1246918390.151,"ept":0.005,"lat":53.563244775,"lon":-113.439622126,"alt":661.098,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGGA,221311,5333.7947,N,11326.3773,W,1,05,7.74,661.10,M,-19.872,M,,*77 +$GPRMC,221311,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*39 +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +{"class":"TPV","tag":"ITK-07","time":1246918391.151,"ept":0.005,"lat":53.563244775,"lon":-113.439622126,"alt":661.098,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.22,"mode":3} +$GPGSV,3,1,09,03,35,061,31,06,26,049,32,07,76,101,26,08,60,183,37*7E +$GPGSV,3,2,09,10,23,180,00,13,33,166,14,19,43,094,47,25,54,109,45*70 +$GPGSV,3,3,09,28,30,125,16*48 +{"class":"SKY","tag":"ITK-02","time":1246918391.371,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":31,"used":true},{"PRN":6,"el":26,"az":49,"ss":32,"used":true},{"PRN":7,"el":76,"az":101,"ss":26,"used":false},{"PRN":8,"el":60,"az":183,"ss":37,"used":true},{"PRN":10,"el":23,"az":180,"ss":0,"used":false},{"PRN":13,"el":33,"az":166,"ss":14,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":16,"used":false}]} +$GPGGA,221312,5333.7947,N,11326.3773,W,1,05,7.74,661.10,M,-19.872,M,,*74 +$GPRMC,221312,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3A +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +{"class":"TPV","tag":"ITK-07","time":1246918392.152,"ept":0.005,"lat":53.563244709,"lon":-113.439622066,"alt":661.103,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGSV,3,1,09,03,35,061,31,06,26,049,32,07,76,101,26,08,60,183,37*7E +$GPGSV,3,2,09,10,23,180,00,13,33,166,20,19,43,094,47,25,54,109,45*77 +$GPGSV,3,3,09,28,30,125,00*4F +{"class":"SKY","tag":"ITK-02","time":1246918392.326,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":31,"used":true},{"PRN":6,"el":26,"az":49,"ss":32,"used":true},{"PRN":7,"el":76,"az":101,"ss":26,"used":false},{"PRN":8,"el":60,"az":183,"ss":37,"used":true},{"PRN":10,"el":23,"az":180,"ss":0,"used":false},{"PRN":13,"el":33,"az":166,"ss":20,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":0,"used":false}]} +$GPGGA,221313,5333.7947,N,11326.3773,W,1,05,7.74,661.10,M,-19.872,M,,*75 +$GPRMC,221313,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3B +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221313,102.11,M,55.39,M,75.10,M*34 +{"class":"TPV","tag":"ITK-07","time":1246918393.153,"ept":0.005,"lat":53.563244709,"lon":-113.439622066,"alt":661.103,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGGA,221314,5333.7947,N,11326.3773,W,1,04,7.74,661.10,M,-19.872,M,,*73 +$GPRMC,221314,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3C +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221314,102.11,M,55.39,M,75.10,M*33 +{"class":"TPV","tag":"ITK-07","time":1246918394.153,"ept":0.005,"lat":53.563244709,"lon":-113.439622066,"alt":661.103,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.22,"mode":3} +$GPGSV,3,1,09,03,35,061,00,06,26,049,32,07,76,101,00,08,60,183,38*77 +$GPGSV,3,2,09,10,23,180,16,13,33,166,00,19,43,094,48,25,54,109,45*7D +$GPGSV,3,3,09,28,30,125,04*4B +{"class":"SKY","tag":"ITK-02","time":1246918394.337,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":0,"used":true},{"PRN":6,"el":26,"az":49,"ss":32,"used":true},{"PRN":7,"el":76,"az":101,"ss":0,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":16,"used":false},{"PRN":13,"el":33,"az":166,"ss":0,"used":false},{"PRN":19,"el":43,"az":94,"ss":48,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":4,"used":false}]} +$GPGGA,221315,5333.7947,N,11326.3773,W,1,04,7.74,661.10,M,-19.872,M,,*72 +$GPRMC,221315,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3D +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221315,102.11,M,55.39,M,75.10,M*32 +{"class":"TPV","tag":"ITK-07","time":1246918395.154,"ept":0.005,"lat":53.563244709,"lon":-113.439622066,"alt":661.103,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGSV,3,1,09,03,35,061,00,06,26,049,33,07,76,101,05,08,60,183,38*73 +$GPGSV,3,2,09,10,23,180,17,13,33,166,00,19,43,094,48,25,54,109,45*7C +$GPGSV,3,3,09,28,30,125,19*47 +{"class":"SKY","tag":"ITK-02","time":1246918395.386,"xdop":6.81,"ydop":3.69,"vdop":3.27,"tdop":4.44,"hdop":7.74,"gdop":9.50,"pdop":8.40,"satellites":[{"PRN":3,"el":35,"az":61,"ss":0,"used":true},{"PRN":6,"el":26,"az":49,"ss":33,"used":true},{"PRN":7,"el":76,"az":101,"ss":5,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":17,"used":false},{"PRN":13,"el":33,"az":166,"ss":0,"used":false},{"PRN":19,"el":43,"az":94,"ss":48,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":19,"used":false}]} +$GPGGA,221316,5333.7947,N,11326.3773,W,1,04,7.74,661.10,M,-19.872,M,,*71 +$GPRMC,221316,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3E +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221316,102.11,M,55.39,M,75.10,M*31 +{"class":"TPV","tag":"ITK-07","time":1246918396.155,"ept":0.005,"lat":53.563244589,"lon":-113.439622006,"alt":661.101,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.01,"mode":3} +$GPGGA,221317,5333.7947,N,11326.3773,W,1,04,7.74,661.10,M,-19.872,M,,*70 +$GPRMC,221317,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3F +$GPGSA,A,3,03,06,08,19,25,,,,,,,,8.4,7.7,3.3*3C +$GPGBS,221317,102.11,M,55.39,M,75.10,M*30 +{"class":"TPV","tag":"ITK-07","time":1246918397.155,"ept":0.005,"lat":53.563244589,"lon":-113.439622006,"alt":661.101,"epx":102.108,"epy":55.386,"epv":75.102,"track":0.0000,"speed":0.000,"climb":0.000,"eps":204.22,"mode":3} +$GPGSV,3,1,09,03,35,061,24,06,26,049,32,07,76,101,19,08,60,183,38*79 +$GPGSV,3,2,09,10,23,180,00,13,33,166,15,19,43,094,47,25,54,109,45*71 +$GPGSV,3,3,09,28,30,125,21*4C +{"class":"SKY","tag":"ITK-02","time":1246918397.328,"xdop":7.46,"ydop":5.36,"vdop":4.49,"tdop":4.67,"hdop":9.19,"gdop":11.24,"pdop":10.23,"satellites":[{"PRN":3,"el":35,"az":61,"ss":24,"used":false},{"PRN":6,"el":26,"az":49,"ss":32,"used":true},{"PRN":7,"el":76,"az":101,"ss":19,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":0,"used":false},{"PRN":13,"el":33,"az":166,"ss":15,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":21,"used":false}]} +$GPGGA,221318,5333.7947,N,11326.3773,W,1,04,9.19,661.10,M,-19.872,M,,*7A +$GPRMC,221318,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*30 +$GPGSA,A,3,06,08,19,25,25,,,,,,,,10.2,9.2,4.5*0D +{"class":"TPV","tag":"ITK-07","time":1246918398.156,"ept":0.005,"lat":53.563244589,"lon":-113.439622006,"alt":661.101,"epx":111.917,"epy":80.379,"epv":103.296,"track":0.0000,"speed":0.000,"climb":0.000,"eps":213.81,"mode":3} +$GPGSV,3,1,09,03,35,061,25,06,26,049,32,07,76,101,20,08,60,183,38*72 +$GPGSV,3,2,09,10,23,180,00,13,33,166,19,19,43,094,47,25,54,109,45*7D +$GPGSV,3,3,09,28,30,125,00*4F +{"class":"SKY","tag":"ITK-02","time":1246918398.391,"xdop":7.46,"ydop":5.36,"vdop":4.49,"tdop":4.67,"hdop":9.19,"gdop":11.24,"pdop":10.23,"satellites":[{"PRN":3,"el":35,"az":61,"ss":25,"used":false},{"PRN":6,"el":26,"az":49,"ss":32,"used":true},{"PRN":7,"el":76,"az":101,"ss":20,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":0,"used":false},{"PRN":13,"el":33,"az":166,"ss":19,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":0,"used":false}]} +$GPGGA,221319,5333.7947,N,11326.3773,W,1,04,9.19,661.10,M,-19.872,M,,*7B +$GPRMC,221319,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*31 +$GPGSA,A,3,06,08,19,25,25,,,,,,,,10.2,9.2,4.5*0D +$GPGBS,221319,111.92,M,80.38,M,103.30,M*0C +{"class":"TPV","tag":"ITK-07","time":1246918399.157,"ept":0.005,"lat":53.563244589,"lon":-113.439622006,"alt":661.101,"epx":111.917,"epy":80.379,"epv":103.296,"track":0.0000,"speed":0.000,"climb":0.000,"eps":223.61,"mode":3} +$GPGGA,221320,5333.7947,N,11326.3773,W,1,04,9.19,661.11,M,-19.872,M,,*70 +$GPRMC,221320,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3B +$GPGSA,A,3,06,08,19,25,25,,,,,,,,10.2,9.2,4.5*0D +{"class":"TPV","tag":"ITK-07","time":1246918400.157,"ept":0.005,"lat":53.563244523,"lon":-113.439621946,"alt":661.106,"epx":111.917,"epy":80.379,"epv":103.296,"track":0.0000,"speed":0.000,"climb":0.000,"eps":223.83,"mode":3} +$GPGSV,3,1,09,03,35,061,00,06,26,049,32,07,76,101,00,08,60,183,38*77 +$GPGSV,3,2,09,10,23,180,24,13,33,166,00,19,43,094,48,25,54,109,45*7C +$GPGSV,3,3,09,28,30,125,06*49 +{"class":"SKY","tag":"ITK-02","time":1246918400.329,"xdop":7.46,"ydop":5.36,"vdop":4.49,"tdop":4.67,"hdop":9.19,"gdop":11.24,"pdop":10.23,"satellites":[{"PRN":3,"el":35,"az":61,"ss":0,"used":false},{"PRN":6,"el":26,"az":49,"ss":32,"used":true},{"PRN":7,"el":76,"az":101,"ss":0,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":24,"used":false},{"PRN":13,"el":33,"az":166,"ss":0,"used":false},{"PRN":19,"el":43,"az":94,"ss":48,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":6,"used":false}]} +$GPGGA,221321,5333.7947,N,11326.3773,W,1,04,9.19,661.11,M,-19.872,M,,*71 +$GPRMC,221321,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3A +$GPGSA,A,3,06,08,19,25,25,,,,,,,,10.2,9.2,4.5*0D +{"class":"TPV","tag":"ITK-07","time":1246918401.158,"ept":0.005,"lat":53.563244523,"lon":-113.439621946,"alt":661.106,"epx":111.917,"epy":80.379,"epv":103.296,"track":0.0000,"speed":0.000,"climb":0.000,"eps":223.61,"mode":3} +$GPGSV,3,1,09,03,35,061,00,06,26,049,31,07,76,101,00,08,60,183,38*74 +$GPGSV,3,2,09,10,23,180,25,13,33,166,00,19,43,094,47,25,54,109,45*72 +$GPGSV,3,3,09,28,30,125,07*48 +{"class":"SKY","tag":"ITK-02","time":1246918401.431,"xdop":7.46,"ydop":5.36,"vdop":4.49,"tdop":4.67,"hdop":9.19,"gdop":11.24,"pdop":10.23,"satellites":[{"PRN":3,"el":35,"az":61,"ss":0,"used":false},{"PRN":6,"el":26,"az":49,"ss":31,"used":true},{"PRN":7,"el":76,"az":101,"ss":0,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":25,"used":false},{"PRN":13,"el":33,"az":166,"ss":0,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":7,"used":false}]} +$GPGGA,221322,5333.7947,N,11326.3773,W,1,04,9.19,661.11,M,-19.872,M,,*72 +$GPRMC,221322,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*39 +$GPGSA,A,3,06,08,19,25,25,,,,,,,,10.2,9.2,4.5*0D +{"class":"TPV","tag":"ITK-07","time":1246918402.158,"ept":0.005,"lat":53.563244523,"lon":-113.439621946,"alt":661.106,"epx":111.917,"epy":80.379,"epv":103.296,"track":0.0000,"speed":0.000,"climb":0.000,"eps":223.83,"mode":3} +$GPGGA,221323,5333.7947,N,11326.3773,W,1,04,9.19,661.11,M,-19.872,M,,*73 +$GPRMC,221323,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*38 +$GPGSA,A,3,06,08,19,25,25,,,,,,,,10.2,9.2,4.5*0D +{"class":"TPV","tag":"ITK-07","time":1246918403.159,"ept":0.005,"lat":53.563244523,"lon":-113.439621946,"alt":661.106,"epx":111.917,"epy":80.379,"epv":103.296,"track":0.0000,"speed":0.000,"climb":0.000,"eps":223.61,"mode":3} +$GPGSV,3,1,09,03,35,061,24,06,26,049,32,07,76,101,21,08,60,183,38*72 +$GPGSV,3,2,09,10,23,180,00,13,33,166,21,19,43,094,47,25,54,109,45*76 +$GPGSV,3,3,09,28,30,125,17*49 +{"class":"SKY","tag":"ITK-02","time":1246918403.350,"xdop":7.46,"ydop":5.36,"vdop":4.49,"tdop":4.67,"hdop":9.19,"gdop":11.24,"pdop":10.23,"satellites":[{"PRN":3,"el":35,"az":61,"ss":24,"used":false},{"PRN":6,"el":26,"az":49,"ss":32,"used":true},{"PRN":7,"el":76,"az":101,"ss":21,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":0,"used":false},{"PRN":13,"el":33,"az":166,"ss":21,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":17,"used":false}]} +$GPGGA,221324,5333.7947,N,11326.3773,W,1,04,9.19,661.11,M,-19.872,M,,*74 +$GPRMC,221324,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3F +$GPGSA,A,3,06,08,19,25,25,,,,,,,,10.2,9.2,4.5*0D +{"class":"TPV","tag":"ITK-07","time":1246918404.160,"ept":0.005,"lat":53.563244428,"lon":-113.439622025,"alt":661.114,"epx":111.917,"epy":80.379,"epv":103.296,"track":0.0000,"speed":0.000,"climb":0.000,"eps":223.61,"mode":3} +$GPGSV,3,1,09,03,35,061,26,06,26,049,32,07,76,101,22,08,60,183,38*73 +$GPGSV,3,2,09,10,23,180,00,13,33,166,19,19,43,094,47,25,54,109,45*7D +$GPGSV,3,3,09,28,30,125,00*4F +{"class":"SKY","tag":"ITK-02","time":1246918404.356,"xdop":7.46,"ydop":5.36,"vdop":4.49,"tdop":4.67,"hdop":9.19,"gdop":11.24,"pdop":10.23,"satellites":[{"PRN":3,"el":35,"az":61,"ss":26,"used":false},{"PRN":6,"el":26,"az":49,"ss":32,"used":true},{"PRN":7,"el":76,"az":101,"ss":22,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":0,"used":false},{"PRN":13,"el":33,"az":166,"ss":19,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":0,"used":false}]} +$GPGGA,221325,5333.7947,N,11326.3773,W,1,04,9.19,661.11,M,-19.872,M,,*75 +$GPRMC,221325,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3E +$GPGSA,A,3,06,08,19,25,25,,,,,,,,10.2,9.2,4.5*0D +$GPGBS,221325,111.92,M,80.38,M,103.30,M*03 +{"class":"TPV","tag":"ITK-07","time":1246918405.160,"ept":0.005,"lat":53.563244428,"lon":-113.439622025,"alt":661.114,"epx":111.917,"epy":80.379,"epv":103.296,"track":0.0000,"speed":0.000,"climb":0.000,"eps":223.83,"mode":3} +$GPGGA,221326,5333.7947,N,11326.3773,W,1,04,9.19,661.11,M,-19.872,M,,*76 +$GPRMC,221326,A,5333.7947,N,11326.3773,W,0.0000,0.000,060709,,*3D +$GPGSA,A,3,06,08,19,25,25,,,,,,,,10.2,9.2,4.5*0D +{"class":"TPV","tag":"ITK-07","time":1246918406.161,"ept":0.005,"lat":53.563244428,"lon":-113.439622025,"alt":661.114,"epx":111.917,"epy":80.379,"epv":103.296,"track":0.0000,"speed":0.000,"climb":0.000,"eps":223.61,"mode":3} +$GPGSV,3,1,09,03,35,061,00,06,26,049,32,07,76,101,00,08,60,183,38*77 +$GPGSV,3,2,09,10,23,180,16,13,33,166,00,19,43,094,47,25,54,109,45*72 +$GPGSV,3,3,09,28,30,125,02*4D +{"class":"SKY","tag":"ITK-02","time":1246918406.375,"xdop":7.46,"ydop":5.36,"vdop":4.49,"tdop":4.67,"hdop":9.19,"gdop":11.24,"pdop":10.23,"satellites":[{"PRN":3,"el":35,"az":61,"ss":0,"used":false},{"PRN":6,"el":26,"az":49,"ss":32,"used":true},{"PRN":7,"el":76,"az":101,"ss":0,"used":false},{"PRN":8,"el":60,"az":183,"ss":38,"used":true},{"PRN":10,"el":23,"az":180,"ss":16,"used":false},{"PRN":13,"el":33,"az":166,"ss":0,"used":false},{"PRN":19,"el":43,"az":94,"ss":47,"used":true},{"PRN":25,"el":54,"az":109,"ss":45,"used":true},{"PRN":28,"el":30,"az":125,"ss":2,"used":false}]} diff --git a/test/daemon/magellan-ec10.log b/test/daemon/magellan-ec10.log new file mode 100644 index 0000000..1f56c3e --- /dev/null +++ b/test/daemon/magellan-ec10.log @@ -0,0 +1,87 @@ +# Name: Magellan EC-10X +# Submitted-by: "Gary E. Miller" +# 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 0000000..b0b93a5 Binary files /dev/null and b/test/daemon/navcom.log differ 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 0000000..462d425 Binary files /dev/null and b/test/daemon/superstar2.log differ 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 0000000..250099d Binary files /dev/null and b/test/daemon/trimble-lassen_iq-3dfix.log differ diff --git a/test/daemon/trimble-lassen_iq-3dfix.log.chk b/test/daemon/trimble-lassen_iq-3dfix.log.chk new file mode 100644 index 0000000..4cf470c --- /dev/null +++ b/test/daemon/trimble-lassen_iq-3dfix.log.chk @@ -0,0 +1,212 @@ +$GPGSV,3,1,10,00,00,000,00,19,26,250,29,00,00,000,00,18,26,096,37*7C +$GPGSV,3,2,10,01,29,221,26,11,24,307,29,03,08,225,28,00,00,000,00*7B +$GPGSV,3,3,10,22,65,094,37,09,24,045,37*78 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":2.56,"tdop":1.47,"hdop":1.43,"gdop":3.28,"pdop":2.93,"satellites":[{"PRN":19,"el":26,"az":250,"ss":29,"used":true},{"PRN":18,"el":26,"az":96,"ss":37,"used":true},{"PRN":1,"el":29,"az":221,"ss":26,"used":false},{"PRN":11,"el":24,"az":307,"ss":29,"used":true},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGSV,3,1,10,00,00,000,00,19,26,250,29,00,00,000,00,18,26,096,38*73 +$GPGSV,3,2,10,01,29,221,29,11,25,307,26,03,08,225,28,00,00,000,00*7A +$GPGSV,3,3,10,22,65,094,38,09,24,045,38*78 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":2.51,"tdop":1.38,"hdop":1.75,"gdop":3.36,"pdop":3.06,"satellites":[{"PRN":19,"el":26,"az":250,"ss":29,"used":true},{"PRN":18,"el":26,"az":96,"ss":38,"used":true},{"PRN":1,"el":29,"az":221,"ss":29,"used":true},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGSV,3,1,10,00,00,000,00,19,26,250,29,00,00,000,00,18,26,096,39*72 +$GPGSV,3,2,10,01,29,221,30,11,25,307,26,03,08,225,28,00,00,000,00*72 +$GPGSV,3,3,10,22,65,094,38,09,24,045,41*76 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":2.54,"tdop":1.54,"hdop":2.07,"gdop":3.62,"pdop":3.27,"satellites":[{"PRN":19,"el":26,"az":250,"ss":29,"used":false},{"PRN":18,"el":26,"az":96,"ss":39,"used":true},{"PRN":1,"el":29,"az":221,"ss":30,"used":true},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGSV,3,1,10,00,00,000,00,19,26,250,29,00,00,000,00,18,26,096,39*72 +$GPGSV,3,2,10,01,29,221,30,11,25,307,26,03,08,225,28,00,00,000,00*72 +$GPGSV,3,3,10,22,64,094,39,09,24,045,40*77 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":2.54,"tdop":1.54,"hdop":2.07,"gdop":3.62,"pdop":3.27,"satellites":[{"PRN":19,"el":26,"az":250,"ss":29,"used":false},{"PRN":18,"el":26,"az":96,"ss":39,"used":true},{"PRN":1,"el":29,"az":221,"ss":30,"used":true},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGSV,3,1,10,00,00,000,00,19,26,250,29,00,00,000,00,18,26,096,39*72 +$GPGSV,3,2,10,01,29,221,30,11,25,307,26,03,08,225,28,00,00,000,00*72 +$GPGSV,3,3,10,22,64,094,40,09,24,045,39*77 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":2.54,"tdop":1.54,"hdop":2.06,"gdop":3.62,"pdop":3.27,"satellites":[{"PRN":19,"el":26,"az":250,"ss":29,"used":false},{"PRN":18,"el":26,"az":96,"ss":39,"used":true},{"PRN":1,"el":29,"az":221,"ss":30,"used":true},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGSV,3,1,10,00,00,000,00,19,26,250,29,00,00,000,00,18,26,096,39*72 +$GPGSV,3,2,10,01,29,221,29,11,25,307,26,03,08,225,28,00,00,000,00*7A +$GPGSV,3,3,10,22,64,094,41,09,24,045,38*77 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":2.54,"tdop":1.54,"hdop":2.06,"gdop":3.62,"pdop":3.27,"satellites":[{"PRN":19,"el":26,"az":250,"ss":29,"used":false},{"PRN":18,"el":26,"az":96,"ss":39,"used":true},{"PRN":1,"el":29,"az":221,"ss":29,"used":true},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGSV,3,1,10,00,00,000,00,19,26,250,29,00,00,000,00,18,26,096,39*72 +$GPGSV,3,2,10,01,29,221,28,11,25,307,26,03,08,225,28,00,00,000,00*7B +$GPGSV,3,3,10,22,64,094,41,09,24,045,40*78 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":2.54,"tdop":1.54,"hdop":2.06,"gdop":3.61,"pdop":3.27,"satellites":[{"PRN":19,"el":26,"az":250,"ss":29,"used":false},{"PRN":18,"el":26,"az":96,"ss":39,"used":true},{"PRN":1,"el":29,"az":221,"ss":28,"used":true},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGGA,065813,5332.3091,N,11329.9353,W,1,03,2.06,698.96,M,-19.813,M,,*71 +$GPRMC,065813,A,5332.3091,N,11329.9353,W,0.0000,0.000,261106,,*3C +$GPGSA,A,2,00,00,00,00,,,,,,,,,3.3,2.1,2.5*37 +{"class":"TPV","tag":"ID8f20","time":1164524293.000,"ept":0.005,"lat":53.538484440,"lon":-113.498921410,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"mode":2} +$GPGGA,065814,5332.3090,N,11329.9353,W,1,03,2.06,698.97,M,-19.813,M,,*76 +$GPRMC,065814,A,5332.3090,N,11329.9353,W,0.0000,0.000,261106,,*3A +$GPGSA,A,2,00,00,00,00,,,,,,,,,3.3,2.1,2.5*37 +{"class":"TPV","tag":"ID8f20","time":1164524294.000,"ept":0.005,"lat":53.538484105,"lon":-113.498921158,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGSV,3,1,10,00,00,000,00,19,26,249,27,00,00,000,00,18,26,096,38*75 +$GPGSV,3,2,10,01,29,221,26,11,25,307,26,03,08,225,28,00,00,000,00*75 +$GPGSV,3,3,10,22,64,094,41,09,24,045,41*79 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":1.00,"tdop":2.55,"hdop":3.72,"gdop":4.62,"pdop":3.85,"satellites":[{"PRN":19,"el":26,"az":249,"ss":27,"used":false},{"PRN":18,"el":26,"az":96,"ss":38,"used":true},{"PRN":1,"el":29,"az":221,"ss":26,"used":false},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGGA,065815,5332.3090,N,11329.9353,W,1,03,3.72,698.97,M,-19.813,M,,*75 +$GPRMC,065815,A,5332.3090,N,11329.9353,W,0.0000,0.000,261106,,*3B +$GPGSA,A,2,00,00,00,,,,,,,,,,3.8,3.7,1.0*3D +{"class":"TPV","tag":"ID8f20","time":1164524295.000,"ept":0.005,"lat":53.538483769,"lon":-113.498920907,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":288.19,"mode":2} +$GPGGA,065816,5332.3090,N,11329.9352,W,1,03,3.72,698.97,M,-19.813,M,,*77 +$GPRMC,065816,A,5332.3090,N,11329.9352,W,0.0000,0.000,261106,,*39 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.8,3.7,1.0*3D +{"class":"TPV","tag":"ID8f20","time":1164524296.000,"ept":0.005,"lat":53.538483434,"lon":-113.498920739,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065817,5332.3090,N,11329.9352,W,1,03,3.72,698.98,M,-19.813,M,,*79 +$GPRMC,065817,A,5332.3090,N,11329.9352,W,0.0000,0.000,261106,,*38 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.8,3.7,1.0*3D +{"class":"TPV","tag":"ID8f20","time":1164524297.000,"ept":0.005,"lat":53.538483099,"lon":-113.498920488,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065818,5332.3090,N,11329.9352,W,1,03,3.72,698.98,M,-19.813,M,,*76 +$GPRMC,065818,A,5332.3090,N,11329.9352,W,0.0000,0.000,261106,,*37 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.8,3.7,1.0*3D +{"class":"TPV","tag":"ID8f20","time":1164524298.000,"ept":0.005,"lat":53.538482764,"lon":-113.498920320,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065819,5332.3090,N,11329.9352,W,1,03,3.72,698.99,M,-19.813,M,,*76 +$GPRMC,065819,A,5332.3090,N,11329.9352,W,0.0000,0.000,261106,,*36 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524299.000,"ept":0.005,"lat":53.538482512,"lon":-113.498920153,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGSV,3,1,10,00,00,000,00,19,26,249,27,00,00,000,00,18,26,096,38*75 +$GPGSV,3,2,10,01,29,221,26,11,25,307,26,03,08,225,28,00,00,000,00*75 +$GPGSV,3,3,10,22,64,094,42,09,24,045,41*7A +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":1.00,"tdop":2.55,"hdop":3.72,"gdop":4.62,"pdop":3.85,"satellites":[{"PRN":19,"el":26,"az":249,"ss":27,"used":false},{"PRN":18,"el":26,"az":96,"ss":38,"used":true},{"PRN":1,"el":29,"az":221,"ss":26,"used":false},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGGA,065820,5332.3089,N,11329.9352,W,1,03,3.72,698.99,M,-19.813,M,,*74 +$GPRMC,065820,A,5332.3089,N,11329.9352,W,0.0000,0.000,261106,,*34 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524300.000,"ept":0.005,"lat":53.538482177,"lon":-113.498919901,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":278.29,"mode":2} +$GPGGA,065821,5332.3089,N,11329.9352,W,1,03,3.72,698.99,M,-19.813,M,,*75 +$GPRMC,065821,A,5332.3089,N,11329.9352,W,0.0000,0.000,261106,,*35 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524301.000,"ept":0.005,"lat":53.538481842,"lon":-113.498919734,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065823,5332.3089,N,11329.9352,W,1,03,3.72,699.00,M,-19.813,M,,*76 +$GPRMC,065823,A,5332.3089,N,11329.9352,W,0.0000,0.000,261106,,*37 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524303.000,"ept":0.005,"lat":53.538481339,"lon":-113.498919482,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":79.08,"mode":2} +$GPGGA,065824,5332.3089,N,11329.9352,W,1,03,3.72,699.00,M,-19.813,M,,*71 +$GPRMC,065824,A,5332.3089,N,11329.9352,W,0.0000,0.000,261106,,*30 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524304.000,"ept":0.005,"lat":53.538481003,"lon":-113.498919314,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGSV,3,1,10,00,00,000,00,19,26,249,27,00,00,000,00,18,26,096,35*78 +$GPGSV,3,2,10,01,30,221,26,11,25,307,26,03,08,225,28,00,00,000,00*7D +$GPGSV,3,3,10,22,64,094,42,09,24,045,40*7B +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":1.00,"tdop":2.55,"hdop":3.72,"gdop":4.62,"pdop":3.85,"satellites":[{"PRN":19,"el":26,"az":249,"ss":27,"used":false},{"PRN":18,"el":26,"az":96,"ss":35,"used":true},{"PRN":1,"el":30,"az":221,"ss":26,"used":false},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGGA,065825,5332.3088,N,11329.9351,W,1,03,3.72,699.01,M,-19.813,M,,*73 +$GPRMC,065825,A,5332.3088,N,11329.9351,W,0.0000,0.000,261106,,*33 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524305.000,"ept":0.005,"lat":53.538480752,"lon":-113.498919147,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065826,5332.3088,N,11329.9351,W,1,03,3.72,699.01,M,-19.813,M,,*70 +$GPRMC,065826,A,5332.3088,N,11329.9351,W,0.0000,0.000,261106,,*30 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524306.000,"ept":0.005,"lat":53.538480500,"lon":-113.498919063,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065827,5332.3088,N,11329.9351,W,1,03,3.72,699.01,M,-19.813,M,,*71 +$GPRMC,065827,A,5332.3088,N,11329.9351,W,0.0000,0.000,261106,,*31 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524307.000,"ept":0.005,"lat":53.538480249,"lon":-113.498918895,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065828,5332.3088,N,11329.9351,W,1,03,3.72,699.02,M,-19.813,M,,*7D +$GPRMC,065828,A,5332.3088,N,11329.9351,W,0.0000,0.000,261106,,*3E +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524308.000,"ept":0.005,"lat":53.538480081,"lon":-113.498918728,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065829,5332.3088,N,11329.9351,W,1,03,3.72,699.02,M,-19.813,M,,*7C +$GPRMC,065829,A,5332.3088,N,11329.9351,W,0.0000,0.000,261106,,*3F +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524309.000,"ept":0.005,"lat":53.538479830,"lon":-113.498918644,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGSV,3,1,10,00,00,000,00,19,26,249,27,00,00,000,00,18,26,096,32*7F +$GPGSV,3,2,10,01,30,221,26,11,25,307,26,03,08,225,28,00,00,000,00*7D +$GPGSV,3,3,10,22,64,094,41,09,24,045,39*76 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":1.00,"tdop":2.56,"hdop":3.72,"gdop":4.63,"pdop":3.85,"satellites":[{"PRN":19,"el":26,"az":249,"ss":27,"used":false},{"PRN":18,"el":26,"az":96,"ss":32,"used":true},{"PRN":1,"el":30,"az":221,"ss":26,"used":false},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGGA,065830,5332.3088,N,11329.9351,W,1,03,3.72,699.03,M,-19.813,M,,*75 +$GPRMC,065830,A,5332.3088,N,11329.9351,W,0.0000,0.000,261106,,*37 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524310.000,"ept":0.005,"lat":53.538479578,"lon":-113.498918476,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065831,5332.3088,N,11329.9351,W,1,03,3.72,699.03,M,-19.813,M,,*74 +$GPRMC,065831,A,5332.3088,N,11329.9351,W,0.0000,0.000,261106,,*36 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524311.000,"ept":0.005,"lat":53.538479327,"lon":-113.498918309,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065832,5332.3087,N,11329.9351,W,1,03,3.72,699.03,M,-19.813,M,,*78 +$GPRMC,065832,A,5332.3087,N,11329.9351,W,0.0000,0.000,261106,,*3A +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524312.000,"ept":0.005,"lat":53.538479159,"lon":-113.498918141,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065833,5332.3087,N,11329.9351,W,1,03,3.72,699.04,M,-19.813,M,,*7E +$GPRMC,065833,A,5332.3087,N,11329.9351,W,0.0000,0.000,261106,,*3B +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524313.000,"ept":0.005,"lat":53.538478908,"lon":-113.498918057,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065834,5332.3087,N,11329.9351,W,1,03,3.72,699.04,M,-19.813,M,,*79 +$GPRMC,065834,A,5332.3087,N,11329.9351,W,0.0000,0.000,261106,,*3C +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524314.000,"ept":0.005,"lat":53.538478740,"lon":-113.498917890,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGSV,3,1,10,00,00,000,00,19,26,249,27,00,00,000,00,18,26,096,32*7F +$GPGSV,3,2,10,01,30,221,26,11,25,307,26,03,08,225,28,00,00,000,00*7D +$GPGSV,3,3,10,22,64,094,40,09,24,045,38*76 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":1.00,"tdop":2.56,"hdop":3.72,"gdop":4.63,"pdop":3.86,"satellites":[{"PRN":19,"el":26,"az":249,"ss":27,"used":false},{"PRN":18,"el":26,"az":96,"ss":32,"used":true},{"PRN":1,"el":30,"az":221,"ss":26,"used":false},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":8,"az":225,"ss":28,"used":false}]} +$GPGGA,065835,5332.3087,N,11329.9351,W,1,03,3.72,699.04,M,-19.813,M,,*78 +$GPRMC,065835,A,5332.3087,N,11329.9351,W,0.0000,0.000,261106,,*3D +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524315.000,"ept":0.005,"lat":53.538478489,"lon":-113.498917806,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065837,5332.3087,N,11329.9351,W,1,03,3.72,699.05,M,-19.813,M,,*7B +$GPRMC,065837,A,5332.3087,N,11329.9351,W,0.0000,0.000,261106,,*3F +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524317.000,"ept":0.005,"lat":53.538478154,"lon":-113.498917722,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":79.08,"mode":2} +$GPGGA,065838,5332.3087,N,11329.9351,W,1,03,3.73,699.05,M,-19.813,M,,*75 +$GPRMC,065838,A,5332.3087,N,11329.9351,W,0.0000,0.000,261106,,*30 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524318.000,"ept":0.005,"lat":53.538477986,"lon":-113.498917722,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065839,5332.3087,N,11329.9351,W,1,03,3.73,699.05,M,-19.813,M,,*74 +$GPRMC,065839,A,5332.3087,N,11329.9351,W,0.0000,0.000,261106,,*31 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524319.000,"ept":0.005,"lat":53.538477818,"lon":-113.498917638,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGSV,3,1,10,00,00,000,00,19,26,249,27,00,00,000,00,18,26,096,30*7D +$GPGSV,3,2,10,01,30,221,26,11,25,307,26,03,07,225,28,00,00,000,00*72 +$GPGSV,3,3,10,22,64,094,40,09,24,045,39*77 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":1.00,"tdop":2.56,"hdop":3.73,"gdop":4.63,"pdop":3.86,"satellites":[{"PRN":19,"el":26,"az":249,"ss":27,"used":false},{"PRN":18,"el":26,"az":96,"ss":30,"used":true},{"PRN":1,"el":30,"az":221,"ss":26,"used":false},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":7,"az":225,"ss":28,"used":false}]} +$GPGGA,065841,5332.3086,N,11329.9350,W,1,03,3.73,699.06,M,-19.813,M,,*78 +$GPRMC,065841,A,5332.3086,N,11329.9350,W,0.0000,0.000,261106,,*3E +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524321.000,"ept":0.005,"lat":53.538477399,"lon":-113.498917470,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":79.08,"mode":2} +$GPGGA,065842,5332.3086,N,11329.9350,W,1,03,3.73,699.06,M,-19.813,M,,*7B +$GPRMC,065842,A,5332.3086,N,11329.9350,W,0.0000,0.000,261106,,*3D +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524322.000,"ept":0.005,"lat":53.538477148,"lon":-113.498917387,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065843,5332.3086,N,11329.9350,W,1,03,3.73,699.07,M,-19.813,M,,*7B +$GPRMC,065843,A,5332.3086,N,11329.9350,W,0.0000,0.000,261106,,*3C +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524323.000,"ept":0.005,"lat":53.538476980,"lon":-113.498917303,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065844,5332.3086,N,11329.9350,W,1,03,3.73,699.07,M,-19.813,M,,*7C +$GPRMC,065844,A,5332.3086,N,11329.9350,W,0.0000,0.000,261106,,*3B +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524324.000,"ept":0.005,"lat":53.538476812,"lon":-113.498917219,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065845,5332.3086,N,11329.9350,W,1,03,3.73,699.07,M,-19.813,M,,*7D +$GPRMC,065845,A,5332.3086,N,11329.9350,W,0.0000,0.000,261106,,*3A +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524325.000,"ept":0.005,"lat":53.538476561,"lon":-113.498917135,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":289.22,"mode":2} +$GPGGA,065846,5332.3086,N,11329.9350,W,1,03,3.73,699.08,M,-19.813,M,,*71 +$GPRMC,065846,A,5332.3086,N,11329.9350,W,0.0000,0.000,261106,,*39 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524326.000,"ept":0.005,"lat":53.538476393,"lon":-113.498917135,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065847,5332.3086,N,11329.9350,W,1,03,3.73,699.08,M,-19.813,M,,*70 +$GPRMC,065847,A,5332.3086,N,11329.9350,W,0.0000,0.000,261106,,*38 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524327.000,"ept":0.005,"lat":53.538476142,"lon":-113.498917051,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065848,5332.3086,N,11329.9350,W,1,03,3.73,699.08,M,-19.813,M,,*7F +$GPRMC,065848,A,5332.3086,N,11329.9350,W,0.0000,0.000,261106,,*37 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524328.000,"ept":0.005,"lat":53.538475974,"lon":-113.498916968,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065849,5332.3085,N,11329.9350,W,1,03,3.73,699.08,M,-19.813,M,,*7D +$GPRMC,065849,A,5332.3085,N,11329.9350,W,0.0000,0.000,261106,,*35 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524329.000,"ept":0.005,"lat":53.538475723,"lon":-113.498916884,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGSV,3,1,10,00,00,000,00,19,26,249,27,00,00,000,00,18,26,096,28*74 +$GPGSV,3,2,10,01,30,221,26,11,25,307,26,03,07,225,28,00,00,000,00*72 +$GPGSV,3,3,10,22,64,094,39,09,24,045,37*77 +{"class":"SKY","tag":"ID5c","xdop":1.21,"ydop":5.27,"vdop":1.00,"tdop":2.57,"hdop":3.73,"gdop":4.64,"pdop":3.86,"satellites":[{"PRN":19,"el":26,"az":249,"ss":27,"used":false},{"PRN":18,"el":26,"az":96,"ss":28,"used":true},{"PRN":1,"el":30,"az":221,"ss":26,"used":false},{"PRN":11,"el":25,"az":307,"ss":26,"used":false},{"PRN":3,"el":7,"az":225,"ss":28,"used":false}]} +$GPGGA,065850,5332.3085,N,11329.9350,W,1,03,3.73,699.09,M,-19.813,M,,*74 +$GPRMC,065850,A,5332.3085,N,11329.9350,W,0.0000,0.000,261106,,*3D +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524330.000,"ept":0.005,"lat":53.538475555,"lon":-113.498916800,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":277.34,"mode":2} +$GPGGA,065851,5332.3085,N,11329.9350,W,1,03,3.73,699.09,M,-19.813,M,,*75 +$GPRMC,065851,A,5332.3085,N,11329.9350,W,0.0000,0.000,261106,,*3C +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524331.000,"ept":0.005,"lat":53.538475388,"lon":-113.498916800,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065852,5332.3085,N,11329.9350,W,1,03,3.73,699.09,M,-19.813,M,,*76 +$GPRMC,065852,A,5332.3085,N,11329.9350,W,0.0000,0.000,261106,,*3F +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524332.000,"ept":0.005,"lat":53.538475136,"lon":-113.498916716,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065853,5332.3085,N,11329.9350,W,1,03,3.73,699.09,M,-19.813,M,,*77 +$GPRMC,065853,A,5332.3085,N,11329.9350,W,0.0000,0.000,261106,,*3E +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524333.000,"ept":0.005,"lat":53.538474968,"lon":-113.498916632,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} +$GPGGA,065854,5332.3085,N,11329.9350,W,1,03,3.73,699.10,M,-19.813,M,,*78 +$GPRMC,065854,A,5332.3085,N,11329.9350,W,0.0000,0.000,261106,,*39 +$GPGSA,A,2,00,00,00,,,,,,,,,,3.9,3.7,1.0*3C +{"class":"TPV","tag":"ID8f20","time":1164524334.000,"ept":0.005,"lat":53.538474717,"lon":-113.498916548,"epx":18.117,"epy":79.085,"track":0.0000,"speed":0.000,"eps":158.17,"mode":2} diff --git a/test/daemon/trimble-lassen_iq-playacar.log b/test/daemon/trimble-lassen_iq-playacar.log new file mode 100644 index 0000000..1750308 Binary files /dev/null and b/test/daemon/trimble-lassen_iq-playacar.log differ 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 0000000..bea0d01 Binary files /dev/null and b/test/daemon/trimble-lassen_iq.log differ 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 0000000..6d93fc4 Binary files /dev/null and b/test/daemon/uBlox-aek-4t.log differ diff --git a/test/daemon/uBlox-aek-4t.log.chk b/test/daemon/uBlox-aek-4t.log.chk new file mode 100644 index 0000000..7374a81 --- /dev/null +++ b/test/daemon/uBlox-aek-4t.log.chk @@ -0,0 +1,70 @@ +$GPGGA,231122,2037.7569,N,08704.0845,W,2,07,,75.78,M,-13.865,M,,*5B +$GPRMC,231122,A,2037.7569,N,08704.0845,W,0.0000,0.000,231207,,*32 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"0x0106","time":1198451482.999,"ept":0.005,"lat":20.629282026,"lon":-87.068075525,"alt":75.777,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,2,1,08,15,67,141,32,02,21,089,31,30,21,234,50,05,18,217,40*7C +$GPGSV,2,2,08,12,16,201,41,18,25,255,41,135,33,251,45,06,54,308,24*40 +{"class":"SKY","tag":"0x0130","xdop":0.69,"ydop":1.52,"vdop":1.99,"tdop":1.31,"hdop":1.67,"gdop":2.91,"pdop":2.60,"satellites":[{"PRN":15,"el":67,"az":141,"ss":32,"used":true},{"PRN":2,"el":21,"az":89,"ss":31,"used":true},{"PRN":30,"el":21,"az":234,"ss":50,"used":true},{"PRN":5,"el":18,"az":217,"ss":40,"used":true},{"PRN":12,"el":16,"az":201,"ss":41,"used":true},{"PRN":18,"el":25,"az":255,"ss":41,"used":true},{"PRN":135,"el":33,"az":251,"ss":45,"used":true},{"PRN":6,"el":54,"az":308,"ss":24,"used":false}]} +$GPGGA,231124,2037.7569,N,08704.0845,W,2,07,1.67,75.76,M,-13.865,M,,*4D +$GPRMC,231124,A,2037.7569,N,08704.0845,W,0.0000,0.000,231207,,*34 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,,2.6,1.7,2.0*32 +{"class":"TPV","tag":"0x0106","time":1198451484.999,"ept":0.005,"lat":20.629281973,"lon":-87.068075520,"alt":75.764,"epx":2.588,"epy":5.690,"epv":11.450,"track":0.0000,"speed":0.000,"climb":0.000,"eps":11.38,"mode":3} +$GPGSV,2,1,08,15,67,141,32,02,21,089,32,30,21,234,50,05,18,217,40*7F +$GPGSV,2,2,08,12,16,201,41,18,25,255,41,135,33,251,45,06,54,308,25*41 +{"class":"SKY","tag":"0x0130","xdop":0.63,"ydop":1.19,"vdop":1.95,"tdop":1.29,"hdop":1.35,"gdop":2.70,"pdop":2.37,"satellites":[{"PRN":15,"el":67,"az":141,"ss":32,"used":true},{"PRN":2,"el":21,"az":89,"ss":32,"used":true},{"PRN":30,"el":21,"az":234,"ss":50,"used":true},{"PRN":5,"el":18,"az":217,"ss":40,"used":true},{"PRN":12,"el":16,"az":201,"ss":41,"used":true},{"PRN":18,"el":25,"az":255,"ss":41,"used":true},{"PRN":135,"el":33,"az":251,"ss":45,"used":true},{"PRN":6,"el":54,"az":308,"ss":25,"used":false}]} +$GPGGA,231125,2037.7569,N,08704.0845,W,2,07,1.35,75.76,M,-13.865,M,,*4B +$GPRMC,231125,A,2037.7569,N,08704.0845,W,0.0000,0.000,231207,,*35 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,2.4,1.3,2.0*34 +{"class":"TPV","tag":"0x0106","time":1198451485.999,"ept":0.005,"lat":20.629281802,"lon":-87.068075424,"alt":75.757,"epx":2.375,"epy":4.455,"epv":11.234,"track":0.0000,"speed":0.000,"climb":0.000,"eps":10.14,"mode":3} +$GPGSV,2,1,08,15,67,141,33,02,21,089,33,30,21,234,50,05,18,217,40*7F +$GPGSV,2,2,08,12,16,201,41,18,25,255,41,135,33,251,45,06,54,308,24*40 +{"class":"SKY","tag":"0x0130","xdop":0.63,"ydop":1.19,"vdop":1.95,"tdop":1.29,"hdop":1.35,"gdop":2.70,"pdop":2.37,"satellites":[{"PRN":15,"el":67,"az":141,"ss":33,"used":true},{"PRN":2,"el":21,"az":89,"ss":33,"used":true},{"PRN":30,"el":21,"az":234,"ss":50,"used":true},{"PRN":5,"el":18,"az":217,"ss":40,"used":true},{"PRN":12,"el":16,"az":201,"ss":41,"used":true},{"PRN":18,"el":25,"az":255,"ss":41,"used":true},{"PRN":135,"el":33,"az":251,"ss":45,"used":true},{"PRN":6,"el":54,"az":308,"ss":24,"used":false}]} +$GPGGA,231126,2037.7569,N,08704.0845,W,2,07,1.35,75.75,M,-13.865,M,,*4B +$GPRMC,231126,A,2037.7569,N,08704.0845,W,0.0000,0.000,231207,,*36 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,2.4,1.3,2.0*34 +{"class":"TPV","tag":"0x0106","time":1198451486.999,"ept":0.005,"lat":20.629281718,"lon":-87.068075424,"alt":75.754,"epx":2.375,"epy":4.455,"epv":11.234,"track":0.0000,"speed":0.000,"climb":0.000,"eps":8.91,"mode":3} +$GPGSV,2,1,08,15,67,141,32,02,21,089,32,30,21,234,50,05,18,217,40*7F +$GPGSV,2,2,08,12,16,201,42,18,25,255,42,135,33,251,44,06,54,308,24*41 +{"class":"SKY","tag":"0x0130","xdop":0.63,"ydop":1.19,"vdop":1.95,"tdop":1.29,"hdop":1.35,"gdop":2.70,"pdop":2.37,"satellites":[{"PRN":15,"el":67,"az":141,"ss":32,"used":true},{"PRN":2,"el":21,"az":89,"ss":32,"used":true},{"PRN":30,"el":21,"az":234,"ss":50,"used":true},{"PRN":5,"el":18,"az":217,"ss":40,"used":true},{"PRN":12,"el":16,"az":201,"ss":42,"used":true},{"PRN":18,"el":25,"az":255,"ss":42,"used":true},{"PRN":135,"el":33,"az":251,"ss":44,"used":true},{"PRN":6,"el":54,"az":308,"ss":24,"used":false}]} +$GPGGA,231127,2037.7569,N,08704.0845,W,2,07,1.35,75.74,M,-13.865,M,,*4B +$GPRMC,231127,A,2037.7569,N,08704.0845,W,0.0000,0.000,231207,,*37 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,2.4,1.3,2.0*34 +{"class":"TPV","tag":"0x0106","time":1198451487.999,"ept":0.005,"lat":20.629281663,"lon":-87.068075323,"alt":75.741,"epx":2.375,"epy":4.455,"epv":11.234,"track":0.0000,"speed":0.000,"climb":0.000,"eps":8.91,"mode":3} +$GPGSV,2,1,08,15,67,141,31,02,21,089,32,30,21,234,50,05,18,217,39*72 +$GPGSV,2,2,08,12,16,201,41,18,25,255,41,135,33,251,45,06,54,308,25*41 +{"class":"SKY","tag":"0x0130","xdop":0.63,"ydop":1.19,"vdop":1.95,"tdop":1.29,"hdop":1.35,"gdop":2.70,"pdop":2.37,"satellites":[{"PRN":15,"el":67,"az":141,"ss":31,"used":true},{"PRN":2,"el":21,"az":89,"ss":32,"used":true},{"PRN":30,"el":21,"az":234,"ss":50,"used":true},{"PRN":5,"el":18,"az":217,"ss":39,"used":true},{"PRN":12,"el":16,"az":201,"ss":41,"used":true},{"PRN":18,"el":25,"az":255,"ss":41,"used":true},{"PRN":135,"el":33,"az":251,"ss":45,"used":true},{"PRN":6,"el":54,"az":308,"ss":25,"used":false}]} +$GPGGA,231128,2037.7569,N,08704.0845,W,2,07,1.35,75.73,M,-13.865,M,,*43 +$GPRMC,231128,A,2037.7569,N,08704.0845,W,0.0000,0.000,231207,,*38 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,2.4,1.3,2.0*34 +{"class":"TPV","tag":"0x0106","time":1198451488.999,"ept":0.005,"lat":20.629281494,"lon":-87.068075323,"alt":75.734,"epx":2.375,"epy":4.455,"epv":11.234,"track":0.0000,"speed":0.000,"climb":0.000,"eps":8.91,"mode":3} +$GPGSV,2,1,08,15,67,141,30,02,21,089,31,30,21,234,50,05,18,217,39*70 +$GPGSV,2,2,08,12,16,201,41,18,25,255,40,135,33,251,44,06,54,308,25*41 +{"class":"SKY","tag":"0x0130","xdop":0.63,"ydop":1.19,"vdop":1.95,"tdop":1.29,"hdop":1.35,"gdop":2.70,"pdop":2.37,"satellites":[{"PRN":15,"el":67,"az":141,"ss":30,"used":true},{"PRN":2,"el":21,"az":89,"ss":31,"used":true},{"PRN":30,"el":21,"az":234,"ss":50,"used":true},{"PRN":5,"el":18,"az":217,"ss":39,"used":true},{"PRN":12,"el":16,"az":201,"ss":41,"used":true},{"PRN":18,"el":25,"az":255,"ss":40,"used":true},{"PRN":135,"el":33,"az":251,"ss":44,"used":true},{"PRN":6,"el":54,"az":308,"ss":25,"used":false}]} +$GPGGA,231129,2037.7569,N,08704.0845,W,2,07,1.35,75.72,M,-13.865,M,,*43 +$GPRMC,231129,A,2037.7569,N,08704.0845,W,0.0000,0.000,231207,,*39 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,2.4,1.3,2.0*34 +{"class":"TPV","tag":"0x0106","time":1198451489.999,"ept":0.005,"lat":20.629281440,"lon":-87.068075223,"alt":75.722,"epx":2.375,"epy":4.455,"epv":11.234,"track":0.0000,"speed":0.000,"climb":0.000,"eps":8.91,"mode":3} +$GPGSV,2,1,08,15,67,141,29,02,21,089,30,30,21,234,50,05,18,217,39*79 +$GPGSV,2,2,08,12,16,201,42,18,25,255,40,135,33,251,44,06,54,308,25*42 +{"class":"SKY","tag":"0x0130","xdop":0.63,"ydop":1.19,"vdop":1.95,"tdop":1.29,"hdop":1.35,"gdop":2.70,"pdop":2.37,"satellites":[{"PRN":15,"el":67,"az":141,"ss":29,"used":true},{"PRN":2,"el":21,"az":89,"ss":30,"used":true},{"PRN":30,"el":21,"az":234,"ss":50,"used":true},{"PRN":5,"el":18,"az":217,"ss":39,"used":true},{"PRN":12,"el":16,"az":201,"ss":42,"used":true},{"PRN":18,"el":25,"az":255,"ss":40,"used":true},{"PRN":135,"el":33,"az":251,"ss":44,"used":true},{"PRN":6,"el":54,"az":308,"ss":25,"used":false}]} +$GPGGA,231130,2037.7569,N,08704.0845,W,2,07,1.35,75.72,M,-13.865,M,,*4B +$GPRMC,231130,A,2037.7569,N,08704.0845,W,0.0000,0.000,231207,,*31 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,2.4,1.3,2.0*34 +{"class":"TPV","tag":"0x0106","time":1198451490.999,"ept":0.005,"lat":20.629281354,"lon":-87.068075127,"alt":75.719,"epx":2.375,"epy":4.455,"epv":11.234,"track":0.0000,"speed":0.000,"climb":0.000,"eps":8.91,"mode":3} +$GPGSV,2,1,08,15,67,141,29,02,21,089,29,30,21,234,50,05,18,217,39*71 +$GPGSV,2,2,08,12,16,201,42,18,25,255,39,135,33,251,44,06,54,308,25*4C +{"class":"SKY","tag":"0x0130","xdop":0.63,"ydop":1.19,"vdop":1.95,"tdop":1.29,"hdop":1.35,"gdop":2.70,"pdop":2.37,"satellites":[{"PRN":15,"el":67,"az":141,"ss":29,"used":true},{"PRN":2,"el":21,"az":89,"ss":29,"used":true},{"PRN":30,"el":21,"az":234,"ss":50,"used":true},{"PRN":5,"el":18,"az":217,"ss":39,"used":true},{"PRN":12,"el":16,"az":201,"ss":42,"used":true},{"PRN":18,"el":25,"az":255,"ss":39,"used":true},{"PRN":135,"el":33,"az":251,"ss":44,"used":true},{"PRN":6,"el":54,"az":308,"ss":25,"used":false}]} +$GPGGA,231131,2037.7569,N,08704.0845,W,2,07,1.35,75.72,M,-13.865,M,,*4A +$GPRMC,231131,A,2037.7569,N,08704.0845,W,0.0000,0.000,231207,,*30 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,2.4,1.3,2.0*34 +{"class":"TPV","tag":"0x0106","time":1198451491.999,"ept":0.005,"lat":20.629281269,"lon":-87.068075127,"alt":75.715,"epx":2.375,"epy":4.455,"epv":11.234,"track":0.0000,"speed":0.000,"climb":0.000,"eps":8.91,"mode":3} +$GPGSV,2,1,08,15,67,141,28,02,21,089,29,30,21,234,50,05,18,217,39*70 +$GPGSV,2,2,08,12,16,201,42,18,25,255,39,135,33,251,45,06,54,308,25*4D +{"class":"SKY","tag":"0x0130","xdop":0.63,"ydop":1.19,"vdop":1.95,"tdop":1.29,"hdop":1.35,"gdop":2.70,"pdop":2.37,"satellites":[{"PRN":15,"el":67,"az":141,"ss":28,"used":true},{"PRN":2,"el":21,"az":89,"ss":29,"used":true},{"PRN":30,"el":21,"az":234,"ss":50,"used":true},{"PRN":5,"el":18,"az":217,"ss":39,"used":true},{"PRN":12,"el":16,"az":201,"ss":42,"used":true},{"PRN":18,"el":25,"az":255,"ss":39,"used":true},{"PRN":135,"el":33,"az":251,"ss":45,"used":true},{"PRN":6,"el":54,"az":308,"ss":25,"used":false}]} +$GPGGA,231132,2037.7569,N,08704.0845,W,2,07,1.35,75.70,M,-13.865,M,,*4B +$GPRMC,231132,A,2037.7569,N,08704.0845,W,0.0000,0.000,231207,,*33 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,2.4,1.3,2.0*34 +{"class":"TPV","tag":"0x0106","time":1198451492.999,"ept":0.005,"lat":20.629281215,"lon":-87.068075026,"alt":75.703,"epx":2.375,"epy":4.455,"epv":11.234,"track":0.0000,"speed":0.000,"climb":0.000,"eps":8.91,"mode":3} +$GPGSV,2,1,08,15,67,141,27,02,21,089,28,30,21,234,50,05,18,217,39*7E +$GPGSV,2,2,08,12,16,201,42,18,25,255,39,135,33,251,44,06,54,308,26*4F +{"class":"SKY","tag":"0x0130","xdop":0.63,"ydop":1.19,"vdop":1.95,"tdop":1.29,"hdop":1.35,"gdop":2.70,"pdop":2.37,"satellites":[{"PRN":15,"el":67,"az":141,"ss":27,"used":true},{"PRN":2,"el":21,"az":89,"ss":28,"used":true},{"PRN":30,"el":21,"az":234,"ss":50,"used":true},{"PRN":5,"el":18,"az":217,"ss":39,"used":true},{"PRN":12,"el":16,"az":201,"ss":42,"used":true},{"PRN":18,"el":25,"az":255,"ss":39,"used":true},{"PRN":135,"el":33,"az":251,"ss":44,"used":true},{"PRN":6,"el":54,"az":308,"ss":26,"used":false}]} diff --git a/test/daemon/uBlox-lea-4h.log b/test/daemon/uBlox-lea-4h.log new file mode 100644 index 0000000..9c65f2c --- /dev/null +++ b/test/daemon/uBlox-lea-4h.log @@ -0,0 +1,380 @@ +# Name: uBlox LEA-4H module +# Chipset: ANTARIS +# Description: uBlox LEA-4H module +# Submitted-by: "Dave Hylands" dhylands@gmail.com +# Date: 10 Aug 2006 +# Location: Surrey, British Columbia, Canada, 49.126356N 122.710015W +# +# This file is Copyright (c) 2010 by the GPSD project +# BSD terms apply: see the file COPYING in the distribution root for details. +# +$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,01,02,,,34*7D +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,030743.57,V,,,,,,,,,,N*7C +$GPVTG,,,,,,,,,N*30 +$GPGGA,030743.57,,,,,0,00,99.99,,,,,,*67 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,01,02,,,34*7D +$GPGLL,,,,,030743.57,V,N*4B +$GPZDA,030743.57,,,,00,00*67 +$GPRMC,030744.57,V,,,,,,,,,,N*7B +$GPVTG,,,,,,,,,N*30 +$GPGGA,030744.57,,,,,0,00,99.99,,,,,,*60 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,01,02,,,34*7D +$GPGLL,,,,,030744.57,V,N*4C +$GPZDA,030744.57,,,,00,00*60 +$GPRMC,030806.00,V,,,,,,,,,,N*70 +$GPVTG,,,,,,,,,N*30 +$GPGGA,030806.00,,,,,0,00,99.99,,,,,,*6B +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,02,04,,,48,02,,,33*71 +$GPGLL,,,,,030806.00,V,N*47 +$GPZDA,030806.00,,,,00,00*6B +$GPRMC,030807.00,V,,,,,,,100806,,,N*7E +$GPVTG,,,,,,,,,N*30 +$GPGGA,030807.00,,,,,0,00,99.99,,,,,,*6A +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,02,04,,,47,02,,,33*7E +$GPGLL,,,,,030807.00,V,N*46 +$GPZDA,030807.00,10,08,2006,00,00*67 +$GPRMC,030851.00,V,,,,,,,100806,,,N*7D +$GPVTG,,,,,,,,,N*30 +$GPGGA,030851.00,,,,,0,03,9.93,,,,,,*59 +$GPGSA,A,1,28,04,02,,,,,,,,,,9.98,9.93,1.00*06 +$GPGSV,1,1,03,28,28,095,33,04,30,150,46,02,07,178,32*4D +$GPGLL,,,,,030851.00,V,N*45 +$GPZDA,030851.00,10,08,2006,00,00*64 +$GPRMC,030852.00,V,,,,,,,100806,,,N*7E +$GPVTG,,,,,,,,,N*30 +$GPGGA,030852.00,,,,,0,03,9.93,,,,,,*5A +$GPGSA,A,1,28,04,02,,,,,,,,,,9.98,9.93,1.00*06 +$GPGSV,1,1,03,28,28,095,33,04,30,150,45,02,07,178,33*4F +$GPGLL,,,,,030852.00,V,N*46 +$GPZDA,030852.00,10,08,2006,00,00*67 +$GPRMC,030853.00,V,,,,,,,100806,,,N*7F +$GPVTG,,,,,,,,,N*30 +$GPGGA,030853.00,,,,,0,03,9.94,,,,,,*5C +$GPGSA,A,1,28,04,02,,,,,,,,,,9.99,9.94,1.00*00 +$GPGSV,1,1,03,28,28,095,33,04,30,150,45,02,07,178,32*4E +$GPGLL,,,,,030853.00,V,N*47 +$GPZDA,030853.00,10,08,2006,00,00*66 +$GPRMC,030857.00,V,,,,,,,100806,,,N*7B +$GPVTG,,,,,,,,,N*30 +$GPGGA,030857.00,,,,,0,03,9.96,,,,,,*5A +$GPGSA,A,1,28,04,02,,,,,,,,,,10.01,9.96,1.00*3B +$GPGSV,1,1,03,28,28,095,33,04,30,150,45,02,07,178,32*4E +$GPGLL,,,,,030857.00,V,N*43 +$GPZDA,030857.00,10,08,2006,00,00*62 +$GPRMC,030858.00,A,4907.85331,N,12243.19743,W,1.049,323.14,100806,,,A*76 +$GPVTG,323.14,T,,M,1.049,N,1.943,K,A*39 +$GPGGA,030858.00,4907.85331,N,12243.19743,W,1,03,9.97,516.7,M,-16.7,M,,*6C +$GPGSA,A,2,28,04,02,,,,,,,,,,10.02,9.97,1.00*3A +$GPGSV,1,1,03,28,28,095,33,04,30,150,45,02,07,178,31*4D +$GPGLL,4907.85331,N,12243.19743,W,030858.00,A,A*75 +$GPZDA,030858.00,10,08,2006,00,00*6D +$GPRMC,030859.00,A,4907.85396,N,12243.19848,W,1.321,323.21,100806,,,A*75 +$GPVTG,323.21,T,,M,1.321,N,2.448,K,A*37 +$GPGGA,030859.00,4907.85396,N,12243.19848,W,1,03,9.97,516.7,M,-16.7,M,,*64 +$GPGSA,A,2,28,04,02,,,,,,,,,,10.02,9.97,1.00*3A +$GPGSV,1,1,03,28,28,095,32,04,30,150,46,02,07,178,32*4C +$GPGLL,4907.85396,N,12243.19848,W,030859.00,A,A*7D +$GPZDA,030859.00,10,08,2006,00,00*6C +$GPRMC,030900.00,A,4907.85424,N,12243.19882,W,1.324,323.26,100806,,,A*72 +$GPVTG,323.26,T,,M,1.324,N,2.454,K,A*38 +$GPGGA,030900.00,4907.85424,N,12243.19882,W,1,03,9.98,516.7,M,-16.7,M,,*6E +$GPGSA,A,2,28,04,02,,,,,,,,,,10.03,9.98,1.00*34 +$GPGSV,1,1,03,28,28,095,33,04,30,150,46,02,07,178,32*4D +$GPGLL,4907.85424,N,12243.19882,W,030900.00,A,A*78 +$GPZDA,030900.00,10,08,2006,00,00*61 +$GPRMC,030901.00,A,4907.85444,N,12243.19906,W,1.458,323.25,100806,,,A*77 +$GPVTG,323.25,T,,M,1.458,N,2.702,K,A*37 +$GPGGA,030901.00,4907.85444,N,12243.19906,W,1,03,9.99,516.7,M,-16.7,M,,*65 +$GPGSA,A,2,28,04,02,,,,,,,,,,10.04,9.99,1.00*32 +$GPGSV,1,1,03,28,28,095,32,04,30,150,45,02,07,178,32*4F +$GPGLL,4907.85444,N,12243.19906,W,030901.00,A,A*72 +$GPZDA,030901.00,10,08,2006,00,00*60 +$GPRMC,031007.00,V,,,,,,,100806,,,N*77 +$GPVTG,,,,,,,,,N*30 +$GPGGA,031007.00,,,,,0,05,2.22,,,,,,*54 +$GPGSA,A,1,28,17,09,04,02,,,,,,,,4.62,2.22,4.05*00 +$GPGSV,2,1,06,28,28,095,26,17,64,064,27,09,55,289,37,04,31,150,43*7C +$GPGSV,2,2,06,02,07,178,32,24,40,121,35*73 +$GPGLL,,,,,031007.00,V,N*4F +$GPZDA,031007.00,10,08,2006,00,00*6E +$GPRMC,031008.00,A,4907.58133,N,12242.60088,W,2.550,220.86,100806,,,A*72 +$GPVTG,220.86,T,,M,2.550,N,4.724,K,A*34 +$GPGGA,031008.00,4907.58133,N,12242.60088,W,1,05,2.15,70.7,M,-16.7,M,,*5D +$GPGSA,A,3,28,17,09,04,02,,,,,,,,4.07,2.15,3.45*06 +$GPGSV,2,1,06,28,28,095,26,17,64,064,27,09,55,289,36,04,31,150,43*7D +$GPGSV,2,2,06,02,07,178,32,24,40,121,35*73 +$GPGLL,4907.58133,N,12242.60088,W,031008.00,A,A*76 +$GPZDA,031008.00,10,08,2006,00,00*61 +$GPRMC,031009.00,A,4907.58122,N,12242.60101,W,0.138,220.93,100806,,,A*7F +$GPVTG,220.93,T,,M,0.138,N,0.255,K,A*3F +$GPGGA,031009.00,4907.58122,N,12242.60101,W,1,05,2.15,70.1,M,-16.7,M,,*5A +$GPGSA,A,3,28,17,09,04,02,,,,,,,,4.06,2.15,3.45*07 +$GPGSV,2,1,06,28,28,095,25,17,64,064,27,09,55,289,36,04,31,150,43*7E +$GPGSV,2,2,06,02,07,178,32,24,40,121,35*73 +$GPGLL,4907.58122,N,12242.60101,W,031009.00,A,A*77 +$GPZDA,031009.00,10,08,2006,00,00*60 +$GPRMC,031516.00,A,4907.56801,N,12242.61073,W,0.084,39.14,100806,,,A*44 +$GPVTG,39.14,T,,M,0.084,N,0.155,K,A*0F +$GPGGA,031516.00,4907.56801,N,12242.61073,W,1,09,1.13,99.1,M,-16.7,M,,*5C +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,33,24,42,118,35,51,32,160,46,26,11,222,28*7C +$GPGSV,3,3,12,48,33,194,42,29,07,218,23,35,31,205,42,05,22,288,30*7B +$GPGLL,4907.56801,N,12242.61073,W,031516.00,A,A*7F +$GPZDA,031516.00,10,08,2006,00,00*6B +$GPRMC,031517.00,A,4907.56809,N,12242.61069,W,0.084,39.37,100806,,,A*47 +$GPVTG,39.37,T,,M,0.084,N,0.156,K,A*0D +$GPGGA,031517.00,4907.56809,N,12242.61069,W,1,09,1.13,98.8,M,-16.7,M,,*56 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,26,17,62,063,35,09,56,285,30,04,33,148,43*76 +$GPGSV,3,2,12,02,09,178,33,24,42,118,35,51,32,160,45,26,11,222,28*7F +$GPGSV,3,3,12,48,33,194,42,29,07,218,23,35,31,205,41,05,22,288,30*78 +$GPGLL,4907.56809,N,12242.61069,W,031517.00,A,A*7D +$GPZDA,031517.00,10,08,2006,00,00*6A +$GPRMC,031518.00,A,4907.56818,N,12242.61064,W,0.084,39.58,100806,,,A*4C +$GPVTG,39.58,T,,M,0.084,N,0.155,K,A*07 +$GPGGA,031518.00,4907.56818,N,12242.61064,W,1,09,1.13,98.5,M,-16.7,M,,*59 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,4,1,13,28,25,097,26,17,62,063,35,09,56,285,29,04,33,148,43*78 +$GPGSV,4,2,13,02,09,178,33,24,42,118,35,51,32,160,46,47,11,246,*75 +$GPGSV,4,3,13,26,11,222,28,48,33,194,41,29,07,218,23,35,31,205,41*75 +$GPGSV,4,4,13,05,22,288,30*4F +$GPGLL,4907.56818,N,12242.61064,W,031518.00,A,A*7F +$GPZDA,031518.00,10,08,2006,00,00*65 +$GPRMC,031519.00,A,4907.56826,N,12242.61066,W,0.083,40.03,100806,,,A*45 +$GPVTG,40.03,T,,M,0.083,N,0.153,K,A*06 +$GPGGA,031519.00,4907.56826,N,12242.61066,W,1,09,1.13,98.2,M,-16.7,M,,*50 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,4,1,13,28,25,097,26,17,62,063,35,09,56,285,29,04,33,148,43*78 +$GPGSV,4,2,13,02,09,178,33,24,42,118,35,51,32,160,46,47,11,246,*75 +$GPGSV,4,3,13,26,11,222,28,48,33,194,42,29,07,218,23,35,31,205,42*75 +$GPGSV,4,4,13,05,22,288,31*4E +$GPGLL,4907.56826,N,12242.61066,W,031519.00,A,A*71 +$GPZDA,031519.00,10,08,2006,00,00*64 +$GPRMC,031520.00,A,4907.56836,N,12242.61071,W,0.072,39.24,100806,,,A*4D +$GPVTG,39.24,T,,M,0.072,N,0.134,K,A*02 +$GPGGA,031520.00,4907.56836,N,12242.61071,W,1,09,1.13,98.0,M,-16.7,M,,*5F +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,4,1,13,28,25,097,26,17,62,063,35,09,56,285,30,04,33,148,43*70 +$GPGSV,4,2,13,02,09,178,33,24,42,118,35,51,32,160,45,47,11,246,*76 +$GPGSV,4,3,13,26,11,222,28,48,33,194,42,29,07,218,23,35,31,205,41*76 +$GPGSV,4,4,13,05,22,288,31*4E +$GPGLL,4907.56836,N,12242.61071,W,031520.00,A,A*7C +$GPZDA,031520.00,10,08,2006,00,00*6E +$GPRMC,031521.00,A,4907.56847,N,12242.61076,W,0.087,39.82,100806,,,A*4B +$GPVTG,39.82,T,,M,0.087,N,0.162,K,A*07 +$GPGGA,031521.00,4907.56847,N,12242.61076,W,1,09,1.13,97.7,M,-16.7,M,,*57 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,4,1,13,28,25,097,27,17,62,063,35,09,56,285,29,04,33,148,43*79 +$GPGSV,4,2,13,02,09,178,33,24,42,118,35,51,32,160,45,47,11,246,*76 +$GPGSV,4,3,13,26,11,222,28,48,33,194,42,29,07,218,23,35,31,205,41*76 +$GPGSV,4,4,13,05,22,288,31*4E +$GPGLL,4907.56847,N,12242.61076,W,031521.00,A,A*7C +$GPZDA,031521.00,10,08,2006,00,00*6F +$GPRMC,031522.00,A,4907.56858,N,12242.61089,W,0.073,38.91,100806,,,A*4E +$GPVTG,38.91,T,,M,0.073,N,0.136,K,A*0E +$GPGGA,031522.00,4907.56858,N,12242.61089,W,1,09,1.13,97.4,M,-16.7,M,,*59 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,4,1,13,28,25,097,27,17,62,063,35,09,56,285,29,04,33,148,43*79 +$GPGSV,4,2,13,02,09,178,33,24,42,118,35,51,32,160,45,47,11,246,*76 +$GPGSV,4,3,13,26,11,222,28,48,33,194,43,29,07,218,22,35,31,205,41*76 +$GPGSV,4,4,13,05,22,288,32*4D +$GPGLL,4907.56858,N,12242.61089,W,031522.00,A,A*71 +$GPZDA,031522.00,10,08,2006,00,00*6C +$GPRMC,031523.00,A,4907.56865,N,12242.61104,W,0.103,40.01,100806,,,A*45 +$GPVTG,40.01,T,,M,0.103,N,0.191,K,A*03 +$GPGGA,031523.00,4907.56865,N,12242.61104,W,1,09,1.13,97.3,M,-16.7,M,,*55 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,27,17,62,063,34,09,56,285,30,04,33,148,43*76 +$GPGSV,3,2,12,02,09,178,34,24,42,118,36,51,32,160,46,26,11,222,28*78 +$GPGSV,3,3,12,48,33,194,43,29,07,218,21,35,31,205,42,05,22,288,32*7A +$GPGLL,4907.56865,N,12242.61104,W,031523.00,A,A*7A +$GPZDA,031523.00,10,08,2006,00,00*6D +$GPRMC,031524.00,A,4907.56869,N,12242.61118,W,0.079,38.21,100806,,,A*42 +$GPVTG,38.21,T,,M,0.079,N,0.147,K,A*09 +$GPGGA,031524.00,4907.56869,N,12242.61118,W,1,09,1.13,97.1,M,-16.7,M,,*51 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,33,24,42,118,36,51,32,160,46,26,11,222,27*70 +$GPGSV,3,3,12,48,33,194,42,29,07,218,20,35,31,205,42,05,22,288,32*7A +$GPGLL,4907.56869,N,12242.61118,W,031524.00,A,A*7C +$GPZDA,031524.00,10,08,2006,00,00*6A +$GPRMC,031525.00,A,4907.56874,N,12242.61134,W,0.055,37.49,100806,,,A*4E +$GPVTG,37.49,T,,M,0.055,N,0.101,K,A*04 +$GPGGA,031525.00,4907.56874,N,12242.61134,W,1,09,1.13,97.0,M,-16.7,M,,*53 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,33,24,42,118,37,51,32,160,46,26,11,222,27*71 +$GPGSV,3,3,12,48,33,194,42,29,07,218,17,35,31,205,41,05,22,288,32*7D +$GPGLL,4907.56874,N,12242.61134,W,031525.00,A,A*7F +$GPZDA,031525.00,10,08,2006,00,00*6B +$GPRMC,031526.00,A,4907.56881,N,12242.61152,W,0.074,36.23,100806,,,A*49 +$GPVTG,36.23,T,,M,0.074,N,0.138,K,A*00 +$GPGGA,031526.00,4907.56881,N,12242.61152,W,1,09,1.13,96.9,M,-16.7,M,,*52 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,34,24,42,118,37,51,32,160,45,26,11,222,26*74 +$GPGSV,3,3,12,48,33,194,42,29,07,218,18,35,31,205,41,05,22,288,32*72 +$GPGLL,4907.56881,N,12242.61152,W,031526.00,A,A*76 +$GPZDA,031526.00,10,08,2006,00,00*68 +$GPRMC,031527.00,A,4907.56880,N,12242.61161,W,0.064,36.09,100806,,,A*40 +$GPVTG,36.09,T,,M,0.064,N,0.118,K,A*0B +$GPGGA,031527.00,4907.56880,N,12242.61161,W,1,09,1.77,96.9,M,-16.7,M,,*50 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.72,1.77,3.27*01 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,34,24,42,118,38,51,32,160,45,26,11,222,26*7B +$GPGSV,3,3,12,48,33,194,42,29,07,218,18,35,31,205,41,05,22,288,32*72 +$GPGLL,4907.56880,N,12242.61161,W,031527.00,A,A*76 +$GPZDA,031527.00,10,08,2006,00,00*69 +$GPRMC,031528.00,A,4907.56877,N,12242.61171,W,0.063,35.66,100806,,,A*4B +$GPVTG,35.66,T,,M,0.063,N,0.117,K,A*09 +$GPGGA,031528.00,4907.56877,N,12242.61171,W,1,09,1.77,97.0,M,-16.7,M,,*5E +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.72,1.77,3.27*01 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,34,24,42,118,38,51,32,160,45,26,11,222,26*7B +$GPGSV,3,3,12,48,33,194,43,29,07,218,19,35,31,205,41,05,22,288,31*71 +$GPGLL,4907.56877,N,12242.61171,W,031528.00,A,A*70 +$GPZDA,031528.00,10,08,2006,00,00*66 +$GPRMC,031529.00,A,4907.56879,N,12242.61185,W,0.066,35.64,100806,,,A*48 +$GPVTG,35.64,T,,M,0.066,N,0.122,K,A*08 +$GPGGA,031529.00,4907.56879,N,12242.61185,W,1,09,1.78,96.9,M,-16.7,M,,*5D +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.72,1.78,3.27*0E +$GPGSV,3,1,12,28,25,097,27,17,62,063,34,09,56,285,30,04,33,148,43*76 +$GPGSV,3,2,12,02,09,178,33,24,42,118,38,51,32,160,45,26,11,222,26*7C +$GPGSV,3,3,12,48,33,194,42,29,07,218,19,35,31,205,41,05,22,288,31*70 +$GPGLL,4907.56879,N,12242.61185,W,031529.00,A,A*74 +$GPZDA,031529.00,10,08,2006,00,00*67 +$GPRMC,031530.00,A,4907.56881,N,12242.61206,W,0.074,36.71,100806,,,A*4B +$GPVTG,36.71,T,,M,0.074,N,0.138,K,A*07 +$GPGGA,031530.00,4907.56881,N,12242.61206,W,1,09,1.78,97.0,M,-16.7,M,,*52 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.72,1.78,3.27*0E +$GPGSV,3,1,12,28,25,097,27,17,62,063,34,09,56,285,30,04,33,148,43*76 +$GPGSV,3,2,12,02,09,178,34,24,42,118,39,51,32,160,45,26,11,222,26*7A +$GPGSV,3,3,12,48,33,194,43,29,07,218,20,35,31,205,41,05,22,288,32*78 +$GPGLL,4907.56881,N,12242.61206,W,031530.00,A,A*73 +$GPZDA,031530.00,10,08,2006,00,00*6F +$GPRMC,031531.00,A,4907.56898,N,12242.61248,W,0.082,35.14,100806,,,A*41 +$GPVTG,35.14,T,,M,0.082,N,0.152,K,A*02 +$GPGGA,031531.00,4907.56898,N,12242.61248,W,1,09,1.78,96.7,M,-16.7,M,,*57 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.73,1.78,3.28*00 +$GPGSV,3,1,12,28,25,097,27,17,62,063,34,09,56,285,31,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,33,24,42,118,39,51,32,160,45,26,11,222,26*7D +$GPGSV,3,3,12,48,33,194,42,29,07,218,20,35,31,205,41,05,22,288,33*78 +$GPGLL,4907.56898,N,12242.61248,W,031531.00,A,A*70 +$GPZDA,031531.00,10,08,2006,00,00*6E +$GPRMC,031532.00,A,4907.56911,N,12242.61285,W,0.067,33.19,100806,,,A*43 +$GPVTG,33.19,T,,M,0.067,N,0.125,K,A*02 +$GPGGA,031532.00,4907.56911,N,12242.61285,W,1,09,1.78,96.5,M,-16.7,M,,*57 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.73,1.78,3.28*00 +$GPGSV,3,1,12,28,25,097,27,17,62,063,34,09,56,285,31,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,33,24,42,118,39,51,32,160,45,26,11,222,25*7E +$GPGSV,3,3,12,48,33,194,42,29,07,218,20,35,31,205,41,05,22,288,33*78 +$GPGLL,4907.56911,N,12242.61285,W,031532.00,A,A*72 +$GPZDA,031532.00,10,08,2006,00,00*6D +$GPRMC,031533.00,A,4907.56922,N,12242.61319,W,0.086,31.63,100806,,,A*46 +$GPVTG,31.63,T,,M,0.086,N,0.160,K,A*03 +$GPGGA,031533.00,4907.56922,N,12242.61319,W,1,09,1.78,96.3,M,-16.7,M,,*54 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.73,1.78,3.28*00 +$GPGSV,4,1,13,28,25,097,27,17,62,063,34,09,56,285,31,04,33,148,43*71 +$GPGSV,4,2,13,02,09,178,34,24,42,118,39,51,32,160,45,11,04,035,*7C +$GPGSV,4,3,13,26,11,222,25,48,33,194,43,29,07,218,21,35,31,205,41*78 +$GPGSV,4,4,13,05,22,288,32*4D +$GPGLL,4907.56922,N,12242.61319,W,031533.00,A,A*77 +$GPZDA,031533.00,10,08,2006,00,00*6C +$GPRMC,031534.00,A,4907.56930,N,12242.61352,W,0.067,31.80,100806,,,A*4F +$GPVTG,31.80,T,,M,0.067,N,0.123,K,A*06 +$GPGGA,031534.00,4907.56930,N,12242.61352,W,1,09,1.78,96.3,M,-16.7,M,,*5F +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.73,1.78,3.28*00 +$GPGSV,4,1,13,28,25,097,27,17,62,063,33,09,56,285,32,04,33,148,43*75 +$GPGSV,4,2,13,02,09,178,34,24,42,118,39,51,32,160,45,11,04,035,*7C +$GPGSV,4,3,13,26,11,222,25,48,33,194,43,29,07,218,21,35,31,205,41*78 +$GPGSV,4,4,13,05,22,288,32*4D +$GPGLL,4907.56930,N,12242.61352,W,031534.00,A,A*7C +$GPZDA,031534.00,10,08,2006,00,00*6B +$GPRMC,031657.00,A,4907.57916,N,12242.60479,W,4.536,74.34,100806,,,A*48 +$GPVTG,74.34,T,,M,4.536,N,8.406,K,A*07 +$GPGGA,031657.00,4907.57916,N,12242.60479,W,1,04,3.84,72.8,M,-16.7,M,,*5E +$GPGSA,A,3,17,09,04,02,,,,,,,,,7.53,3.84,6.48*0F +$GPGSV,3,1,11,28,25,097,,17,61,062,17,09,57,284,17,04,34,148,16*71 +$GPGSV,3,2,11,02,10,178,14,24,42,117,16,05,23,288,,29,06,218,13*72 +$GPGSV,3,3,11,26,10,222,,11,03,035,12,51,32,160,*4A +$GPGLL,4907.57916,N,12242.60479,W,031657.00,A,A*70 +$GPZDA,031657.00,10,08,2006,00,00*6D +$GPRMC,031658.00,A,4907.58097,N,12242.60538,W,6.135,347.99,100806,,,A*7D +$GPVTG,347.99,T,,M,6.135,N,11.369,K,A*00 +$GPGGA,031658.00,4907.58097,N,12242.60538,W,1,03,3.46,72.8,M,-16.7,M,,*53 +$GPGSA,A,2,09,04,24,,,,,,,,,,3.61,3.46,1.00*0C +$GPGSV,3,1,11,28,25,097,,17,61,062,17,09,57,284,17,04,34,148,15*72 +$GPGSV,3,2,11,02,10,178,12,24,42,117,20,05,23,288,,29,06,218,13*71 +$GPGSV,3,3,11,26,10,222,,11,03,035,11,51,32,160,*49 +$GPGLL,4907.58097,N,12242.60538,W,031658.00,A,A*74 +$GPZDA,031658.00,10,08,2006,00,00*62 +$GPRMC,031659.00,V,,,,,,,100806,,,N*7A +$GPVTG,,,,,,,,,N*30 +$GPGGA,031659.00,,,,,0,00,99.99,,,,,,*6E +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,3,1,10,28,25,097,,17,61,062,19,09,57,284,21,04,34,148,13*7E +$GPGSV,3,2,10,02,10,178,16,24,42,117,20,05,23,288,,29,06,218,17*70 +$GPGSV,3,3,10,26,10,222,,11,03,035,17*7C +$GPGLL,,,,,031659.00,V,N*42 +$GPZDA,031659.00,10,08,2006,00,00*63 +$GPRMC,031700.00,V,,,,,,,100806,,,N*77 +$GPVTG,,,,,,,,,N*30 +$GPGGA,031700.00,,,,,0,00,99.99,,,,,,*63 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,3,1,10,28,25,097,,17,61,062,19,09,57,284,19,04,34,148,13*75 +$GPGSV,3,2,10,02,10,178,16,24,42,117,20,05,23,288,,29,06,218,17*70 +$GPGSV,3,3,10,26,10,222,,11,03,035,14*7F +$GPGLL,,,,,031700.00,V,N*4F +$GPZDA,031700.00,10,08,2006,00,00*6E +$GPRMC,031701.00,V,,,,,,,100806,,,N*76 +$GPVTG,,,,,,,,,N*30 +$GPGGA,031701.00,,,,,0,00,99.99,,,,,,*62 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,3,1,10,28,25,097,,17,61,062,16,09,57,284,14,04,34,148,15*71 +$GPGSV,3,2,10,02,10,178,16,24,42,117,20,05,23,288,,29,06,218,16*71 +$GPGSV,3,3,10,26,10,222,,11,03,035,13*78 +$GPGLL,,,,,031701.00,V,N*4E +$GPZDA,031701.00,10,08,2006,00,00*6F +$GPRMC,032534.00,V,,,,,,,100806,,,N*71 +$GPVTG,,,,,,,,,N*30 +$GPGGA,032534.00,,,,,0,00,99.99,,,,,,*65 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,3,1,11,05,26,289,,17,58,061,,09,58,277,,24,44,112,*77 +$GPGSV,3,2,11,02,14,177,,04,37,146,,28,22,100,,26,07,220,*75 +$GPGSV,3,3,11,29,03,216,,11,01,034,,20,05,064,15*43 +$GPGLL,,,,,032534.00,V,N*49 +$GPZDA,032534.00,10,08,2006,00,00*68 +$GPRMC,032535.00,V,,,,,,,100806,,,N*70 +$GPVTG,,,,,,,,,N*30 +$GPGGA,032535.00,,,,,0,00,99.99,,,,,,*64 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,3,1,11,05,26,289,,17,58,061,,09,58,277,,24,44,112,*77 +$GPGSV,3,2,11,02,14,177,,04,37,146,,28,22,100,,26,07,220,*75 +$GPGSV,3,3,11,29,03,216,,11,01,034,,20,05,064,*47 +$GPGLL,,,,,032535.00,V,N*48 +$GPZDA,032535.00,10,08,2006,00,00*69 diff --git a/test/daemon/uBlox-lea-4h.log.chk b/test/daemon/uBlox-lea-4h.log.chk new file mode 100644 index 0000000..d58eb9c --- /dev/null +++ b/test/daemon/uBlox-lea-4h.log.chk @@ -0,0 +1,449 @@ +$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,01,02,,,34*7D +$GPGLL,,,,,,V,N*64 +$GPZDA,,,,,00,00*48 +$GPRMC,030743.57,V,,,,,,,,,,N*7C +$GPVTG,,,,,,,,,N*30 +$GPGGA,030743.57,,,,,0,00,99.99,,,,,,*67 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,01,02,,,34*7D +$GPGLL,,,,,030743.57,V,N*4B +$GPZDA,030743.57,,,,00,00*67 +$GPRMC,030744.57,V,,,,,,,,,,N*7B +$GPVTG,,,,,,,,,N*30 +$GPGGA,030744.57,,,,,0,00,99.99,,,,,,*60 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +{"class":"TPV","tag":"GSA","mode":1} +$GPGSV,1,1,01,02,,,34*7D +$GPGLL,,,,,030744.57,V,N*4C +$GPZDA,030744.57,,,,00,00*60 +$GPRMC,030806.00,V,,,,,,,,,,N*70 +$GPVTG,,,,,,,,,N*30 +$GPGGA,030806.00,,,,,0,00,99.99,,,,,,*6B +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,02,04,,,48,02,,,33*71 +$GPGLL,,,,,030806.00,V,N*47 +$GPZDA,030806.00,,,,00,00*6B +$GPRMC,030807.00,V,,,,,,,100806,,,N*7E +$GPVTG,,,,,,,,,N*30 +$GPGGA,030807.00,,,,,0,00,99.99,,,,,,*6A +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,1,1,02,04,,,47,02,,,33*7E +$GPGLL,,,,,030807.00,V,N*46 +$GPZDA,030807.00,10,08,2006,00,00*67 +$GPRMC,030851.00,V,,,,,,,100806,,,N*7D +$GPVTG,,,,,,,,,N*30 +$GPGGA,030851.00,,,,,0,03,9.93,,,,,,*59 +$GPGSA,A,1,28,04,02,,,,,,,,,,9.98,9.93,1.00*06 +$GPGSV,1,1,03,28,28,095,33,04,30,150,46,02,07,178,32*4D +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":28,"az":95,"ss":33,"used":true},{"PRN":4,"el":30,"az":150,"ss":46,"used":true},{"PRN":2,"el":7,"az":178,"ss":32,"used":true}]} +$GPGLL,,,,,030851.00,V,N*45 +{"class":"TPV","tag":"GLL","time":1155179331.000,"ept":0.005,"mode":0} +$GPZDA,030851.00,10,08,2006,00,00*64 +$GPRMC,030852.00,V,,,,,,,100806,,,N*7E +$GPVTG,,,,,,,,,N*30 +$GPGGA,030852.00,,,,,0,03,9.93,,,,,,*5A +$GPGSA,A,1,28,04,02,,,,,,,,,,9.98,9.93,1.00*06 +$GPGSV,1,1,03,28,28,095,33,04,30,150,45,02,07,178,33*4F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":28,"az":95,"ss":33,"used":true},{"PRN":4,"el":30,"az":150,"ss":45,"used":true},{"PRN":2,"el":7,"az":178,"ss":33,"used":true}]} +$GPGLL,,,,,030852.00,V,N*46 +{"class":"TPV","tag":"GLL","time":1155179332.000,"ept":0.005,"mode":0} +$GPZDA,030852.00,10,08,2006,00,00*67 +$GPRMC,030853.00,V,,,,,,,100806,,,N*7F +$GPVTG,,,,,,,,,N*30 +$GPGGA,030853.00,,,,,0,03,9.94,,,,,,*5C +$GPGSA,A,1,28,04,02,,,,,,,,,,9.99,9.94,1.00*00 +$GPGSV,1,1,03,28,28,095,33,04,30,150,45,02,07,178,32*4E +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":28,"az":95,"ss":33,"used":true},{"PRN":4,"el":30,"az":150,"ss":45,"used":true},{"PRN":2,"el":7,"az":178,"ss":32,"used":true}]} +$GPGLL,,,,,030853.00,V,N*47 +{"class":"TPV","tag":"GLL","time":1155179333.000,"ept":0.005,"mode":0} +$GPZDA,030853.00,10,08,2006,00,00*66 +$GPRMC,030857.00,V,,,,,,,100806,,,N*7B +$GPVTG,,,,,,,,,N*30 +$GPGGA,030857.00,,,,,0,03,9.96,,,,,,*5A +$GPGSA,A,1,28,04,02,,,,,,,,,,10.01,9.96,1.00*3B +$GPGSV,1,1,03,28,28,095,33,04,30,150,45,02,07,178,32*4E +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":28,"az":95,"ss":33,"used":true},{"PRN":4,"el":30,"az":150,"ss":45,"used":true},{"PRN":2,"el":7,"az":178,"ss":32,"used":true}]} +$GPGLL,,,,,030857.00,V,N*43 +{"class":"TPV","tag":"GLL","time":1155179337.000,"ept":0.005,"mode":0} +$GPZDA,030857.00,10,08,2006,00,00*62 +$GPRMC,030858.00,A,4907.85331,N,12243.19743,W,1.049,323.14,100806,,,A*76 +$GPVTG,323.14,T,,M,1.049,N,1.943,K,A*39 +$GPGGA,030858.00,4907.85331,N,12243.19743,W,1,03,9.97,516.7,M,-16.7,M,,*6C +$GPGSA,A,2,28,04,02,,,,,,,,,,10.02,9.97,1.00*3A +$GPGSV,1,1,03,28,28,095,33,04,30,150,45,02,07,178,31*4D +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":28,"az":95,"ss":33,"used":true},{"PRN":4,"el":30,"az":150,"ss":45,"used":true},{"PRN":2,"el":7,"az":178,"ss":31,"used":true}]} +$GPGLL,4907.85331,N,12243.19743,W,030858.00,A,A*75 +{"class":"TPV","tag":"GLL","time":1155179338.000,"ept":0.005,"lat":49.130888500,"lon":-122.719957167,"alt":516.700,"epv":23.000,"track":323.1400,"speed":0.540,"climb":0.000,"mode":3} +$GPZDA,030858.00,10,08,2006,00,00*6D +$GPRMC,030859.00,A,4907.85396,N,12243.19848,W,1.321,323.21,100806,,,A*75 +$GPVTG,323.21,T,,M,1.321,N,2.448,K,A*37 +$GPGGA,030859.00,4907.85396,N,12243.19848,W,1,03,9.97,516.7,M,-16.7,M,,*64 +$GPGSA,A,2,28,04,02,,,,,,,,,,10.02,9.97,1.00*3A +$GPGSV,1,1,03,28,28,095,32,04,30,150,46,02,07,178,32*4C +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":28,"az":95,"ss":32,"used":true},{"PRN":4,"el":30,"az":150,"ss":46,"used":true},{"PRN":2,"el":7,"az":178,"ss":32,"used":true}]} +$GPGLL,4907.85396,N,12243.19848,W,030859.00,A,A*7D +{"class":"TPV","tag":"GLL","time":1155179339.000,"ept":0.005,"lat":49.130899333,"lon":-122.719974667,"alt":516.700,"epv":23.000,"track":323.2100,"speed":0.680,"climb":0.000,"mode":3} +$GPZDA,030859.00,10,08,2006,00,00*6C +$GPRMC,030900.00,A,4907.85424,N,12243.19882,W,1.324,323.26,100806,,,A*72 +$GPVTG,323.26,T,,M,1.324,N,2.454,K,A*38 +$GPGGA,030900.00,4907.85424,N,12243.19882,W,1,03,9.98,516.7,M,-16.7,M,,*6E +$GPGSA,A,2,28,04,02,,,,,,,,,,10.03,9.98,1.00*34 +$GPGSV,1,1,03,28,28,095,33,04,30,150,46,02,07,178,32*4D +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":28,"az":95,"ss":33,"used":true},{"PRN":4,"el":30,"az":150,"ss":46,"used":true},{"PRN":2,"el":7,"az":178,"ss":32,"used":true}]} +$GPGLL,4907.85424,N,12243.19882,W,030900.00,A,A*78 +{"class":"TPV","tag":"GLL","time":1155179340.000,"ept":0.005,"lat":49.130904000,"lon":-122.719980333,"alt":516.700,"epv":23.000,"track":323.2600,"speed":0.681,"climb":0.000,"mode":3} +$GPZDA,030900.00,10,08,2006,00,00*61 +$GPRMC,030901.00,A,4907.85444,N,12243.19906,W,1.458,323.25,100806,,,A*77 +$GPVTG,323.25,T,,M,1.458,N,2.702,K,A*37 +$GPGGA,030901.00,4907.85444,N,12243.19906,W,1,03,9.99,516.7,M,-16.7,M,,*65 +$GPGSA,A,2,28,04,02,,,,,,,,,,10.04,9.99,1.00*32 +$GPGSV,1,1,03,28,28,095,32,04,30,150,45,02,07,178,32*4F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":28,"az":95,"ss":32,"used":true},{"PRN":4,"el":30,"az":150,"ss":45,"used":true},{"PRN":2,"el":7,"az":178,"ss":32,"used":true}]} +$GPGLL,4907.85444,N,12243.19906,W,030901.00,A,A*72 +{"class":"TPV","tag":"GLL","time":1155179341.000,"ept":0.005,"lat":49.130907333,"lon":-122.719984333,"alt":516.700,"epv":23.000,"track":323.2500,"speed":0.750,"climb":0.000,"mode":3} +$GPZDA,030901.00,10,08,2006,00,00*60 +$GPRMC,031007.00,V,,,,,,,100806,,,N*77 +$GPVTG,,,,,,,,,N*30 +$GPGGA,031007.00,,,,,0,05,2.22,,,,,,*54 +$GPGSA,A,1,28,17,09,04,02,,,,,,,,4.62,2.22,4.05*00 +$GPGSV,2,1,06,28,28,095,26,17,64,064,27,09,55,289,37,04,31,150,43*7C +$GPGSV,2,2,06,02,07,178,32,24,40,121,35*73 +{"class":"SKY","tag":"GSV","xdop":0.98,"ydop":1.92,"vdop":3.45,"tdop":2.55,"hdop":2.15,"gdop":4.80,"pdop":4.07,"satellites":[{"PRN":28,"el":28,"az":95,"ss":26,"used":true},{"PRN":17,"el":64,"az":64,"ss":27,"used":true},{"PRN":9,"el":55,"az":289,"ss":37,"used":true},{"PRN":4,"el":31,"az":150,"ss":43,"used":true},{"PRN":2,"el":7,"az":178,"ss":32,"used":true},{"PRN":24,"el":40,"az":121,"ss":35,"used":false}]} +$GPGLL,,,,,031007.00,V,N*4F +{"class":"TPV","tag":"GLL","time":1155179407.000,"ept":0.005,"mode":0} +$GPZDA,031007.00,10,08,2006,00,00*6E +$GPRMC,031008.00,A,4907.58133,N,12242.60088,W,2.550,220.86,100806,,,A*72 +$GPVTG,220.86,T,,M,2.550,N,4.724,K,A*34 +$GPGGA,031008.00,4907.58133,N,12242.60088,W,1,05,2.15,70.7,M,-16.7,M,,*5D +$GPGSA,A,3,28,17,09,04,02,,,,,,,,4.07,2.15,3.45*06 +$GPGSV,2,1,06,28,28,095,26,17,64,064,27,09,55,289,36,04,31,150,43*7D +$GPGSV,2,2,06,02,07,178,32,24,40,121,35*73 +{"class":"SKY","tag":"GSV","xdop":0.98,"ydop":1.92,"vdop":3.45,"tdop":2.55,"hdop":2.15,"gdop":4.80,"pdop":4.07,"satellites":[{"PRN":28,"el":28,"az":95,"ss":26,"used":true},{"PRN":17,"el":64,"az":64,"ss":27,"used":true},{"PRN":9,"el":55,"az":289,"ss":36,"used":true},{"PRN":4,"el":31,"az":150,"ss":43,"used":true},{"PRN":2,"el":7,"az":178,"ss":32,"used":true},{"PRN":24,"el":40,"az":121,"ss":35,"used":false}]} +$GPGLL,4907.58133,N,12242.60088,W,031008.00,A,A*76 +{"class":"TPV","tag":"GLL","time":1155179408.000,"ept":0.005,"lat":49.126355500,"lon":-122.710014667,"alt":70.700,"epx":14.642,"epy":28.806,"epv":79.346,"track":220.8600,"speed":1.312,"climb":0.000,"eps":0.86,"mode":3} +$GPZDA,031008.00,10,08,2006,00,00*61 +$GPRMC,031009.00,A,4907.58122,N,12242.60101,W,0.138,220.93,100806,,,A*7F +$GPVTG,220.93,T,,M,0.138,N,0.255,K,A*3F +$GPGGA,031009.00,4907.58122,N,12242.60101,W,1,05,2.15,70.1,M,-16.7,M,,*5A +$GPGSA,A,3,28,17,09,04,02,,,,,,,,4.06,2.15,3.45*07 +$GPGSV,2,1,06,28,28,095,25,17,64,064,27,09,55,289,36,04,31,150,43*7E +$GPGSV,2,2,06,02,07,178,32,24,40,121,35*73 +{"class":"SKY","tag":"GSV","xdop":0.98,"ydop":1.92,"vdop":3.45,"tdop":2.55,"hdop":2.15,"gdop":4.80,"pdop":4.07,"satellites":[{"PRN":28,"el":28,"az":95,"ss":25,"used":true},{"PRN":17,"el":64,"az":64,"ss":27,"used":true},{"PRN":9,"el":55,"az":289,"ss":36,"used":true},{"PRN":4,"el":31,"az":150,"ss":43,"used":true},{"PRN":2,"el":7,"az":178,"ss":32,"used":true},{"PRN":24,"el":40,"az":121,"ss":35,"used":false}]} +$GPGLL,4907.58122,N,12242.60101,W,031009.00,A,A*77 +{"class":"TPV","tag":"GLL","time":1155179409.000,"ept":0.005,"lat":49.126353667,"lon":-122.710016833,"alt":70.100,"epx":14.642,"epy":28.806,"epv":79.346,"track":220.9300,"speed":0.071,"climb":0.000,"eps":57.61,"mode":3} +$GPZDA,031009.00,10,08,2006,00,00*60 +$GPRMC,031516.00,A,4907.56801,N,12242.61073,W,0.084,39.14,100806,,,A*44 +$GPVTG,39.14,T,,M,0.084,N,0.155,K,A*0F +$GPGGA,031516.00,4907.56801,N,12242.61073,W,1,09,1.13,99.1,M,-16.7,M,,*5C +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,33,24,42,118,35,51,32,160,46,26,11,222,28*7C +$GPGSV,3,3,12,48,33,194,42,29,07,218,23,35,31,205,42,05,22,288,30*7B +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":26,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":35,"used":true},{"PRN":51,"el":32,"az":160,"ss":46,"used":false},{"PRN":26,"el":11,"az":222,"ss":28,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":23,"used":false},{"PRN":35,"el":31,"az":205,"ss":42,"used":true},{"PRN":5,"el":22,"az":288,"ss":30,"used":true}]} +$GPGLL,4907.56801,N,12242.61073,W,031516.00,A,A*7F +{"class":"TPV","tag":"GLL","time":1155179716.000,"ept":0.005,"lat":49.126133500,"lon":-122.710178833,"alt":99.100,"epx":14.642,"epy":28.806,"epv":79.346,"track":39.1400,"speed":0.043,"climb":0.000,"eps":0.19,"mode":3} +$GPZDA,031516.00,10,08,2006,00,00*6B +$GPRMC,031517.00,A,4907.56809,N,12242.61069,W,0.084,39.37,100806,,,A*47 +$GPVTG,39.37,T,,M,0.084,N,0.156,K,A*0D +$GPGGA,031517.00,4907.56809,N,12242.61069,W,1,09,1.13,98.8,M,-16.7,M,,*56 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,26,17,62,063,35,09,56,285,30,04,33,148,43*76 +$GPGSV,3,2,12,02,09,178,33,24,42,118,35,51,32,160,45,26,11,222,28*7F +$GPGSV,3,3,12,48,33,194,42,29,07,218,23,35,31,205,41,05,22,288,30*78 +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":26,"used":true},{"PRN":17,"el":62,"az":63,"ss":35,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":35,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":26,"el":11,"az":222,"ss":28,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":23,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":30,"used":true}]} +$GPGLL,4907.56809,N,12242.61069,W,031517.00,A,A*7D +{"class":"TPV","tag":"GLL","time":1155179717.000,"ept":0.005,"lat":49.126134833,"lon":-122.710178167,"alt":98.800,"epx":10.180,"epy":18.094,"epv":49.642,"track":39.3700,"speed":0.043,"climb":0.000,"eps":46.90,"mode":3} +$GPZDA,031517.00,10,08,2006,00,00*6A +$GPRMC,031518.00,A,4907.56818,N,12242.61064,W,0.084,39.58,100806,,,A*4C +$GPVTG,39.58,T,,M,0.084,N,0.155,K,A*07 +$GPGGA,031518.00,4907.56818,N,12242.61064,W,1,09,1.13,98.5,M,-16.7,M,,*59 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,4,1,13,28,25,097,26,17,62,063,35,09,56,285,29,04,33,148,43*78 +$GPGSV,4,2,13,02,09,178,33,24,42,118,35,51,32,160,46,47,11,246,*75 +$GPGSV,4,3,13,26,11,222,28,48,33,194,41,29,07,218,23,35,31,205,41*75 +$GPGSV,4,4,13,05,22,288,30*4F +{"class":"SKY","tag":"GSV","xdop":0.63,"ydop":1.24,"vdop":2.09,"tdop":1.47,"hdop":1.39,"gdop":2.91,"pdop":2.51,"satellites":[{"PRN":28,"el":25,"az":97,"ss":26,"used":true},{"PRN":17,"el":62,"az":63,"ss":35,"used":true},{"PRN":9,"el":56,"az":285,"ss":29,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":35,"used":true},{"PRN":51,"el":32,"az":160,"ss":46,"used":false},{"PRN":47,"el":11,"az":246,"ss":0,"used":false},{"PRN":26,"el":11,"az":222,"ss":28,"used":true},{"PRN":48,"el":33,"az":194,"ss":41,"used":false},{"PRN":29,"el":7,"az":218,"ss":23,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":30,"used":true}]} +$GPGLL,4907.56818,N,12242.61064,W,031518.00,A,A*7F +{"class":"TPV","tag":"GLL","time":1155179718.000,"ept":0.005,"lat":49.126136333,"lon":-122.710177333,"alt":98.500,"epx":10.180,"epy":18.094,"epv":49.642,"track":39.5800,"speed":0.043,"climb":0.000,"eps":36.19,"mode":3} +$GPZDA,031518.00,10,08,2006,00,00*65 +$GPRMC,031519.00,A,4907.56826,N,12242.61066,W,0.083,40.03,100806,,,A*45 +$GPVTG,40.03,T,,M,0.083,N,0.153,K,A*06 +$GPGGA,031519.00,4907.56826,N,12242.61066,W,1,09,1.13,98.2,M,-16.7,M,,*50 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,4,1,13,28,25,097,26,17,62,063,35,09,56,285,29,04,33,148,43*78 +$GPGSV,4,2,13,02,09,178,33,24,42,118,35,51,32,160,46,47,11,246,*75 +$GPGSV,4,3,13,26,11,222,28,48,33,194,42,29,07,218,23,35,31,205,42*75 +$GPGSV,4,4,13,05,22,288,31*4E +{"class":"SKY","tag":"GSV","xdop":0.63,"ydop":1.24,"vdop":2.09,"tdop":1.47,"hdop":1.39,"gdop":2.91,"pdop":2.51,"satellites":[{"PRN":28,"el":25,"az":97,"ss":26,"used":true},{"PRN":17,"el":62,"az":63,"ss":35,"used":true},{"PRN":9,"el":56,"az":285,"ss":29,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":35,"used":true},{"PRN":51,"el":32,"az":160,"ss":46,"used":false},{"PRN":47,"el":11,"az":246,"ss":0,"used":false},{"PRN":26,"el":11,"az":222,"ss":28,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":23,"used":false},{"PRN":35,"el":31,"az":205,"ss":42,"used":true},{"PRN":5,"el":22,"az":288,"ss":31,"used":true}]} +$GPGLL,4907.56826,N,12242.61066,W,031519.00,A,A*71 +{"class":"TPV","tag":"GLL","time":1155179719.000,"ept":0.005,"lat":49.126137667,"lon":-122.710177667,"alt":98.200,"epx":9.479,"epy":18.633,"epv":48.035,"track":40.0300,"speed":0.043,"climb":0.000,"eps":36.73,"mode":3} +$GPZDA,031519.00,10,08,2006,00,00*64 +$GPRMC,031520.00,A,4907.56836,N,12242.61071,W,0.072,39.24,100806,,,A*4D +$GPVTG,39.24,T,,M,0.072,N,0.134,K,A*02 +$GPGGA,031520.00,4907.56836,N,12242.61071,W,1,09,1.13,98.0,M,-16.7,M,,*5F +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,4,1,13,28,25,097,26,17,62,063,35,09,56,285,30,04,33,148,43*70 +$GPGSV,4,2,13,02,09,178,33,24,42,118,35,51,32,160,45,47,11,246,*76 +$GPGSV,4,3,13,26,11,222,28,48,33,194,42,29,07,218,23,35,31,205,41*76 +$GPGSV,4,4,13,05,22,288,31*4E +{"class":"SKY","tag":"GSV","xdop":0.63,"ydop":1.24,"vdop":2.09,"tdop":1.47,"hdop":1.39,"gdop":2.91,"pdop":2.51,"satellites":[{"PRN":28,"el":25,"az":97,"ss":26,"used":true},{"PRN":17,"el":62,"az":63,"ss":35,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":35,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":47,"el":11,"az":246,"ss":0,"used":false},{"PRN":26,"el":11,"az":222,"ss":28,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":23,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":31,"used":true}]} +$GPGLL,4907.56836,N,12242.61071,W,031520.00,A,A*7C +{"class":"TPV","tag":"GLL","time":1155179720.000,"ept":0.005,"lat":49.126139333,"lon":-122.710178500,"alt":98.000,"epx":9.479,"epy":18.633,"epv":48.035,"track":39.2400,"speed":0.037,"climb":0.000,"eps":37.27,"mode":3} +$GPZDA,031520.00,10,08,2006,00,00*6E +$GPRMC,031521.00,A,4907.56847,N,12242.61076,W,0.087,39.82,100806,,,A*4B +$GPVTG,39.82,T,,M,0.087,N,0.162,K,A*07 +$GPGGA,031521.00,4907.56847,N,12242.61076,W,1,09,1.13,97.7,M,-16.7,M,,*57 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,4,1,13,28,25,097,27,17,62,063,35,09,56,285,29,04,33,148,43*79 +$GPGSV,4,2,13,02,09,178,33,24,42,118,35,51,32,160,45,47,11,246,*76 +$GPGSV,4,3,13,26,11,222,28,48,33,194,42,29,07,218,23,35,31,205,41*76 +$GPGSV,4,4,13,05,22,288,31*4E +{"class":"SKY","tag":"GSV","xdop":0.63,"ydop":1.24,"vdop":2.09,"tdop":1.47,"hdop":1.39,"gdop":2.91,"pdop":2.51,"satellites":[{"PRN":28,"el":25,"az":97,"ss":27,"used":true},{"PRN":17,"el":62,"az":63,"ss":35,"used":true},{"PRN":9,"el":56,"az":285,"ss":29,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":35,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":47,"el":11,"az":246,"ss":0,"used":false},{"PRN":26,"el":11,"az":222,"ss":28,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":23,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":31,"used":true}]} +$GPGLL,4907.56847,N,12242.61076,W,031521.00,A,A*7C +{"class":"TPV","tag":"GLL","time":1155179721.000,"ept":0.005,"lat":49.126141167,"lon":-122.710179333,"alt":97.700,"epx":9.479,"epy":18.633,"epv":48.035,"track":39.8200,"speed":0.045,"climb":0.000,"eps":37.27,"mode":3} +$GPZDA,031521.00,10,08,2006,00,00*6F +$GPRMC,031522.00,A,4907.56858,N,12242.61089,W,0.073,38.91,100806,,,A*4E +$GPVTG,38.91,T,,M,0.073,N,0.136,K,A*0E +$GPGGA,031522.00,4907.56858,N,12242.61089,W,1,09,1.13,97.4,M,-16.7,M,,*59 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,4,1,13,28,25,097,27,17,62,063,35,09,56,285,29,04,33,148,43*79 +$GPGSV,4,2,13,02,09,178,33,24,42,118,35,51,32,160,45,47,11,246,*76 +$GPGSV,4,3,13,26,11,222,28,48,33,194,43,29,07,218,22,35,31,205,41*76 +$GPGSV,4,4,13,05,22,288,32*4D +{"class":"SKY","tag":"GSV","xdop":0.63,"ydop":1.24,"vdop":2.09,"tdop":1.47,"hdop":1.39,"gdop":2.91,"pdop":2.51,"satellites":[{"PRN":28,"el":25,"az":97,"ss":27,"used":true},{"PRN":17,"el":62,"az":63,"ss":35,"used":true},{"PRN":9,"el":56,"az":285,"ss":29,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":35,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":47,"el":11,"az":246,"ss":0,"used":false},{"PRN":26,"el":11,"az":222,"ss":28,"used":true},{"PRN":48,"el":33,"az":194,"ss":43,"used":false},{"PRN":29,"el":7,"az":218,"ss":22,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":32,"used":true}]} +$GPGLL,4907.56858,N,12242.61089,W,031522.00,A,A*71 +{"class":"TPV","tag":"GLL","time":1155179722.000,"ept":0.005,"lat":49.126143000,"lon":-122.710181500,"alt":97.400,"epx":9.479,"epy":18.633,"epv":48.035,"track":38.9100,"speed":0.038,"climb":0.000,"eps":37.27,"mode":3} +$GPZDA,031522.00,10,08,2006,00,00*6C +$GPRMC,031523.00,A,4907.56865,N,12242.61104,W,0.103,40.01,100806,,,A*45 +$GPVTG,40.01,T,,M,0.103,N,0.191,K,A*03 +$GPGGA,031523.00,4907.56865,N,12242.61104,W,1,09,1.13,97.3,M,-16.7,M,,*55 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,27,17,62,063,34,09,56,285,30,04,33,148,43*76 +$GPGSV,3,2,12,02,09,178,34,24,42,118,36,51,32,160,46,26,11,222,28*78 +$GPGSV,3,3,12,48,33,194,43,29,07,218,21,35,31,205,42,05,22,288,32*7A +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":27,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":34,"used":true},{"PRN":24,"el":42,"az":118,"ss":36,"used":true},{"PRN":51,"el":32,"az":160,"ss":46,"used":false},{"PRN":26,"el":11,"az":222,"ss":28,"used":true},{"PRN":48,"el":33,"az":194,"ss":43,"used":false},{"PRN":29,"el":7,"az":218,"ss":21,"used":false},{"PRN":35,"el":31,"az":205,"ss":42,"used":true},{"PRN":5,"el":22,"az":288,"ss":32,"used":true}]} +$GPGLL,4907.56865,N,12242.61104,W,031523.00,A,A*7A +{"class":"TPV","tag":"GLL","time":1155179723.000,"ept":0.005,"lat":49.126144167,"lon":-122.710184000,"alt":97.300,"epx":9.479,"epy":18.633,"epv":48.035,"track":40.0100,"speed":0.053,"climb":0.000,"eps":37.27,"mode":3} +$GPZDA,031523.00,10,08,2006,00,00*6D +$GPRMC,031524.00,A,4907.56869,N,12242.61118,W,0.079,38.21,100806,,,A*42 +$GPVTG,38.21,T,,M,0.079,N,0.147,K,A*09 +$GPGGA,031524.00,4907.56869,N,12242.61118,W,1,09,1.13,97.1,M,-16.7,M,,*51 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,33,24,42,118,36,51,32,160,46,26,11,222,27*70 +$GPGSV,3,3,12,48,33,194,42,29,07,218,20,35,31,205,42,05,22,288,32*7A +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":26,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":36,"used":true},{"PRN":51,"el":32,"az":160,"ss":46,"used":false},{"PRN":26,"el":11,"az":222,"ss":27,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":20,"used":false},{"PRN":35,"el":31,"az":205,"ss":42,"used":true},{"PRN":5,"el":22,"az":288,"ss":32,"used":true}]} +$GPGLL,4907.56869,N,12242.61118,W,031524.00,A,A*7C +{"class":"TPV","tag":"GLL","time":1155179724.000,"ept":0.005,"lat":49.126144833,"lon":-122.710186333,"alt":97.100,"epx":10.180,"epy":18.094,"epv":49.642,"track":38.2100,"speed":0.041,"climb":0.000,"eps":36.73,"mode":3} +$GPZDA,031524.00,10,08,2006,00,00*6A +$GPRMC,031525.00,A,4907.56874,N,12242.61134,W,0.055,37.49,100806,,,A*4E +$GPVTG,37.49,T,,M,0.055,N,0.101,K,A*04 +$GPGGA,031525.00,4907.56874,N,12242.61134,W,1,09,1.13,97.0,M,-16.7,M,,*53 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,33,24,42,118,37,51,32,160,46,26,11,222,27*71 +$GPGSV,3,3,12,48,33,194,42,29,07,218,17,35,31,205,41,05,22,288,32*7D +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":26,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":37,"used":true},{"PRN":51,"el":32,"az":160,"ss":46,"used":false},{"PRN":26,"el":11,"az":222,"ss":27,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":17,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":32,"used":true}]} +$GPGLL,4907.56874,N,12242.61134,W,031525.00,A,A*7F +{"class":"TPV","tag":"GLL","time":1155179725.000,"ept":0.005,"lat":49.126145667,"lon":-122.710189000,"alt":97.000,"epx":10.180,"epy":18.094,"epv":49.642,"track":37.4900,"speed":0.028,"climb":0.000,"eps":36.19,"mode":3} +$GPZDA,031525.00,10,08,2006,00,00*6B +$GPRMC,031526.00,A,4907.56881,N,12242.61152,W,0.074,36.23,100806,,,A*49 +$GPVTG,36.23,T,,M,0.074,N,0.138,K,A*00 +$GPGGA,031526.00,4907.56881,N,12242.61152,W,1,09,1.13,96.9,M,-16.7,M,,*52 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,2.20,1.13,1.89*03 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,34,24,42,118,37,51,32,160,45,26,11,222,26*74 +$GPGSV,3,3,12,48,33,194,42,29,07,218,18,35,31,205,41,05,22,288,32*72 +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":26,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":34,"used":true},{"PRN":24,"el":42,"az":118,"ss":37,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":26,"el":11,"az":222,"ss":26,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":18,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":32,"used":true}]} +$GPGLL,4907.56881,N,12242.61152,W,031526.00,A,A*76 +{"class":"TPV","tag":"GLL","time":1155179726.000,"ept":0.005,"lat":49.126146833,"lon":-122.710192000,"alt":96.900,"epx":10.180,"epy":18.094,"epv":49.642,"track":36.2300,"speed":0.038,"climb":0.000,"eps":36.19,"mode":3} +$GPZDA,031526.00,10,08,2006,00,00*68 +$GPRMC,031527.00,A,4907.56880,N,12242.61161,W,0.064,36.09,100806,,,A*40 +$GPVTG,36.09,T,,M,0.064,N,0.118,K,A*0B +$GPGGA,031527.00,4907.56880,N,12242.61161,W,1,09,1.77,96.9,M,-16.7,M,,*50 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.72,1.77,3.27*01 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,34,24,42,118,38,51,32,160,45,26,11,222,26*7B +$GPGSV,3,3,12,48,33,194,42,29,07,218,18,35,31,205,41,05,22,288,32*72 +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":26,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":34,"used":true},{"PRN":24,"el":42,"az":118,"ss":38,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":26,"el":11,"az":222,"ss":26,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":18,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":32,"used":true}]} +$GPGLL,4907.56880,N,12242.61161,W,031527.00,A,A*76 +{"class":"TPV","tag":"GLL","time":1155179727.000,"ept":0.005,"lat":49.126146667,"lon":-122.710193500,"alt":96.900,"epx":10.180,"epy":18.094,"epv":49.642,"track":36.0900,"speed":0.033,"climb":0.000,"eps":36.19,"mode":3} +$GPZDA,031527.00,10,08,2006,00,00*69 +$GPRMC,031528.00,A,4907.56877,N,12242.61171,W,0.063,35.66,100806,,,A*4B +$GPVTG,35.66,T,,M,0.063,N,0.117,K,A*09 +$GPGGA,031528.00,4907.56877,N,12242.61171,W,1,09,1.77,97.0,M,-16.7,M,,*5E +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.72,1.77,3.27*01 +$GPGSV,3,1,12,28,25,097,26,17,62,063,34,09,56,285,30,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,34,24,42,118,38,51,32,160,45,26,11,222,26*7B +$GPGSV,3,3,12,48,33,194,43,29,07,218,19,35,31,205,41,05,22,288,31*71 +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":26,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":34,"used":true},{"PRN":24,"el":42,"az":118,"ss":38,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":26,"el":11,"az":222,"ss":26,"used":true},{"PRN":48,"el":33,"az":194,"ss":43,"used":false},{"PRN":29,"el":7,"az":218,"ss":19,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":31,"used":true}]} +$GPGLL,4907.56877,N,12242.61171,W,031528.00,A,A*70 +{"class":"TPV","tag":"GLL","time":1155179728.000,"ept":0.005,"lat":49.126146167,"lon":-122.710195167,"alt":97.000,"epx":10.180,"epy":18.094,"epv":49.642,"track":35.6600,"speed":0.032,"climb":0.000,"eps":36.19,"mode":3} +$GPZDA,031528.00,10,08,2006,00,00*66 +$GPRMC,031529.00,A,4907.56879,N,12242.61185,W,0.066,35.64,100806,,,A*48 +$GPVTG,35.64,T,,M,0.066,N,0.122,K,A*08 +$GPGGA,031529.00,4907.56879,N,12242.61185,W,1,09,1.78,96.9,M,-16.7,M,,*5D +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.72,1.78,3.27*0E +$GPGSV,3,1,12,28,25,097,27,17,62,063,34,09,56,285,30,04,33,148,43*76 +$GPGSV,3,2,12,02,09,178,33,24,42,118,38,51,32,160,45,26,11,222,26*7C +$GPGSV,3,3,12,48,33,194,42,29,07,218,19,35,31,205,41,05,22,288,31*70 +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":27,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":38,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":26,"el":11,"az":222,"ss":26,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":19,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":31,"used":true}]} +$GPGLL,4907.56879,N,12242.61185,W,031529.00,A,A*74 +{"class":"TPV","tag":"GLL","time":1155179729.000,"ept":0.005,"lat":49.126146500,"lon":-122.710197500,"alt":96.900,"epx":10.180,"epy":18.094,"epv":49.642,"track":35.6400,"speed":0.034,"climb":0.000,"eps":36.19,"mode":3} +$GPZDA,031529.00,10,08,2006,00,00*67 +$GPRMC,031530.00,A,4907.56881,N,12242.61206,W,0.074,36.71,100806,,,A*4B +$GPVTG,36.71,T,,M,0.074,N,0.138,K,A*07 +$GPGGA,031530.00,4907.56881,N,12242.61206,W,1,09,1.78,97.0,M,-16.7,M,,*52 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.72,1.78,3.27*0E +$GPGSV,3,1,12,28,25,097,27,17,62,063,34,09,56,285,30,04,33,148,43*76 +$GPGSV,3,2,12,02,09,178,34,24,42,118,39,51,32,160,45,26,11,222,26*7A +$GPGSV,3,3,12,48,33,194,43,29,07,218,20,35,31,205,41,05,22,288,32*78 +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":27,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":30,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":34,"used":true},{"PRN":24,"el":42,"az":118,"ss":39,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":26,"el":11,"az":222,"ss":26,"used":true},{"PRN":48,"el":33,"az":194,"ss":43,"used":false},{"PRN":29,"el":7,"az":218,"ss":20,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":32,"used":true}]} +$GPGLL,4907.56881,N,12242.61206,W,031530.00,A,A*73 +{"class":"TPV","tag":"GLL","time":1155179730.000,"ept":0.005,"lat":49.126146833,"lon":-122.710201000,"alt":97.000,"epx":10.180,"epy":18.094,"epv":49.642,"track":36.7100,"speed":0.038,"climb":0.000,"eps":36.19,"mode":3} +$GPZDA,031530.00,10,08,2006,00,00*6F +$GPRMC,031531.00,A,4907.56898,N,12242.61248,W,0.082,35.14,100806,,,A*41 +$GPVTG,35.14,T,,M,0.082,N,0.152,K,A*02 +$GPGGA,031531.00,4907.56898,N,12242.61248,W,1,09,1.78,96.7,M,-16.7,M,,*57 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.73,1.78,3.28*00 +$GPGSV,3,1,12,28,25,097,27,17,62,063,34,09,56,285,31,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,33,24,42,118,39,51,32,160,45,26,11,222,26*7D +$GPGSV,3,3,12,48,33,194,42,29,07,218,20,35,31,205,41,05,22,288,33*78 +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":27,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":31,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":39,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":26,"el":11,"az":222,"ss":26,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":20,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":33,"used":true}]} +$GPGLL,4907.56898,N,12242.61248,W,031531.00,A,A*70 +{"class":"TPV","tag":"GLL","time":1155179731.000,"ept":0.005,"lat":49.126149667,"lon":-122.710208000,"alt":96.700,"epx":10.180,"epy":18.094,"epv":49.642,"track":35.1400,"speed":0.042,"climb":0.000,"eps":36.19,"mode":3} +$GPZDA,031531.00,10,08,2006,00,00*6E +$GPRMC,031532.00,A,4907.56911,N,12242.61285,W,0.067,33.19,100806,,,A*43 +$GPVTG,33.19,T,,M,0.067,N,0.125,K,A*02 +$GPGGA,031532.00,4907.56911,N,12242.61285,W,1,09,1.78,96.5,M,-16.7,M,,*57 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.73,1.78,3.28*00 +$GPGSV,3,1,12,28,25,097,27,17,62,063,34,09,56,285,31,04,33,148,43*77 +$GPGSV,3,2,12,02,09,178,33,24,42,118,39,51,32,160,45,26,11,222,25*7E +$GPGSV,3,3,12,48,33,194,42,29,07,218,20,35,31,205,41,05,22,288,33*78 +{"class":"SKY","tag":"GSV","xdop":0.68,"ydop":1.21,"vdop":2.16,"tdop":1.64,"hdop":1.38,"gdop":3.04,"pdop":2.56,"satellites":[{"PRN":28,"el":25,"az":97,"ss":27,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":31,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":33,"used":true},{"PRN":24,"el":42,"az":118,"ss":39,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":26,"el":11,"az":222,"ss":25,"used":true},{"PRN":48,"el":33,"az":194,"ss":42,"used":false},{"PRN":29,"el":7,"az":218,"ss":20,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":33,"used":true}]} +$GPGLL,4907.56911,N,12242.61285,W,031532.00,A,A*72 +{"class":"TPV","tag":"GLL","time":1155179732.000,"ept":0.005,"lat":49.126151833,"lon":-122.710214167,"alt":96.500,"epx":10.180,"epy":18.094,"epv":49.642,"track":33.1900,"speed":0.034,"climb":0.000,"eps":36.19,"mode":3} +$GPZDA,031532.00,10,08,2006,00,00*6D +$GPRMC,031533.00,A,4907.56922,N,12242.61319,W,0.086,31.63,100806,,,A*46 +$GPVTG,31.63,T,,M,0.086,N,0.160,K,A*03 +$GPGGA,031533.00,4907.56922,N,12242.61319,W,1,09,1.78,96.3,M,-16.7,M,,*54 +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.73,1.78,3.28*00 +$GPGSV,4,1,13,28,25,097,27,17,62,063,34,09,56,285,31,04,33,148,43*71 +$GPGSV,4,2,13,02,09,178,34,24,42,118,39,51,32,160,45,11,04,035,*7C +$GPGSV,4,3,13,26,11,222,25,48,33,194,43,29,07,218,21,35,31,205,41*78 +$GPGSV,4,4,13,05,22,288,32*4D +{"class":"SKY","tag":"GSV","xdop":0.69,"ydop":0.62,"vdop":1.22,"tdop":0.74,"hdop":0.93,"gdop":1.70,"pdop":1.53,"satellites":[{"PRN":28,"el":25,"az":97,"ss":27,"used":true},{"PRN":17,"el":62,"az":63,"ss":34,"used":true},{"PRN":9,"el":56,"az":285,"ss":31,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":34,"used":true},{"PRN":24,"el":42,"az":118,"ss":39,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":11,"el":4,"az":35,"ss":0,"used":false},{"PRN":26,"el":11,"az":222,"ss":25,"used":true},{"PRN":48,"el":33,"az":194,"ss":43,"used":false},{"PRN":29,"el":7,"az":218,"ss":21,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":32,"used":true}]} +$GPGLL,4907.56922,N,12242.61319,W,031533.00,A,A*77 +{"class":"TPV","tag":"GLL","time":1155179733.000,"ept":0.005,"lat":49.126153667,"lon":-122.710219833,"alt":96.300,"epx":10.180,"epy":18.094,"epv":49.642,"track":31.6300,"speed":0.044,"climb":0.000,"eps":36.19,"mode":3} +$GPZDA,031533.00,10,08,2006,00,00*6C +$GPRMC,031534.00,A,4907.56930,N,12242.61352,W,0.067,31.80,100806,,,A*4F +$GPVTG,31.80,T,,M,0.067,N,0.123,K,A*06 +$GPGGA,031534.00,4907.56930,N,12242.61352,W,1,09,1.78,96.3,M,-16.7,M,,*5F +$GPGSA,A,3,28,17,09,04,02,24,26,35,05,,,,3.73,1.78,3.28*00 +$GPGSV,4,1,13,28,25,097,27,17,62,063,33,09,56,285,32,04,33,148,43*75 +$GPGSV,4,2,13,02,09,178,34,24,42,118,39,51,32,160,45,11,04,035,*7C +$GPGSV,4,3,13,26,11,222,25,48,33,194,43,29,07,218,21,35,31,205,41*78 +$GPGSV,4,4,13,05,22,288,32*4D +{"class":"SKY","tag":"GSV","xdop":0.69,"ydop":0.62,"vdop":1.22,"tdop":0.74,"hdop":0.93,"gdop":1.70,"pdop":1.53,"satellites":[{"PRN":28,"el":25,"az":97,"ss":27,"used":true},{"PRN":17,"el":62,"az":63,"ss":33,"used":true},{"PRN":9,"el":56,"az":285,"ss":32,"used":true},{"PRN":4,"el":33,"az":148,"ss":43,"used":true},{"PRN":2,"el":9,"az":178,"ss":34,"used":true},{"PRN":24,"el":42,"az":118,"ss":39,"used":true},{"PRN":51,"el":32,"az":160,"ss":45,"used":false},{"PRN":11,"el":4,"az":35,"ss":0,"used":false},{"PRN":26,"el":11,"az":222,"ss":25,"used":true},{"PRN":48,"el":33,"az":194,"ss":43,"used":false},{"PRN":29,"el":7,"az":218,"ss":21,"used":false},{"PRN":35,"el":31,"az":205,"ss":41,"used":true},{"PRN":5,"el":22,"az":288,"ss":32,"used":true}]} +$GPGLL,4907.56930,N,12242.61352,W,031534.00,A,A*7C +{"class":"TPV","tag":"GLL","time":1155179734.000,"ept":0.005,"lat":49.126155000,"lon":-122.710225333,"alt":96.300,"epx":10.339,"epy":9.313,"epv":27.993,"track":31.8000,"speed":0.034,"climb":0.000,"eps":28.43,"mode":3} +$GPZDA,031534.00,10,08,2006,00,00*6B +$GPRMC,031657.00,A,4907.57916,N,12242.60479,W,4.536,74.34,100806,,,A*48 +$GPVTG,74.34,T,,M,4.536,N,8.406,K,A*07 +$GPGGA,031657.00,4907.57916,N,12242.60479,W,1,04,3.84,72.8,M,-16.7,M,,*5E +$GPGSA,A,3,17,09,04,02,,,,,,,,,7.53,3.84,6.48*0F +$GPGSV,3,1,11,28,25,097,,17,61,062,17,09,57,284,17,04,34,148,16*71 +$GPGSV,3,2,11,02,10,178,14,24,42,117,16,05,23,288,,29,06,218,13*72 +$GPGSV,3,3,11,26,10,222,,11,03,035,12,51,32,160,*4A +{"class":"SKY","tag":"GSV","xdop":1.40,"ydop":1.85,"vdop":4.72,"tdop":3.66,"hdop":2.32,"gdop":6.41,"pdop":5.26,"satellites":[{"PRN":28,"el":25,"az":97,"ss":0,"used":false},{"PRN":17,"el":61,"az":62,"ss":17,"used":true},{"PRN":9,"el":57,"az":284,"ss":17,"used":true},{"PRN":4,"el":34,"az":148,"ss":16,"used":true},{"PRN":2,"el":10,"az":178,"ss":14,"used":true},{"PRN":24,"el":42,"az":117,"ss":16,"used":false},{"PRN":5,"el":23,"az":288,"ss":0,"used":false},{"PRN":29,"el":6,"az":218,"ss":13,"used":false},{"PRN":26,"el":10,"az":222,"ss":0,"used":false},{"PRN":11,"el":3,"az":35,"ss":12,"used":false},{"PRN":51,"el":32,"az":160,"ss":0,"used":false}]} +$GPGLL,4907.57916,N,12242.60479,W,031657.00,A,A*70 +{"class":"TPV","tag":"GLL","time":1155179817.000,"ept":0.005,"lat":49.126319333,"lon":-122.710079833,"alt":72.800,"epx":10.339,"epy":9.313,"epv":27.993,"track":74.3400,"speed":2.334,"climb":0.000,"eps":0.25,"mode":3} +$GPZDA,031657.00,10,08,2006,00,00*6D +$GPRMC,031658.00,A,4907.58097,N,12242.60538,W,6.135,347.99,100806,,,A*7D +$GPVTG,347.99,T,,M,6.135,N,11.369,K,A*00 +$GPGGA,031658.00,4907.58097,N,12242.60538,W,1,03,3.46,72.8,M,-16.7,M,,*53 +$GPGSA,A,2,09,04,24,,,,,,,,,,3.61,3.46,1.00*0C +$GPGSV,3,1,11,28,25,097,,17,61,062,17,09,57,284,17,04,34,148,15*72 +$GPGSV,3,2,11,02,10,178,12,24,42,117,20,05,23,288,,29,06,218,13*71 +$GPGSV,3,3,11,26,10,222,,11,03,035,11,51,32,160,*49 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":25,"az":97,"ss":0,"used":false},{"PRN":17,"el":61,"az":62,"ss":17,"used":false},{"PRN":9,"el":57,"az":284,"ss":17,"used":true},{"PRN":4,"el":34,"az":148,"ss":15,"used":true},{"PRN":2,"el":10,"az":178,"ss":12,"used":false},{"PRN":24,"el":42,"az":117,"ss":20,"used":true},{"PRN":5,"el":23,"az":288,"ss":0,"used":false},{"PRN":29,"el":6,"az":218,"ss":13,"used":false},{"PRN":26,"el":10,"az":222,"ss":0,"used":false},{"PRN":11,"el":3,"az":35,"ss":11,"used":false},{"PRN":51,"el":32,"az":160,"ss":0,"used":false}]} +$GPGLL,4907.58097,N,12242.60538,W,031658.00,A,A*74 +{"class":"TPV","tag":"GLL","time":1155179818.000,"ept":0.005,"lat":49.126349500,"lon":-122.710089667,"alt":72.800,"epx":20.926,"epy":27.800,"epv":108.598,"track":347.9900,"speed":3.156,"climb":0.000,"eps":38.14,"mode":3} +$GPZDA,031658.00,10,08,2006,00,00*62 +$GPRMC,031659.00,V,,,,,,,100806,,,N*7A +$GPVTG,,,,,,,,,N*30 +$GPGGA,031659.00,,,,,0,00,99.99,,,,,,*6E +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,3,1,10,28,25,097,,17,61,062,19,09,57,284,21,04,34,148,13*7E +$GPGSV,3,2,10,02,10,178,16,24,42,117,20,05,23,288,,29,06,218,17*70 +$GPGSV,3,3,10,26,10,222,,11,03,035,17*7C +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":25,"az":97,"ss":0,"used":false},{"PRN":17,"el":61,"az":62,"ss":19,"used":false},{"PRN":9,"el":57,"az":284,"ss":21,"used":false},{"PRN":4,"el":34,"az":148,"ss":13,"used":false},{"PRN":2,"el":10,"az":178,"ss":16,"used":false},{"PRN":24,"el":42,"az":117,"ss":20,"used":false},{"PRN":5,"el":23,"az":288,"ss":0,"used":false},{"PRN":29,"el":6,"az":218,"ss":17,"used":false},{"PRN":26,"el":10,"az":222,"ss":0,"used":false},{"PRN":11,"el":3,"az":35,"ss":17,"used":false}]} +$GPGLL,,,,,031659.00,V,N*42 +{"class":"TPV","tag":"GLL","time":1155179819.000,"ept":0.005,"mode":0} +$GPZDA,031659.00,10,08,2006,00,00*63 +$GPRMC,031700.00,V,,,,,,,100806,,,N*77 +$GPVTG,,,,,,,,,N*30 +$GPGGA,031700.00,,,,,0,00,99.99,,,,,,*63 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,3,1,10,28,25,097,,17,61,062,19,09,57,284,19,04,34,148,13*75 +$GPGSV,3,2,10,02,10,178,16,24,42,117,20,05,23,288,,29,06,218,17*70 +$GPGSV,3,3,10,26,10,222,,11,03,035,14*7F +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":25,"az":97,"ss":0,"used":false},{"PRN":17,"el":61,"az":62,"ss":19,"used":false},{"PRN":9,"el":57,"az":284,"ss":19,"used":false},{"PRN":4,"el":34,"az":148,"ss":13,"used":false},{"PRN":2,"el":10,"az":178,"ss":16,"used":false},{"PRN":24,"el":42,"az":117,"ss":20,"used":false},{"PRN":5,"el":23,"az":288,"ss":0,"used":false},{"PRN":29,"el":6,"az":218,"ss":17,"used":false},{"PRN":26,"el":10,"az":222,"ss":0,"used":false},{"PRN":11,"el":3,"az":35,"ss":14,"used":false}]} +$GPGLL,,,,,031700.00,V,N*4F +{"class":"TPV","tag":"GLL","time":1155179820.000,"ept":0.005,"mode":0} +$GPZDA,031700.00,10,08,2006,00,00*6E +$GPRMC,031701.00,V,,,,,,,100806,,,N*76 +$GPVTG,,,,,,,,,N*30 +$GPGGA,031701.00,,,,,0,00,99.99,,,,,,*62 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,3,1,10,28,25,097,,17,61,062,16,09,57,284,14,04,34,148,15*71 +$GPGSV,3,2,10,02,10,178,16,24,42,117,20,05,23,288,,29,06,218,16*71 +$GPGSV,3,3,10,26,10,222,,11,03,035,13*78 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":28,"el":25,"az":97,"ss":0,"used":false},{"PRN":17,"el":61,"az":62,"ss":16,"used":false},{"PRN":9,"el":57,"az":284,"ss":14,"used":false},{"PRN":4,"el":34,"az":148,"ss":15,"used":false},{"PRN":2,"el":10,"az":178,"ss":16,"used":false},{"PRN":24,"el":42,"az":117,"ss":20,"used":false},{"PRN":5,"el":23,"az":288,"ss":0,"used":false},{"PRN":29,"el":6,"az":218,"ss":16,"used":false},{"PRN":26,"el":10,"az":222,"ss":0,"used":false},{"PRN":11,"el":3,"az":35,"ss":13,"used":false}]} +$GPGLL,,,,,031701.00,V,N*4E +{"class":"TPV","tag":"GLL","time":1155179821.000,"ept":0.005,"mode":0} +$GPZDA,031701.00,10,08,2006,00,00*6F +$GPRMC,032534.00,V,,,,,,,100806,,,N*71 +$GPVTG,,,,,,,,,N*30 +$GPGGA,032534.00,,,,,0,00,99.99,,,,,,*65 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,3,1,11,05,26,289,,17,58,061,,09,58,277,,24,44,112,*77 +$GPGSV,3,2,11,02,14,177,,04,37,146,,28,22,100,,26,07,220,*75 +$GPGSV,3,3,11,29,03,216,,11,01,034,,20,05,064,15*43 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":5,"el":26,"az":289,"ss":0,"used":false},{"PRN":17,"el":58,"az":61,"ss":0,"used":false},{"PRN":9,"el":58,"az":277,"ss":0,"used":false},{"PRN":24,"el":44,"az":112,"ss":0,"used":false},{"PRN":2,"el":14,"az":177,"ss":0,"used":false},{"PRN":4,"el":37,"az":146,"ss":0,"used":false},{"PRN":28,"el":22,"az":100,"ss":0,"used":false},{"PRN":26,"el":7,"az":220,"ss":0,"used":false},{"PRN":29,"el":3,"az":216,"ss":0,"used":false},{"PRN":11,"el":1,"az":34,"ss":0,"used":false},{"PRN":20,"el":5,"az":64,"ss":15,"used":false}]} +$GPGLL,,,,,032534.00,V,N*49 +{"class":"TPV","tag":"GLL","time":1155180334.000,"ept":0.005,"mode":0} +$GPZDA,032534.00,10,08,2006,00,00*68 +$GPRMC,032535.00,V,,,,,,,100806,,,N*70 +$GPVTG,,,,,,,,,N*30 +$GPGGA,032535.00,,,,,0,00,99.99,,,,,,*64 +$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 +$GPGSV,3,1,11,05,26,289,,17,58,061,,09,58,277,,24,44,112,*77 +$GPGSV,3,2,11,02,14,177,,04,37,146,,28,22,100,,26,07,220,*75 +$GPGSV,3,3,11,29,03,216,,11,01,034,,20,05,064,*47 +{"class":"SKY","tag":"GSV","satellites":[{"PRN":5,"el":26,"az":289,"ss":0,"used":false},{"PRN":17,"el":58,"az":61,"ss":0,"used":false},{"PRN":9,"el":58,"az":277,"ss":0,"used":false},{"PRN":24,"el":44,"az":112,"ss":0,"used":false},{"PRN":2,"el":14,"az":177,"ss":0,"used":false},{"PRN":4,"el":37,"az":146,"ss":0,"used":false},{"PRN":28,"el":22,"az":100,"ss":0,"used":false},{"PRN":26,"el":7,"az":220,"ss":0,"used":false},{"PRN":29,"el":3,"az":216,"ss":0,"used":false},{"PRN":11,"el":1,"az":34,"ss":0,"used":false},{"PRN":20,"el":5,"az":64,"ss":0,"used":false}]} +$GPGLL,,,,,032535.00,V,N*48 +{"class":"TPV","tag":"GLL","time":1155180335.000,"ept":0.005,"mode":0} +$GPZDA,032535.00,10,08,2006,00,00*69 diff --git a/test/daemon/uBlox-lea-4s.log b/test/daemon/uBlox-lea-4s.log new file mode 100644 index 0000000..634e43a --- /dev/null +++ b/test/daemon/uBlox-lea-4s.log @@ -0,0 +1,36 @@ +# Name: LEA-4S +# Chipset: ANTARIS +# Submitted-by: "Ali Utku Selen" +# 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 0000000..0c42dba Binary files /dev/null and b/test/daemon/uBlox-lea-4t.log differ diff --git a/test/daemon/uBlox-lea-4t.log.chk b/test/daemon/uBlox-lea-4t.log.chk new file mode 100644 index 0000000..00babb5 --- /dev/null +++ b/test/daemon/uBlox-lea-4t.log.chk @@ -0,0 +1,225 @@ +$GPGGA,203543,5333.7954,N,11326.3727,W,1,08,,655.33,M,-19.872,M,,*64 +$GPRMC,203543,A,5333.7954,N,11326.3727,W,0.0000,0.000,280109,,*31 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"0x0106","time":1233174943.001,"ept":0.005,"lat":53.563256268,"lon":-113.439544853,"alt":655.331,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGSV,3,1,11,21,73,276,33,24,56,094,46,15,40,113,30,18,40,217,43*7B +$GPGSV,3,2,11,26,40,087,45,29,40,164,34,16,28,280,33,10,21,056,38*70 +$GPGSV,3,3,11,22,09,225,29,27,06,055,24,07,05,000,25*4E +{"class":"SKY","tag":"0x0130","xdop":0.60,"ydop":0.98,"vdop":2.13,"tdop":1.40,"hdop":1.15,"gdop":2.80,"pdop":2.42,"satellites":[{"PRN":21,"el":73,"az":276,"ss":33,"used":true},{"PRN":24,"el":56,"az":94,"ss":46,"used":true},{"PRN":15,"el":40,"az":113,"ss":30,"used":true},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":34,"used":true},{"PRN":16,"el":28,"az":280,"ss":33,"used":true},{"PRN":10,"el":21,"az":56,"ss":38,"used":true},{"PRN":22,"el":9,"az":225,"ss":29,"used":false},{"PRN":27,"el":6,"az":55,"ss":24,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203544,5333.7952,N,11326.3727,W,1,08,1.15,655.35,M,-19.872,M,,*78 +$GPRMC,203544,A,5333.7952,N,11326.3727,W,0.0000,0.000,280109,,*30 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,2.4,1.1,2.1*37 +$GPGBS,203544,9.05,M,14.66,M,49.03,M*3D +{"class":"TPV","tag":"0x0106","time":1233174944.001,"ept":0.005,"lat":53.563254093,"lon":-113.439545157,"alt":655.348,"epx":9.054,"epy":14.659,"epv":49.029,"track":0.0000,"speed":0.000,"climb":0.000,"eps":29.32,"mode":3} +$GPGSV,3,1,11,21,73,276,32,24,56,094,46,15,40,113,30,18,40,217,43*7A +$GPGSV,3,2,11,26,40,087,45,29,40,164,34,16,28,280,33,10,21,056,39*71 +$GPGSV,3,3,11,22,09,225,29,27,06,055,24,07,05,000,26*4D +{"class":"SKY","tag":"0x0130","xdop":0.60,"ydop":0.98,"vdop":2.13,"tdop":1.40,"hdop":1.15,"gdop":2.80,"pdop":2.42,"satellites":[{"PRN":21,"el":73,"az":276,"ss":32,"used":true},{"PRN":24,"el":56,"az":94,"ss":46,"used":true},{"PRN":15,"el":40,"az":113,"ss":30,"used":true},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":34,"used":true},{"PRN":16,"el":28,"az":280,"ss":33,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":22,"el":9,"az":225,"ss":29,"used":false},{"PRN":27,"el":6,"az":55,"ss":24,"used":false},{"PRN":7,"el":5,"az":0,"ss":26,"used":false}]} +$GPGGA,203545,5333.7951,N,11326.3728,W,1,08,1.15,655.25,M,-19.872,M,,*74 +$GPRMC,203545,A,5333.7951,N,11326.3728,W,0.0000,0.000,280109,,*3D +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,2.4,1.1,2.1*37 +$GPGBS,203545,9.05,M,14.66,M,49.03,M*3C +{"class":"TPV","tag":"0x0106","time":1233174945.001,"ept":0.005,"lat":53.563252365,"lon":-113.439546320,"alt":655.254,"epx":9.054,"epy":14.659,"epv":49.029,"track":0.0000,"speed":0.000,"climb":0.000,"eps":29.32,"mode":3} +$GPGSV,3,1,11,21,73,276,32,24,56,094,46,15,40,113,31,18,40,217,43*7B +$GPGSV,3,2,11,26,40,087,45,29,40,164,34,16,28,280,32,10,21,056,39*70 +$GPGSV,3,3,11,22,09,225,29,27,06,055,24,07,05,000,25*4E +{"class":"SKY","tag":"0x0130","xdop":0.60,"ydop":0.98,"vdop":2.13,"tdop":1.40,"hdop":1.15,"gdop":2.80,"pdop":2.42,"satellites":[{"PRN":21,"el":73,"az":276,"ss":32,"used":true},{"PRN":24,"el":56,"az":94,"ss":46,"used":true},{"PRN":15,"el":40,"az":113,"ss":31,"used":true},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":34,"used":true},{"PRN":16,"el":28,"az":280,"ss":32,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":22,"el":9,"az":225,"ss":29,"used":false},{"PRN":27,"el":6,"az":55,"ss":24,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203546,5333.7950,N,11326.3728,W,1,07,1.15,655.18,M,-19.872,M,,*77 +$GPRMC,203546,A,5333.7950,N,11326.3728,W,0.0000,0.000,280109,,*3F +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,,2.4,1.1,2.1*37 +{"class":"TPV","tag":"0x0106","time":1233174946.001,"ept":0.005,"lat":53.563250640,"lon":-113.439547224,"alt":655.184,"epx":9.054,"epy":14.659,"epv":49.029,"track":0.0000,"speed":0.000,"climb":0.000,"eps":29.32,"mode":3} +$GPGSV,3,1,11,21,73,276,33,24,56,094,46,15,40,113,30,18,40,217,43*7B +$GPGSV,3,2,11,26,40,087,45,29,40,164,34,16,28,280,32,10,21,056,39*70 +$GPGSV,3,3,11,22,09,225,30,27,06,055,24,07,05,000,25*46 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":33,"used":true},{"PRN":24,"el":56,"az":94,"ss":46,"used":true},{"PRN":15,"el":40,"az":113,"ss":30,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":34,"used":true},{"PRN":16,"el":28,"az":280,"ss":32,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":27,"el":6,"az":55,"ss":24,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203547,5333.7949,N,11326.3729,W,1,07,1.36,655.14,M,-19.872,M,,*72 +$GPRMC,203547,A,5333.7949,N,11326.3729,W,0.0000,0.000,280109,,*37 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203547,9.91,M,17.83,M,62.12,M*32 +{"class":"TPV","tag":"0x0106","time":1233174947.001,"ept":0.005,"lat":53.563249046,"lon":-113.439548267,"alt":655.141,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":32.49,"mode":3} +$GPGSV,3,1,11,21,73,276,33,24,56,094,46,15,40,113,29,18,40,217,43*73 +$GPGSV,3,2,11,26,40,087,45,29,40,164,33,16,28,280,32,10,21,056,39*77 +$GPGSV,3,3,11,22,09,225,30,27,06,055,25,07,05,000,25*47 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":33,"used":true},{"PRN":24,"el":56,"az":94,"ss":46,"used":true},{"PRN":15,"el":40,"az":113,"ss":29,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":32,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":27,"el":6,"az":55,"ss":25,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203548,5333.7948,N,11326.3730,W,1,07,1.36,655.09,M,-19.872,M,,*78 +$GPRMC,203548,A,5333.7948,N,11326.3730,W,0.0000,0.000,280109,,*31 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203548,9.91,M,17.83,M,62.12,M*3D +{"class":"TPV","tag":"0x0106","time":1233174948.001,"ept":0.005,"lat":53.563247427,"lon":-113.439549171,"alt":655.088,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,3,1,11,21,73,276,32,24,56,094,46,15,40,113,29,18,40,217,43*72 +$GPGSV,3,2,11,26,40,087,45,29,40,164,33,16,28,280,32,10,21,056,39*77 +$GPGSV,3,3,11,22,09,225,29,27,06,055,24,07,05,000,25*4E +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":32,"used":true},{"PRN":24,"el":56,"az":94,"ss":46,"used":true},{"PRN":15,"el":40,"az":113,"ss":29,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":32,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":22,"el":9,"az":225,"ss":29,"used":false},{"PRN":27,"el":6,"az":55,"ss":24,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203549,5333.7947,N,11326.3730,W,1,07,1.36,655.02,M,-19.872,M,,*7D +$GPRMC,203549,A,5333.7947,N,11326.3730,W,0.0000,0.000,280109,,*3F +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203549,9.91,M,17.83,M,62.12,M*3C +{"class":"TPV","tag":"0x0106","time":1233174949.001,"ept":0.005,"lat":53.563245784,"lon":-113.439549937,"alt":655.024,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,3,1,12,21,73,276,32,24,56,094,46,15,40,113,26,18,40,217,43*7E +$GPGSV,3,2,12,26,40,087,45,29,40,164,33,16,28,280,32,10,21,056,39*74 +$GPGSV,3,3,12,03,10,317,25,22,09,225,30,27,06,055,25,07,05,000,25*74 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":32,"used":true},{"PRN":24,"el":56,"az":94,"ss":46,"used":true},{"PRN":15,"el":40,"az":113,"ss":26,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":32,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":27,"el":6,"az":55,"ss":25,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203550,5333.7947,N,11326.3731,W,1,07,1.36,654.88,M,-19.872,M,,*77 +$GPRMC,203550,A,5333.7947,N,11326.3731,W,0.0000,0.000,280109,,*36 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203550,9.91,M,17.83,M,62.12,M*34 +{"class":"TPV","tag":"0x0106","time":1233174950.001,"ept":0.005,"lat":53.563244339,"lon":-113.439551123,"alt":654.882,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,3,1,12,21,73,276,31,24,56,094,46,15,40,113,23,18,40,217,43*78 +$GPGSV,3,2,12,26,40,087,45,29,40,164,33,16,28,280,31,10,21,056,39*77 +$GPGSV,3,3,12,03,10,317,24,22,09,225,30,27,06,055,25,07,05,000,26*76 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":46,"used":true},{"PRN":15,"el":40,"az":113,"ss":23,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":31,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":3,"el":10,"az":317,"ss":24,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":27,"el":6,"az":55,"ss":25,"used":false},{"PRN":7,"el":5,"az":0,"ss":26,"used":false}]} +$GPGGA,203551,5333.7946,N,11326.3731,W,1,07,1.36,654.80,M,-19.872,M,,*7F +$GPRMC,203551,A,5333.7946,N,11326.3731,W,0.0000,0.000,280109,,*36 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203551,9.91,M,17.83,M,62.12,M*35 +{"class":"TPV","tag":"0x0106","time":1233174951.001,"ept":0.005,"lat":53.563242857,"lon":-113.439551871,"alt":654.805,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,3,1,12,21,73,276,31,24,56,094,46,15,40,113,25,18,40,217,43*7E +$GPGSV,3,2,12,26,40,087,45,29,40,164,33,16,28,280,32,10,21,056,39*74 +$GPGSV,3,3,12,03,10,317,24,22,09,225,30,27,06,055,25,07,05,000,26*76 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":46,"used":true},{"PRN":15,"el":40,"az":113,"ss":25,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":32,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":3,"el":10,"az":317,"ss":24,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":27,"el":6,"az":55,"ss":25,"used":false},{"PRN":7,"el":5,"az":0,"ss":26,"used":false}]} +$GPGGA,203552,5333.7945,N,11326.3731,W,1,07,1.36,654.84,M,-19.872,M,,*7B +$GPRMC,203552,A,5333.7945,N,11326.3731,W,0.0000,0.000,280109,,*36 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203552,9.91,M,17.83,M,62.12,M*36 +{"class":"TPV","tag":"0x0106","time":1233174952.001,"ept":0.005,"lat":53.563241243,"lon":-113.439552276,"alt":654.838,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,3,1,12,21,73,276,31,24,56,094,45,15,40,113,25,18,40,217,43*7D +$GPGSV,3,2,12,26,40,087,45,29,40,164,33,16,28,280,32,10,21,056,39*74 +$GPGSV,3,3,12,03,10,317,25,22,09,225,30,27,06,055,25,07,05,000,25*74 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":25,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":32,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":27,"el":6,"az":55,"ss":25,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203553,5333.7944,N,11326.3731,W,1,07,1.36,654.89,M,-19.872,M,,*76 +$GPRMC,203553,A,5333.7944,N,11326.3731,W,0.0000,0.000,280109,,*36 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203553,9.91,M,17.83,M,62.12,M*37 +{"class":"TPV","tag":"0x0106","time":1233174953.001,"ept":0.005,"lat":53.563239698,"lon":-113.439552484,"alt":654.890,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,3,1,12,21,73,276,31,24,56,094,45,15,40,113,25,18,40,217,43*7D +$GPGSV,3,2,12,26,40,087,45,29,40,164,33,16,28,280,32,10,21,056,40*7A +$GPGSV,3,3,12,03,10,317,25,22,09,225,30,27,06,055,24,07,05,000,25*75 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":25,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":32,"used":true},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":27,"el":6,"az":55,"ss":24,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203554,5333.7943,N,11326.3732,W,1,07,1.36,654.98,M,-19.872,M,,*75 +$GPRMC,203554,A,5333.7943,N,11326.3732,W,0.0000,0.000,280109,,*35 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203554,9.91,M,17.83,M,62.12,M*30 +{"class":"TPV","tag":"0x0106","time":1233174954.001,"ept":0.005,"lat":53.563238309,"lon":-113.439552968,"alt":654.979,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,3,1,12,21,73,276,32,24,56,094,45,15,40,113,24,18,40,217,43*7F +$GPGSV,3,2,12,26,40,087,45,29,40,164,34,16,28,280,32,10,21,056,39*73 +$GPGSV,3,3,12,03,10,317,25,22,09,225,30,27,06,055,24,07,05,000,25*75 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":32,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":24,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":34,"used":true},{"PRN":16,"el":28,"az":280,"ss":32,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":27,"el":6,"az":55,"ss":24,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203555,5333.7942,N,11326.3732,W,1,07,1.36,655.09,M,-19.872,M,,*7C +$GPRMC,203555,A,5333.7942,N,11326.3732,W,0.0000,0.000,280109,,*35 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203555,9.91,M,17.83,M,62.12,M*31 +{"class":"TPV","tag":"0x0106","time":1233174955.001,"ept":0.005,"lat":53.563236952,"lon":-113.439553055,"alt":655.091,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,3,1,12,21,73,276,32,24,56,094,45,15,40,113,23,18,40,217,43*78 +$GPGSV,3,2,12,26,40,087,45,29,40,164,33,16,28,280,33,10,21,056,39*75 +$GPGSV,3,3,12,03,10,317,25,22,09,225,30,27,06,055,27,07,05,000,25*76 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":32,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":23,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":33,"used":true},{"PRN":10,"el":21,"az":56,"ss":39,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":27,"el":6,"az":55,"ss":27,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203556,5333.7941,N,11326.3732,W,1,07,1.36,655.13,M,-19.872,M,,*77 +$GPRMC,203556,A,5333.7941,N,11326.3732,W,0.0000,0.000,280109,,*35 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203556,9.91,M,17.83,M,62.12,M*32 +{"class":"TPV","tag":"0x0106","time":1233174956.001,"ept":0.005,"lat":53.563235688,"lon":-113.439553304,"alt":655.133,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,4,1,13,21,73,276,31,24,56,094,45,15,40,113,24,18,40,217,43*7A +$GPGSV,4,2,13,26,40,087,45,29,40,164,33,16,28,280,32,06,21,311,21*7C +$GPGSV,4,3,13,10,21,056,40,03,10,317,27,22,09,225,31,27,06,055,27*73 +$GPGSV,4,4,13,07,05,000,25*4E +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":24,"used":false},{"PRN":18,"el":40,"az":217,"ss":43,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":32,"used":true},{"PRN":6,"el":21,"az":311,"ss":21,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":27,"used":false},{"PRN":22,"el":9,"az":225,"ss":31,"used":false},{"PRN":27,"el":6,"az":55,"ss":27,"used":false},{"PRN":7,"el":5,"az":0,"ss":25,"used":false}]} +$GPGGA,203557,5333.7941,N,11326.3732,W,1,07,1.36,655.18,M,-19.872,M,,*7D +$GPRMC,203557,A,5333.7941,N,11326.3732,W,0.0000,0.000,280109,,*34 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203557,9.91,M,17.83,M,62.12,M*33 +{"class":"TPV","tag":"0x0106","time":1233174957.001,"ept":0.005,"lat":53.563234506,"lon":-113.439553414,"alt":655.180,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,4,1,14,21,73,276,31,24,56,094,45,15,40,113,24,18,40,217,44*7A +$GPGSV,4,2,14,26,40,087,45,29,40,164,33,16,28,280,33,06,21,311,23*78 +$GPGSV,4,3,14,10,21,056,40,03,10,317,27,22,09,225,31,08,06,036,18*70 +$GPGSV,4,4,14,27,06,055,27,07,05,000,24*7E +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":24,"used":false},{"PRN":18,"el":40,"az":217,"ss":44,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":33,"used":true},{"PRN":6,"el":21,"az":311,"ss":23,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":27,"used":false},{"PRN":22,"el":9,"az":225,"ss":31,"used":false},{"PRN":8,"el":6,"az":36,"ss":18,"used":false},{"PRN":27,"el":6,"az":55,"ss":27,"used":false},{"PRN":7,"el":5,"az":0,"ss":24,"used":false}]} +$GPGGA,203558,5333.7940,N,11326.3732,W,1,07,1.36,655.22,M,-19.872,M,,*7A +$GPRMC,203558,A,5333.7940,N,11326.3732,W,0.0000,0.000,280109,,*3A +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203558,9.91,M,17.83,M,62.12,M*3C +{"class":"TPV","tag":"0x0106","time":1233174958.001,"ept":0.005,"lat":53.563233539,"lon":-113.439553506,"alt":655.222,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,4,1,14,21,73,276,31,24,56,094,45,15,40,113,24,18,40,217,44*7A +$GPGSV,4,2,14,26,40,087,45,29,40,164,33,16,28,280,33,06,21,311,25*7E +$GPGSV,4,3,14,10,21,056,40,03,10,317,26,22,09,225,31,08,06,036,18*71 +$GPGSV,4,4,14,27,06,055,26,07,05,000,24*7F +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":24,"used":false},{"PRN":18,"el":40,"az":217,"ss":44,"used":true},{"PRN":26,"el":40,"az":87,"ss":45,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":33,"used":true},{"PRN":6,"el":21,"az":311,"ss":25,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":26,"used":false},{"PRN":22,"el":9,"az":225,"ss":31,"used":false},{"PRN":8,"el":6,"az":36,"ss":18,"used":false},{"PRN":27,"el":6,"az":55,"ss":26,"used":false},{"PRN":7,"el":5,"az":0,"ss":24,"used":false}]} +$GPGGA,203559,5333.7940,N,11326.3733,W,1,07,1.36,655.22,M,-19.872,M,,*7A +$GPRMC,203559,A,5333.7940,N,11326.3733,W,0.0000,0.000,280109,,*3A +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203559,9.91,M,17.83,M,62.12,M*3D +{"class":"TPV","tag":"0x0106","time":1233174959.001,"ept":0.005,"lat":53.563232686,"lon":-113.439554175,"alt":655.218,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,4,1,14,21,73,276,31,24,56,094,45,15,40,113,24,18,40,217,44*7A +$GPGSV,4,2,14,26,40,087,44,29,40,164,34,16,28,280,31,06,21,311,25*7A +$GPGSV,4,3,14,10,21,056,40,03,10,317,25,22,09,225,30,08,06,036,15*7E +$GPGSV,4,4,14,27,06,055,27,07,05,000,24*7E +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":24,"used":false},{"PRN":18,"el":40,"az":217,"ss":44,"used":true},{"PRN":26,"el":40,"az":87,"ss":44,"used":true},{"PRN":29,"el":40,"az":164,"ss":34,"used":true},{"PRN":16,"el":28,"az":280,"ss":31,"used":true},{"PRN":6,"el":21,"az":311,"ss":25,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":8,"el":6,"az":36,"ss":15,"used":false},{"PRN":27,"el":6,"az":55,"ss":27,"used":false},{"PRN":7,"el":5,"az":0,"ss":24,"used":false}]} +$GPGGA,203600,5333.7939,N,11326.3733,W,1,07,1.36,655.26,M,-19.872,M,,*7F +$GPRMC,203600,A,5333.7939,N,11326.3733,W,0.0000,0.000,280109,,*3B +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203600,9.91,M,17.83,M,62.12,M*32 +{"class":"TPV","tag":"0x0106","time":1233174960.001,"ept":0.005,"lat":53.563232220,"lon":-113.439554904,"alt":655.256,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,4,1,14,21,73,276,32,24,56,094,45,15,40,113,23,18,40,217,44*7E +$GPGSV,4,2,14,26,40,087,44,29,40,164,34,16,28,280,31,06,21,311,25*7A +$GPGSV,4,3,14,10,21,056,40,03,10,317,25,22,09,225,30,08,06,036,18*73 +$GPGSV,4,4,14,27,06,055,27,07,05,000,24*7E +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":32,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":23,"used":false},{"PRN":18,"el":40,"az":217,"ss":44,"used":true},{"PRN":26,"el":40,"az":87,"ss":44,"used":true},{"PRN":29,"el":40,"az":164,"ss":34,"used":true},{"PRN":16,"el":28,"az":280,"ss":31,"used":true},{"PRN":6,"el":21,"az":311,"ss":25,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":8,"el":6,"az":36,"ss":18,"used":false},{"PRN":27,"el":6,"az":55,"ss":27,"used":false},{"PRN":7,"el":5,"az":0,"ss":24,"used":false}]} +$GPGGA,203601,5333.7939,N,11326.3733,W,1,06,1.36,655.20,M,-19.872,M,,*79 +$GPRMC,203601,A,5333.7939,N,11326.3733,W,0.0000,0.000,280109,,*3A +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203601,9.91,M,17.83,M,62.12,M*33 +{"class":"TPV","tag":"0x0106","time":1233174961.001,"ept":0.005,"lat":53.563231439,"lon":-113.439555338,"alt":655.196,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,4,1,14,21,73,276,32,24,56,094,45,15,40,113,24,18,40,217,44*79 +$GPGSV,4,2,14,26,40,087,44,29,40,164,34,16,28,280,31,06,21,311,28*77 +$GPGSV,4,3,14,10,21,056,40,03,10,317,25,22,09,225,30,08,06,036,18*73 +$GPGSV,4,4,14,27,06,055,27,07,05,000,24*7E +{"class":"SKY","tag":"0x0130","xdop":1.29,"ydop":2.35,"vdop":5.81,"tdop":4.99,"hdop":2.68,"gdop":8.12,"pdop":6.40,"satellites":[{"PRN":21,"el":73,"az":276,"ss":32,"used":false},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":24,"used":false},{"PRN":18,"el":40,"az":217,"ss":44,"used":true},{"PRN":26,"el":40,"az":87,"ss":44,"used":true},{"PRN":29,"el":40,"az":164,"ss":34,"used":true},{"PRN":16,"el":28,"az":280,"ss":31,"used":true},{"PRN":6,"el":21,"az":311,"ss":28,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":8,"el":6,"az":36,"ss":18,"used":false},{"PRN":27,"el":6,"az":55,"ss":27,"used":false},{"PRN":7,"el":5,"az":0,"ss":24,"used":false}]} +$GPGGA,203602,5333.7939,N,11326.3734,W,1,07,2.68,655.19,M,-19.872,M,,*7E +$GPRMC,203602,A,5333.7939,N,11326.3734,W,0.0000,0.000,280109,,*3E +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,6.4,2.7,5.8*38 +$GPGBS,203602,19.34,M,35.29,M,133.62,M*3C +{"class":"TPV","tag":"0x0106","time":1233174962.001,"ept":0.005,"lat":53.563230854,"lon":-113.439555989,"alt":655.194,"epx":19.340,"epy":35.289,"epv":133.617,"track":0.0000,"speed":0.000,"climb":0.000,"eps":53.12,"mode":3} +$GPGSV,4,1,14,21,73,276,31,24,56,094,45,15,40,113,24,18,40,217,44*7A +$GPGSV,4,2,14,26,40,087,44,29,40,164,33,16,28,280,31,06,21,311,27*7F +$GPGSV,4,3,14,10,21,056,40,03,10,317,25,22,09,225,30,08,06,036,18*73 +$GPGSV,4,4,14,27,06,055,28,07,05,000,21*74 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":24,"used":false},{"PRN":18,"el":40,"az":217,"ss":44,"used":true},{"PRN":26,"el":40,"az":87,"ss":44,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":31,"used":true},{"PRN":6,"el":21,"az":311,"ss":27,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":8,"el":6,"az":36,"ss":18,"used":false},{"PRN":27,"el":6,"az":55,"ss":28,"used":false},{"PRN":7,"el":5,"az":0,"ss":21,"used":false}]} +$GPGGA,203603,5333.7938,N,11326.3734,W,1,07,1.36,655.18,M,-19.872,M,,*77 +$GPRMC,203603,A,5333.7938,N,11326.3734,W,0.0000,0.000,280109,,*3E +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203603,9.91,M,17.83,M,62.12,M*31 +{"class":"TPV","tag":"0x0106","time":1233174963.001,"ept":0.005,"lat":53.563230468,"lon":-113.439556819,"alt":655.176,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":53.12,"mode":3} +$GPGSV,4,1,14,21,73,276,31,24,56,094,45,15,40,113,25,18,40,217,44*7B +$GPGSV,4,2,14,26,40,087,44,29,40,164,33,16,28,280,30,06,21,311,27*7E +$GPGSV,4,3,14,10,21,056,40,03,10,317,25,22,09,225,30,08,06,036,18*73 +$GPGSV,4,4,14,27,06,055,28,07,05,000,21*74 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":25,"used":false},{"PRN":18,"el":40,"az":217,"ss":44,"used":true},{"PRN":26,"el":40,"az":87,"ss":44,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":30,"used":true},{"PRN":6,"el":21,"az":311,"ss":27,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":8,"el":6,"az":36,"ss":18,"used":false},{"PRN":27,"el":6,"az":55,"ss":28,"used":false},{"PRN":7,"el":5,"az":0,"ss":21,"used":false}]} +$GPGGA,203604,5333.7938,N,11326.3735,W,1,07,1.36,655.23,M,-19.872,M,,*79 +$GPRMC,203604,A,5333.7938,N,11326.3735,W,0.0000,0.000,280109,,*38 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203604,9.91,M,17.83,M,62.12,M*36 +{"class":"TPV","tag":"0x0106","time":1233174964.001,"ept":0.005,"lat":53.563230108,"lon":-113.439557548,"alt":655.231,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,4,1,14,21,73,276,32,24,56,094,45,15,40,113,27,18,40,217,44*7A +$GPGSV,4,2,14,26,40,087,44,29,40,164,32,16,28,280,31,06,21,311,27*7E +$GPGSV,4,3,14,10,21,056,40,03,10,317,25,22,09,225,30,08,06,036,18*73 +$GPGSV,4,4,14,27,06,055,28,07,05,000,22*77 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":32,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":27,"used":false},{"PRN":18,"el":40,"az":217,"ss":44,"used":true},{"PRN":26,"el":40,"az":87,"ss":44,"used":true},{"PRN":29,"el":40,"az":164,"ss":32,"used":true},{"PRN":16,"el":28,"az":280,"ss":31,"used":true},{"PRN":6,"el":21,"az":311,"ss":27,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":8,"el":6,"az":36,"ss":18,"used":false},{"PRN":27,"el":6,"az":55,"ss":28,"used":false},{"PRN":7,"el":5,"az":0,"ss":22,"used":false}]} +$GPGGA,203605,5333.7938,N,11326.3735,W,1,07,1.36,655.29,M,-19.872,M,,*72 +$GPRMC,203605,A,5333.7938,N,11326.3735,W,0.0000,0.000,280109,,*39 +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203605,9.91,M,17.83,M,62.12,M*37 +{"class":"TPV","tag":"0x0106","time":1233174965.001,"ept":0.005,"lat":53.563229839,"lon":-113.439558476,"alt":655.290,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,4,1,14,21,73,276,32,24,56,094,45,15,40,113,27,18,40,217,44*7A +$GPGSV,4,2,14,26,40,087,44,29,40,164,33,16,28,280,30,06,21,311,28*71 +$GPGSV,4,3,14,10,21,056,40,03,10,317,25,22,09,225,30,08,06,036,18*73 +$GPGSV,4,4,14,27,06,055,28,07,05,000,23*76 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":32,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":27,"used":false},{"PRN":18,"el":40,"az":217,"ss":44,"used":true},{"PRN":26,"el":40,"az":87,"ss":44,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":30,"used":true},{"PRN":6,"el":21,"az":311,"ss":28,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":8,"el":6,"az":36,"ss":18,"used":false},{"PRN":27,"el":6,"az":55,"ss":28,"used":false},{"PRN":7,"el":5,"az":0,"ss":23,"used":false}]} +$GPGGA,203606,5333.7938,N,11326.3735,W,1,07,1.36,655.31,M,-19.872,M,,*78 +$GPRMC,203606,A,5333.7938,N,11326.3735,W,0.0000,0.000,280109,,*3A +$GPGSA,A,3,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,,,,,,,,,,,,,,3.0,1.4,2.7*31 +$GPGBS,203606,9.91,M,17.83,M,62.12,M*34 +{"class":"TPV","tag":"0x0106","time":1233174966.001,"ept":0.005,"lat":53.563229443,"lon":-113.439558988,"alt":655.310,"epx":9.910,"epy":17.828,"epv":62.124,"track":0.0000,"speed":0.000,"climb":0.000,"eps":35.66,"mode":3} +$GPGSV,4,1,14,21,73,276,31,24,56,094,45,15,40,113,27,18,40,217,44*79 +$GPGSV,4,2,14,26,40,087,44,29,40,164,33,16,28,280,31,06,22,310,27*7D +$GPGSV,4,3,14,10,21,056,40,03,10,317,25,22,09,225,30,08,06,036,18*73 +$GPGSV,4,4,14,27,06,055,28,07,05,000,23*76 +{"class":"SKY","tag":"0x0130","xdop":0.66,"ydop":1.19,"vdop":2.70,"tdop":1.94,"hdop":1.36,"gdop":3.59,"pdop":3.02,"satellites":[{"PRN":21,"el":73,"az":276,"ss":31,"used":true},{"PRN":24,"el":56,"az":94,"ss":45,"used":true},{"PRN":15,"el":40,"az":113,"ss":27,"used":false},{"PRN":18,"el":40,"az":217,"ss":44,"used":true},{"PRN":26,"el":40,"az":87,"ss":44,"used":true},{"PRN":29,"el":40,"az":164,"ss":33,"used":true},{"PRN":16,"el":28,"az":280,"ss":31,"used":true},{"PRN":6,"el":22,"az":310,"ss":27,"used":false},{"PRN":10,"el":21,"az":56,"ss":40,"used":true},{"PRN":3,"el":10,"az":317,"ss":25,"used":false},{"PRN":22,"el":9,"az":225,"ss":30,"used":false},{"PRN":8,"el":6,"az":36,"ss":18,"used":false},{"PRN":27,"el":6,"az":55,"ss":28,"used":false},{"PRN":7,"el":5,"az":0,"ss":23,"used":false}]} diff --git a/test/daemon/uBlox-sirf1.log b/test/daemon/uBlox-sirf1.log new file mode 100644 index 0000000..a73f700 Binary files /dev/null and b/test/daemon/uBlox-sirf1.log differ diff --git a/test/daemon/uBlox-sirf1.log.chk b/test/daemon/uBlox-sirf1.log.chk new file mode 100644 index 0000000..9c9397a --- /dev/null +++ b/test/daemon/uBlox-sirf1.log.chk @@ -0,0 +1,316 @@ +$GPGSV,3,1,12,04,51,189,00,11,63,142,46,23,22,187,45,20,69,250,45*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,46*71 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,45,24,43,294,47*77 +{"class":"SKY","tag":"MID4","time":1118480771.990,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":46,"used":false},{"PRN":23,"el":22,"az":187,"ss":45,"used":false},{"PRN":20,"el":69,"az":250,"ss":45,"used":false},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":false},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":46,"used":false},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":false},{"PRN":25,"el":18,"az":90,"ss":45,"used":false},{"PRN":24,"el":43,"az":294,"ss":47,"used":false}]} +$GPGGA,090611,5203.7606,N,00508.3161,E,1,08,1.80,33.30,M,46.772,M,,*74 +$GPRMC,090611,A,5203.7606,N,00508.3161,E,0.0000,0.000,110605,,*2A +$GPGSA,A,3,11,23,20,07,01,14,25,24,,,,,0.0,1.8,0.0*3A +{"class":"TPV","tag":"MID2","time":1118480771.990,"ept":0.005,"lat":52.062675884,"lon":5.138600900,"alt":33.299,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$GPGGA,090613,5203.7605,N,00508.3168,E,1,08,1.80,34.43,M,46.772,M,,*7F +$GPRMC,090613,A,5203.7605,N,00508.3168,E,0.0447,54.442,110605,,*16 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480773.999,"ept":0.005,"lat":52.062675221,"lon":5.138613239,"alt":34.425,"epv":23.000,"track":54.4418,"speed":0.023,"climb":0.024,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,46,23,22,187,44,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,46*71 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480772.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":46,"used":true},{"PRN":23,"el":22,"az":187,"ss":44,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":46,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090614,5203.7605,N,00508.3168,E,1,08,1.80,34.44,M,46.772,M,,*7F +$GPRMC,090614,A,5203.7605,N,00508.3168,E,0.0525,55.231,110605,,*17 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480774.999,"ept":0.005,"lat":52.062674648,"lon":5.138613239,"alt":34.441,"epx":13.815,"epy":10.613,"epv":23.000,"track":55.2310,"speed":0.027,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,45,24,43,294,48*78 +{"class":"SKY","tag":"MID4","time":1118480773.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":45,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090615,5203.7605,N,00508.3168,E,1,08,1.80,34.46,M,46.772,M,,*7C +$GPRMC,090615,A,5203.7605,N,00508.3168,E,0.0467,53.664,110605,,*13 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480775.999,"ept":0.005,"lat":52.062674648,"lon":5.138613239,"alt":34.458,"epx":13.815,"epy":10.613,"epv":23.000,"track":53.6641,"speed":0.024,"climb":0.024,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,44,20,69,250,44*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,44,24,43,294,48*78 +{"class":"SKY","tag":"MID4","time":1118480774.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":44,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090616,5203.7605,N,00508.3168,E,1,08,1.80,34.47,M,46.772,M,,*7E +$GPRMC,090616,A,5203.7605,N,00508.3168,E,0.0525,57.361,110605,,*13 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480776.999,"ept":0.005,"lat":52.062674648,"lon":5.138613239,"alt":34.472,"epx":13.815,"epy":10.613,"epv":23.000,"track":57.3607,"speed":0.027,"climb":0.026,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,44,20,69,250,45*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,45,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480775.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":44,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":45,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090617,5203.7605,N,00508.3168,E,1,08,1.80,34.49,M,46.772,M,,*71 +$GPRMC,090617,A,5203.7605,N,00508.3168,E,0.0467,50.658,110605,,*1D +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480777.999,"ept":0.005,"lat":52.062674648,"lon":5.138613239,"alt":34.488,"epx":13.815,"epy":10.613,"epv":23.000,"track":50.6579,"speed":0.024,"climb":0.025,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,44,20,69,250,44*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,44,24,43,294,48*78 +{"class":"SKY","tag":"MID4","time":1118480776.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":44,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090618,5203.7605,N,00508.3168,E,1,08,1.80,34.50,M,46.772,M,,*76 +$GPRMC,090618,A,5203.7605,N,00508.3168,E,0.0583,58.520,110605,,*1D +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480778.999,"ept":0.005,"lat":52.062674648,"lon":5.138613239,"alt":34.504,"epx":13.815,"epy":10.613,"epv":23.000,"track":58.5200,"speed":0.030,"climb":0.029,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,44,20,69,250,44*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,44,24,43,294,47*77 +{"class":"SKY","tag":"MID4","time":1118480777.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":44,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090619,5203.7605,N,00508.3168,E,1,08,1.80,34.53,M,46.772,M,,*74 +$GPRMC,090619,A,5203.7605,N,00508.3168,E,0.0525,52.550,110605,,*1D +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480779.999,"ept":0.005,"lat":52.062674648,"lon":5.138613239,"alt":34.525,"epx":13.815,"epy":10.613,"epv":23.000,"track":52.5503,"speed":0.027,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,44,20,69,250,44*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,45,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480778.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":44,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":45,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090620,5203.7604,N,00508.3168,E,1,08,1.80,34.55,M,46.772,M,,*79 +$GPRMC,090620,A,5203.7604,N,00508.3168,E,0.0544,52.048,110605,,*1D +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480780.999,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.545,"epx":13.815,"epy":10.613,"epv":23.000,"track":52.0477,"speed":0.028,"climb":0.026,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,44,20,69,250,45*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,42,02,13,316,00,01,49,069,47*71 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,44,24,43,294,47*77 +{"class":"SKY","tag":"MID4","time":1118480779.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":44,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":42,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090621,5203.7604,N,00508.3168,E,1,08,1.80,34.56,M,46.772,M,,*7B +$GPRMC,090621,A,5203.7604,N,00508.3168,E,0.0505,57.303,110605,,*10 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480781.999,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.563,"epx":13.815,"epy":10.613,"epv":23.000,"track":57.3033,"speed":0.026,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,44,20,69,250,44*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,44,24,43,294,47*77 +{"class":"SKY","tag":"MID4","time":1118480780.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":44,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090622,5203.7604,N,00508.3168,E,1,08,1.80,34.58,M,46.772,M,,*76 +$GPRMC,090622,A,5203.7604,N,00508.3168,E,0.0544,50.157,110605,,*12 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480782.999,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.581,"epx":13.815,"epy":10.613,"epv":23.000,"track":50.1571,"speed":0.028,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,44,20,69,250,45*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,44,24,43,294,48*78 +{"class":"SKY","tag":"MID4","time":1118480781.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":44,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090623,5203.7604,N,00508.3168,E,1,08,1.80,34.60,M,46.772,M,,*7C +$GPRMC,090623,A,5203.7604,N,00508.3168,E,0.0544,53.626,110605,,*11 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480783.999,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.599,"epx":13.815,"epy":10.613,"epv":23.000,"track":53.6261,"speed":0.028,"climb":0.025,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,44*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,42,02,13,316,00,01,49,069,46*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480782.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":42,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":46,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090624,5203.7604,N,00508.3168,E,1,08,1.80,34.61,M,46.772,M,,*7A +$GPRMC,090624,A,5203.7604,N,00508.3168,E,0.0505,52.472,110605,,*11 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480784.999,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.614,"epx":13.815,"epy":10.613,"epv":23.000,"track":52.4722,"speed":0.026,"climb":0.024,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,44*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,42,02,13,316,00,01,49,069,46*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480783.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":42,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":46,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090625,5203.7604,N,00508.3168,E,1,08,1.80,34.63,M,46.772,M,,*79 +$GPRMC,090625,A,5203.7604,N,00508.3168,E,0.0544,46.638,110605,,*1C +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480785.998,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.628,"epx":13.815,"epy":10.613,"epv":23.000,"track":46.6380,"speed":0.028,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,46,20,69,250,44*7E +$GPGSV,3,2,12,13,34,231,00,07,35,297,42,02,13,316,00,01,49,069,47*71 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480784.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":46,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":42,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090626,5203.7604,N,00508.3168,E,1,08,1.80,34.65,M,46.772,M,,*7C +$GPRMC,090626,A,5203.7604,N,00508.3168,E,0.0525,52.472,110605,,*11 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480786.998,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.645,"epx":13.815,"epy":10.613,"epv":23.000,"track":52.4723,"speed":0.027,"climb":0.025,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,44*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,42,02,13,316,00,01,49,069,47*71 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480785.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":42,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090627,5203.7604,N,00508.3168,E,1,08,1.80,34.66,M,46.772,M,,*7E +$GPRMC,090627,A,5203.7604,N,00508.3168,E,0.0467,55.803,110605,,*1A +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480787.999,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.660,"epx":13.815,"epy":10.613,"epv":23.000,"track":55.8031,"speed":0.024,"climb":0.024,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,44*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,42,02,13,316,00,01,49,069,47*71 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480786.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":42,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090628,5203.7604,N,00508.3168,E,1,08,1.80,34.68,M,46.772,M,,*7F +$GPRMC,090628,A,5203.7604,N,00508.3168,E,0.0544,57.676,110605,,*1B +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480788.999,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.676,"epx":13.815,"epy":10.613,"epv":23.000,"track":57.6760,"speed":0.028,"climb":0.026,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,44*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,42,02,13,316,00,01,49,069,47*71 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480787.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":42,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090629,5203.7604,N,00508.3168,E,1,08,1.80,34.69,M,46.772,M,,*7F +$GPRMC,090629,A,5203.7604,N,00508.3168,E,0.0505,47.992,110605,,*1B +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480789.999,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.694,"epx":13.815,"epy":10.613,"epv":23.000,"track":47.9916,"speed":0.026,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,44*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480788.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090630,5203.7604,N,00508.3168,E,1,08,1.80,34.71,M,46.772,M,,*7E +$GPRMC,090630,A,5203.7604,N,00508.3168,E,0.0525,54.404,110605,,*11 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480790.999,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.713,"epx":13.815,"epy":10.613,"epv":23.000,"track":54.4040,"speed":0.027,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,44,24,43,294,47*77 +{"class":"SKY","tag":"MID4","time":1118480789.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090631,5203.7604,N,00508.3168,E,1,08,1.80,34.73,M,46.772,M,,*7D +$GPRMC,090631,A,5203.7604,N,00508.3168,E,0.0544,57.430,110605,,*13 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480791.999,"ept":0.005,"lat":52.062674075,"lon":5.138613239,"alt":34.732,"epx":13.815,"epy":10.613,"epv":23.000,"track":57.4299,"speed":0.028,"climb":0.029,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,44,20,69,250,44*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,44,02,13,316,00,01,49,069,47*77 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480790.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":44,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":44,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090632,5203.7604,N,00508.3168,E,1,08,1.80,34.75,M,46.772,M,,*78 +$GPRMC,090632,A,5203.7604,N,00508.3168,E,0.0505,50.753,110605,,*14 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480792.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.754,"epx":13.815,"epy":10.613,"epv":23.000,"track":50.7535,"speed":0.026,"climb":0.024,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,44*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,44,02,13,316,00,01,49,069,47*77 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480791.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":44,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090633,5203.7604,N,00508.3168,E,1,08,1.80,34.77,M,46.772,M,,*7B +$GPRMC,090633,A,5203.7604,N,00508.3168,E,0.0525,55.771,110605,,*12 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480793.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.770,"epx":13.815,"epy":10.613,"epv":23.000,"track":55.7710,"speed":0.027,"climb":0.025,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,44*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,44,02,13,316,00,01,49,069,47*77 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480792.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":44,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090634,5203.7604,N,00508.3168,E,1,08,1.80,34.79,M,46.772,M,,*72 +$GPRMC,090634,A,5203.7604,N,00508.3168,E,0.0525,56.120,110605,,*14 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480794.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.788,"epx":13.815,"epy":10.613,"epv":23.000,"track":56.1196,"speed":0.027,"climb":0.029,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,44,02,13,316,00,01,49,069,47*77 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480793.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":44,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090635,5203.7604,N,00508.3168,E,1,08,1.80,34.81,M,46.772,M,,*74 +$GPRMC,090635,A,5203.7604,N,00508.3168,E,0.0505,55.137,110605,,*12 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480795.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.810,"epx":13.815,"epy":10.613,"epv":23.000,"track":55.1368,"speed":0.026,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,44,02,13,316,00,01,49,069,47*77 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,43,24,43,294,48*7E +{"class":"SKY","tag":"MID4","time":1118480794.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":44,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":43,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090636,5203.7604,N,00508.3168,E,1,08,1.80,34.83,M,46.772,M,,*75 +$GPRMC,090636,A,5203.7604,N,00508.3168,E,0.0525,56.312,110605,,*15 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480796.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.830,"epx":13.815,"epy":10.613,"epv":23.000,"track":56.3121,"speed":0.027,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480795.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090637,5203.7604,N,00508.3168,E,1,08,1.80,34.85,M,46.772,M,,*72 +$GPRMC,090637,A,5203.7604,N,00508.3168,E,0.0564,56.963,110605,,*1D +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480797.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.850,"epx":13.815,"epy":10.613,"epv":23.000,"track":56.9633,"speed":0.029,"climb":0.028,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480796.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090638,5203.7604,N,00508.3168,E,1,08,1.80,34.87,M,46.772,M,,*7F +$GPRMC,090638,A,5203.7604,N,00508.3168,E,0.0467,50.169,110605,,*14 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480798.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.871,"epx":13.815,"epy":10.613,"epv":23.000,"track":50.1692,"speed":0.024,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,48*79 +{"class":"SKY","tag":"MID4","time":1118480797.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090639,5203.7604,N,00508.3168,E,1,08,1.80,34.89,M,46.772,M,,*70 +$GPRMC,090639,A,5203.7604,N,00508.3168,E,0.0583,59.282,110605,,*11 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480799.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.891,"epx":13.815,"epy":10.613,"epv":23.000,"track":59.2822,"speed":0.030,"climb":0.026,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,44*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,45,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480798.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":45,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090640,5203.7604,N,00508.3168,E,1,08,1.80,34.91,M,46.772,M,,*77 +$GPRMC,090640,A,5203.7604,N,00508.3168,E,0.0583,50.788,110605,,*19 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480800.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.908,"epx":13.815,"epy":10.613,"epv":23.000,"track":50.7882,"speed":0.030,"climb":0.027,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,45,24,43,294,47*77 +{"class":"SKY","tag":"MID4","time":1118480799.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":45,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090641,5203.7604,N,00508.3168,E,1,08,1.80,34.93,M,46.772,M,,*74 +$GPRMC,090641,A,5203.7604,N,00508.3168,E,0.0544,52.764,110605,,*13 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480801.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.927,"epx":13.815,"epy":10.613,"epv":23.000,"track":52.7638,"speed":0.028,"climb":0.028,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,44,02,13,316,00,01,49,069,47*77 +$GPGSV,3,3,12,27,46,082,00,14,18,040,46,25,18,090,45,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480800.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":44,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":46,"used":true},{"PRN":25,"el":18,"az":90,"ss":45,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090642,5203.7604,N,00508.3168,E,1,08,1.80,34.95,M,46.772,M,,*71 +$GPRMC,090642,A,5203.7604,N,00508.3168,E,0.0525,53.233,110605,,*11 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480802.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.947,"epx":13.815,"epy":10.613,"epv":23.000,"track":53.2332,"speed":0.027,"climb":0.026,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,44,02,13,316,00,01,49,069,46*76 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,45,24,43,294,47*77 +{"class":"SKY","tag":"MID4","time":1118480801.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":44,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":46,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":45,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090643,5203.7604,N,00508.3168,E,1,08,1.80,34.97,M,46.772,M,,*72 +$GPRMC,090643,A,5203.7604,N,00508.3168,E,0.0525,57.787,110605,,*1E +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480803.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.965,"epx":13.815,"epy":10.613,"epv":23.000,"track":57.7866,"speed":0.027,"climb":0.026,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,45,24,43,294,48*78 +{"class":"SKY","tag":"MID4","time":1118480802.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":45,"used":true},{"PRN":24,"el":43,"az":294,"ss":48,"used":true}]} +$GPGGA,090644,5203.7604,N,00508.3168,E,1,08,1.80,34.98,M,46.772,M,,*7A +$GPRMC,090644,A,5203.7604,N,00508.3168,E,0.0544,53.946,110605,,*19 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480804.998,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":34.983,"epx":13.815,"epy":10.613,"epv":23.000,"track":53.9462,"speed":0.028,"climb":0.025,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,43,02,13,316,00,01,49,069,47*70 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480803.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":43,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090645,5203.7604,N,00508.3168,E,1,08,1.80,35.00,M,46.772,M,,*7B +$GPRMC,090645,A,5203.7604,N,00508.3168,E,0.0467,53.835,110605,,*1D +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480805.998,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":35.001,"epx":13.815,"epy":10.613,"epv":23.000,"track":53.8351,"speed":0.024,"climb":0.024,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,44*7D +$GPGSV,3,2,12,13,34,231,00,07,35,297,44,02,13,316,00,01,49,069,47*77 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480804.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":44,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":44,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090646,5203.7604,N,00508.3168,E,1,08,1.80,35.02,M,46.772,M,,*7A +$GPRMC,090646,A,5203.7604,N,00508.3168,E,0.0486,56.661,110605,,*1B +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480806.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":35.017,"epx":13.815,"epy":10.613,"epv":23.000,"track":56.6610,"speed":0.025,"climb":0.023,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,44,02,13,316,00,01,49,069,47*77 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,45,24,43,294,47*77 +{"class":"SKY","tag":"MID4","time":1118480805.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":44,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":45,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090647,5203.7604,N,00508.3168,E,1,08,1.80,35.03,M,46.772,M,,*7A +$GPRMC,090647,A,5203.7604,N,00508.3168,E,0.0583,56.423,110605,,*1A +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480807.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":35.032,"epx":13.815,"epy":10.613,"epv":23.000,"track":56.4233,"speed":0.030,"climb":0.028,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,63,142,47,23,22,187,45,20,69,250,45*7C +$GPGSV,3,2,12,13,34,231,00,07,35,297,44,02,13,316,00,01,49,069,47*77 +$GPGSV,3,3,12,27,46,082,00,14,18,040,47,25,18,090,44,24,43,294,47*76 +{"class":"SKY","tag":"MID4","time":1118480806.990,"xdop":0.92,"ydop":0.71,"vdop":1.78,"tdop":1.29,"hdop":1.16,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":63,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":250,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":35,"az":297,"ss":44,"used":true},{"PRN":2,"el":13,"az":316,"ss":0,"used":false},{"PRN":1,"el":49,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":82,"ss":0,"used":false},{"PRN":14,"el":18,"az":40,"ss":47,"used":true},{"PRN":25,"el":18,"az":90,"ss":44,"used":true},{"PRN":24,"el":43,"az":294,"ss":47,"used":true}]} +$GPGGA,090648,5203.7604,N,00508.3168,E,1,08,1.80,35.05,M,46.772,M,,*73 +$GPRMC,090648,A,5203.7604,N,00508.3168,E,0.0544,53.197,110605,,*11 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480808.999,"ept":0.005,"lat":52.062673502,"lon":5.138613239,"alt":35.052,"epx":13.815,"epy":10.613,"epv":23.000,"track":53.1973,"speed":0.028,"climb":0.026,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,62,142,47,23,22,187,45,20,69,252,45*7F +$GPGSV,3,2,12,13,34,231,00,07,36,297,44,02,14,316,00,01,48,069,47*72 +$GPGSV,3,3,12,27,46,081,00,14,17,039,47,25,19,090,44,24,44,294,47*72 +{"class":"SKY","tag":"MID4","time":1118480807.990,"xdop":0.90,"ydop":0.71,"vdop":1.80,"tdop":1.29,"hdop":1.15,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":62,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":252,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":36,"az":297,"ss":44,"used":true},{"PRN":2,"el":14,"az":316,"ss":0,"used":false},{"PRN":1,"el":48,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":81,"ss":0,"used":false},{"PRN":14,"el":17,"az":39,"ss":47,"used":true},{"PRN":25,"el":19,"az":90,"ss":44,"used":true},{"PRN":24,"el":44,"az":294,"ss":47,"used":true}]} +$GPGGA,090649,5203.7604,N,00508.3168,E,1,08,1.80,35.07,M,46.772,M,,*70 +$GPRMC,090649,A,5203.7604,N,00508.3168,E,0.0525,50.564,110605,,*1C +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480809.999,"ept":0.005,"lat":52.062673502,"lon":5.138612666,"alt":35.068,"epx":13.533,"epy":10.581,"epv":23.000,"track":50.5642,"speed":0.027,"climb":0.024,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,62,142,47,23,22,187,45,20,69,252,45*7F +$GPGSV,3,2,12,13,34,231,00,07,36,297,45,02,14,316,00,01,48,069,47*73 +$GPGSV,3,3,12,27,46,081,00,14,17,039,47,25,19,090,44,24,44,294,47*72 +{"class":"SKY","tag":"MID4","time":1118480808.990,"xdop":0.90,"ydop":0.71,"vdop":1.80,"tdop":1.29,"hdop":1.15,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":62,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":252,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":36,"az":297,"ss":45,"used":true},{"PRN":2,"el":14,"az":316,"ss":0,"used":false},{"PRN":1,"el":48,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":81,"ss":0,"used":false},{"PRN":14,"el":17,"az":39,"ss":47,"used":true},{"PRN":25,"el":19,"az":90,"ss":44,"used":true},{"PRN":24,"el":44,"az":294,"ss":47,"used":true}]} +$GPGGA,090650,5203.7604,N,00508.3168,E,1,08,1.80,35.08,M,46.772,M,,*77 +$GPRMC,090650,A,5203.7604,N,00508.3168,E,0.0564,54.515,110605,,*13 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480810.999,"ept":0.005,"lat":52.062672929,"lon":5.138612666,"alt":35.084,"epx":13.533,"epy":10.581,"epv":23.000,"track":54.5150,"speed":0.029,"climb":0.026,"mode":3} +$GPGSV,3,1,12,04,51,189,00,11,62,142,47,23,22,187,45,20,69,252,45*7F +$GPGSV,3,2,12,13,34,231,00,07,36,297,44,02,14,316,00,01,48,069,47*72 +$GPGSV,3,3,12,27,46,081,00,14,17,039,47,25,19,090,44,24,44,294,47*72 +{"class":"SKY","tag":"MID4","time":1118480809.990,"xdop":0.90,"ydop":0.71,"vdop":1.80,"tdop":1.29,"hdop":1.15,"gdop":2.49,"pdop":2.13,"satellites":[{"PRN":4,"el":51,"az":189,"ss":0,"used":false},{"PRN":11,"el":62,"az":142,"ss":47,"used":true},{"PRN":23,"el":22,"az":187,"ss":45,"used":true},{"PRN":20,"el":69,"az":252,"ss":45,"used":true},{"PRN":13,"el":34,"az":231,"ss":0,"used":false},{"PRN":7,"el":36,"az":297,"ss":44,"used":true},{"PRN":2,"el":14,"az":316,"ss":0,"used":false},{"PRN":1,"el":48,"az":69,"ss":47,"used":true},{"PRN":27,"el":46,"az":81,"ss":0,"used":false},{"PRN":14,"el":17,"az":39,"ss":47,"used":true},{"PRN":25,"el":19,"az":90,"ss":44,"used":true},{"PRN":24,"el":44,"az":294,"ss":47,"used":true}]} +$GPGGA,090651,5203.7604,N,00508.3168,E,1,08,1.80,35.10,M,46.772,M,,*7F +$GPRMC,090651,A,5203.7604,N,00508.3168,E,0.0544,53.714,110605,,*14 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.8,1.8,1.0*32 +{"class":"TPV","tag":"MID98","time":1118480811.999,"ept":0.005,"lat":52.062672929,"lon":5.138612666,"alt":35.101,"epx":13.533,"epy":10.581,"epv":23.000,"track":53.7143,"speed":0.028,"climb":0.028,"mode":3} diff --git a/test/daemon/venus634lp.log b/test/daemon/venus634lp.log new file mode 100644 index 0000000..170d3d9 --- /dev/null +++ b/test/daemon/venus634lp.log @@ -0,0 +1,727 @@ +# Name: Venus634LP +# Submitted-by: Viktar Palstsiuk +# 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 0000000..61e61c4 Binary files /dev/null and b/test/daemon/zodiac.log differ diff --git a/test/daemon/zodiac.log.chk b/test/daemon/zodiac.log.chk new file mode 100644 index 0000000..c0b9b2b --- /dev/null +++ b/test/daemon/zodiac.log.chk @@ -0,0 +1,126 @@ +$GPGGA,204220,5203.7576,N,00508.3123,E,1,08,,8.23,M,47.120,M,0.91,W*13 +$GPRMC,204220,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*23 +$GPGSA,A,3,,,,,,,,,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695340.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.230,"track":0.0000,"speed":0.000,"climb":-0.010,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695353.000} +$GPGGA,204221,5203.7576,N,00508.3123,E,1,08,,8.23,M,47.120,M,0.91,W*12 +$GPRMC,204221,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*22 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695341.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.230,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695354.000} +$GPGGA,204222,5203.7576,N,00508.3123,E,1,08,,8.20,M,47.120,M,0.91,W*12 +$GPRMC,204222,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*21 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695342.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.200,"track":0.0000,"speed":0.000,"climb":-0.020,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695355.000} +$GPGGA,204223,5203.7576,N,00508.3123,E,1,08,,8.28,M,47.120,M,0.91,W*1B +$GPRMC,204223,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*20 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695343.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.280,"track":0.0000,"speed":0.000,"climb":0.050,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695356.000} +$GPGGA,204224,5203.7576,N,00508.3123,E,1,08,,8.27,M,47.120,M,0.91,W*13 +$GPRMC,204224,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*27 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695344.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.270,"track":0.0000,"speed":0.000,"climb":0.010,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695357.000} +$GPGGA,204225,5203.7576,N,00508.3123,E,1,08,,8.26,M,47.120,M,0.91,W*13 +$GPRMC,204225,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*26 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695345.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.260,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695358.000} +$GPGGA,204226,5203.7576,N,00508.3123,E,1,08,,8.29,M,47.120,M,0.91,W*1F +$GPRMC,204226,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*25 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695346.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.290,"track":0.0000,"speed":0.000,"climb":0.030,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695359.000} +$GPGGA,204227,5203.7576,N,00508.3123,E,1,08,,8.28,M,47.120,M,0.91,W*1F +$GPRMC,204227,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*24 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695347.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.280,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695360.000} +$GPGGA,204228,5203.7576,N,00508.3123,E,1,08,,8.29,M,47.120,M,0.91,W*11 +$GPRMC,204228,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*2B +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695348.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.290,"track":0.0000,"speed":0.000,"climb":0.010,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695361.000} +$GPGGA,204229,5203.7576,N,00508.3123,E,1,08,,8.28,M,47.120,M,0.91,W*11 +$GPRMC,204229,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*2A +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695349.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.280,"track":0.0000,"speed":0.000,"climb":-0.010,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695362.000} +$GPGGA,204230,5203.7576,N,00508.3123,E,1,08,,8.32,M,47.120,M,0.91,W*12 +$GPRMC,204230,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*22 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695350.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.320,"track":0.0000,"speed":0.000,"climb":0.040,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695363.000} +$GPGGA,204231,5203.7576,N,00508.3123,E,1,08,,8.33,M,47.120,M,0.91,W*12 +$GPRMC,204231,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*23 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695351.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.330,"track":0.0000,"speed":0.000,"climb":0.030,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695364.000} +$GPGGA,204232,5203.7576,N,00508.3123,E,1,08,,8.31,M,47.120,M,0.91,W*13 +$GPRMC,204232,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*20 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695352.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.310,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695365.000} +$GPGGA,204233,5203.7576,N,00508.3123,E,1,08,,8.27,M,47.120,M,0.91,W*15 +$GPRMC,204233,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*21 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695353.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.270,"track":0.0000,"speed":0.000,"climb":-0.020,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695366.000} +$GPGGA,204234,5203.7576,N,00508.3123,E,1,08,,8.29,M,47.120,M,0.91,W*1C +$GPRMC,204234,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*26 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695354.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.290,"track":0.0000,"speed":0.000,"climb":0.020,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695367.000} +$GPGGA,204235,5203.7576,N,00508.3123,E,1,08,,8.27,M,47.120,M,0.91,W*13 +$GPRMC,204235,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*27 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695355.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.270,"track":0.0000,"speed":0.000,"climb":-0.010,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695368.000} +$GPGGA,204236,5203.7576,N,00508.3123,E,1,08,,8.26,M,47.120,M,0.91,W*11 +$GPRMC,204236,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*24 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695356.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.260,"track":0.0000,"speed":0.000,"climb":-0.010,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695369.000} +$GPGGA,204237,5203.7576,N,00508.3123,E,1,08,,8.25,M,47.120,M,0.91,W*13 +$GPRMC,204237,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*25 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695357.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.250,"track":0.0000,"speed":0.000,"climb":0.000,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695370.000} +$GPGGA,204238,5203.7576,N,00508.3123,E,1,08,,8.20,M,47.120,M,0.91,W*19 +$GPRMC,204238,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*2A +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695358.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.200,"track":0.0000,"speed":0.000,"climb":-0.030,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695371.000} +$GPGGA,204239,5203.7576,N,00508.3123,E,1,08,,8.18,M,47.120,M,0.91,W*13 +$GPRMC,204239,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*2B +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695359.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.180,"track":0.0000,"speed":0.000,"climb":-0.030,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695372.000} +$GPGGA,204240,5203.7576,N,00508.3123,E,1,08,,8.19,M,47.120,M,0.91,W*1C +$GPRMC,204240,A,5203.7576,N,00508.3123,E,0.0000,0.000,130605,,*25 +$GPGSA,A,3,00,00,00,00,00,00,00,00,,,,,0.0,0.0,0.0*32 +{"class":"TPV","tag":"1000","time":1118695360.000,"ept":0.005,"lat":52.062625946,"lon":5.138537608,"alt":8.190,"track":0.0000,"speed":0.000,"climb":-0.010,"mode":3} +$PRWIZCH,01,2,05,7,04,7,14,7,02,0,07,7,30,7,18,6,24,7,09,7,00,0,22,7*4C +{"class":"SKY","tag":"1002","time":1118695373.000} diff --git a/test/earthmate b/test/earthmate new file mode 100644 index 0000000..67102a0 Binary files /dev/null and b/test/earthmate differ 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()