[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gpsd-dev] Getting the driver-switching logic right

From: Eric S. Raymond
Subject: [gpsd-dev] Getting the driver-switching logic right
Date: Sat, 12 Oct 2013 09:07:29 -0400 (EDT)

The rules for when we change the active device driver have been in flux
since 3.9. This note is an attempt to think through the problem and
develop a better, more stable set of rules.  Criticism and suggestions
for improvement will be welcomed.

We need to solve this before we can ship 3.10.

Whenever we see a packet, there are three decisions we may have to make:

1) Should we change the selected driver?  This changes gpsd's theory of what
   device it's dealing with, and in particular what control capabilities
   the device has.

2) In gpsd, how should we parse the packet?  This is not the same
   decision as whether to change drivers, because (as we'll see below)
   some devices output more than one packet format.  Thus, some
   drivers need to handle more than one.

3) In gpsmon, which monitor object should we use to dump the packet fields?

The background conditions of the problem are these:

Almost all incoming packet types can be identified with
effectively perfect reliability, because they have distinguishing
header bytes, a length field, and a checksum.  The set of these
well-behaved packet types includes the NMEA0183, SiRF, uBlox, Zodiac,
Evermore, InCore, Navcom, Superstar II, and Geostar GPS protocols. It
also includes RTCM3, and (through a strange sort of black magic)
RTCM2. Finally, it includes AIVDM.

Garmin binary, Evermore binary, and TSIP binary packets are the
problem cases for packet type recognition.  They can be confused with
each other, because they use the same DLE-based framing and don't have
checksums.  The packet getter uses knowledge about ranges of legal
values at particular offsets to disambiguate among these three.  From
the point of view of the rest of the code, they're nearly as perfectly
distinguishable from each other and the checksummed protocols as the
checksummed protocols are from each other - "almost" because we have
had one report of the TSIP driver very occasionally grabbing SiRF
packets that we had to work around by ensuring the check for SiRF was
done first.

There is a one-to-one correspondence between packet types and device
drivers *except* when the packet type is plain NMEA. Several different
drivers process the NMEA packet type.

A plain NMEA packet can be generic NMEA, or it can be from a device
that speaks an enhanced NMEA superset (like the San Jose Navigation FV-18
or Ashtech/Thales/Magellan-Professional devices), or it can be emitted
by a device that natively speaks some binary packet format but has an NMEA 
textual mode (SiRF, uBlox, Evermore, and Zodiac are like this).

So, how do we make sense of this mess? 

I was originally going to add a long explanation of the rules we used in 3.9
and earlier, and how they've changed twice since that release.  But there's
not a lot of point in that.  Instead I'm going to reason out how it ought
to work, inviting other developers to criticize and correct the logic.

The most important thing we want from our transition rules is that if gpsd
has recognized a device type with command capabilities (the ability to, for
example, change mode or baud rate), we *never* want to lose the information
that these command string are valid for the device. 

The following table classifies all the drivers we have by what sorts of
command strings they have and whether their packet type is uniquely
recognizable.  It's the output of gpsd -L:

                                Generic NMEA
                                Delorme TripMate
                                Delorme EarthMate (pre-2003, Zodiac chipset)
                                Furuno Electric GH-79L4
n                               Garmin NMEA
                c               MTK-3301
                                OceanServer Digital Compass OS5000
                                San Jose Navigation FV18
        b                       True North
                c               Jackson Labs Fury
                        *       AIVDM
n       b       c       *       EverMore binary
n                       *       Garmin Serial binary
                        *       Garmin USB binary
n       b               *       GeoStar binary
                        *       iTalk binary
n       b               *       Oncore binary
        b               *       Navcom binary
n       b               *       SiRF binary
n       b               *       SuperStarII binary
n       b               *       Trimble TSIP binary
n       b       c       *       uBlox UBX binary
        b               *       Zodiac binary
                        *       RTCM104V2
                        *       RTCM104V3
                        *       Garmin Simple Text
                        *       JSON slave driver

The capabilities are as follows

n: mode switch, b: speed switch, c: rate switch, *: non-NMEA packet type.

Here are the rules that I think will work.  Criticism invited:

1. When you see a unique packet type for a driver with control
   capabilities, switch to that driver.  Covers EverMore binary, Garmin
   serial binary, Geostar binary, oncore binary, Navcom binary, SiRF
   binary, SuperStar II binary, Trimble TSIP binary, uBlox UBX binary,
   and Zodiac binary.

2. When you see a unique packet type with no control capabilities,
   pass the packet to the packet parser for that driver but *do not
   switch drivers* (that is, retain whatever driver type is currently
   selected).  This covers AIVDM, Garmin USB binary, iTalk binary,
   RTCM2, RTCM3, Garmin Simple Text, and the JSON slave driver.

3. Keep a fallback pointer to the last NMEA driver that identified
   itself (e.g. via a trigger string or probe response). The default
   value of this fallback is Generic NMEA.  When you see an NMEA
   packet, pass it to your fallback driver.  *Never switch drivers in
   this case.* This rule assumes that enhanced NMEA drevices (Ashtech, Delorme
   Tripmate and Earthmate, Furuno Electric GH-79L4, Garmin NMEA,
   MTK-3301, OceanServer Digital Compass OS500, San Jose Navigation
   FV180, True North, Jackson Labs Fury) identify themselves early after

As for how to tell what monitor object to use in JSON, I think the
rules for that need to look like this:

1. If the packet is non-NMEA, then: If there is a monitor object with a driver 
   pointer for which the driver packet type matches, use that.  Otherwise
   just display packets.

2. Otherwise the packet is NMEA. Use the monitor object using the fallback
   driver pointer, if there is one. Otherwise
   just display packets.

Please try to think through the combinations and tell me if there is a
case you think these rules get wrong or won't cover.
                <a href="";>Eric S. Raymond</a>

Where rights secured by the Constitution are involved, there can be no
rule making or legislation which would abrogate them.
        -- Miranda vs. Arizona, 384 US 436 p. 491

reply via email to

[Prev in Thread] Current Thread [Next in Thread]