Falling through the cracks: why GPSD sometimes bogarts non-GPS devices
<p>In a recent Google+ comment, H. Peter Anvin grumped about GPSD using &#8220;braindead heuristics&#8221; to determine which USB devices it should sniff as possible GPses when it gets a hotplug notification saying that one has connected.  I was going to reply in a comment there, but the explanation ran too long for that.</p>
<p>Short version: yes, GPSD will very occasionally sniff at a device that is none of its business. We&#8217;re stuck in a bad place because of deficiencies in the USB standard, But it doesn&#8217;t happen often, and all the alternative behaviors I&#8217;ve been able to imagine would be worse in very obvious ways. Detailed explanation follows.</p>
<p><span id="more-4319"></span></p>
<p>USB devices are supposed to present a &#8220;device class&#8221; number that clues in the host system what kind of thing it is and how to talk to it.  In an ideal world, there would be a &#8220;GPS&#8221; device class which every GPS would present, and GPSD would cheerfully ignore anything that didn&#8217;t present it, and all would be gladness and joy.</p>
<p>We don&#8217;t live in that world.  Look at the <a href="http://www.usb.org/developers/defined_class">list of USB device classes</a> and notice that none of them is &#8220;GPS&#8221;.  Lacking any defined GPS class, the standard tells vendors that GPSes have to sit in the stupid corners labelled &#8220;00h&#8221; and &#8220;FFh&#8221;.  Along with every other USB devices type lacking an assigned class number, including in particular serial-to-USB adapter chips.</p>
<p>You may recall from some of my previous rants that your basic bog-standard USB GPS consists of a GPS chip shipping data over TTL-level RS232 lines to a serial-to-USB adapter chip. And that&#8217;s the root of GPSD&#8217;s problem right there. GPSD will never mess with your mouse or your mass storage but here&#8217;s no way that a USB GPS is distinguishable from some random other device that happens to be lurking behind a serial-to-USB adapter &#8211; it&#8217;s classes 00h/FFh all the way down.</p>
<p>So GPSD goes to the next level and watches for the specific Vendor-ID/Product IDs of serial-to-USB adapters that usually mean aha that&#8217;s a GPS. The most common VID/PID combination is 067b:2303  which is a Prolific Logic 2303; GPSD also recognizes nearly a dozen other specific VID/PID pairs mostly corresponding to various serial-to-USB adapter chips.</p>
<p>And 99% of the time &#8220;that&#8217;s a GPS&#8221; is exactly what these VID/PID pairs do in fact mean; for end users, anyway.  The exceptions are things like Arduino prototyping boards that will only ever be hooked up by a tiny minority of geeks like&#8230;H. Peter Anvin.  Who will grumble.</p>
<p>This sucks in a minor way, but watcha gonna do?  With this behavior. GPSD has very nice autoconfiguration in almost all cases &#8211; you plug in the GPS, hotplug wakes up the daemon, it autobauds and autoconfigures, and location data magically appears on port 2947 without the user having had to hand-tweak a blessed thing. This is good!</p>
<p>Unfortunately, the only way to prevent GPSD from occasionally sniffing at a device that turns out not to be a GPS would be to disable hotplug startup and require users to manually launch GPSD when they want to run it and know what their device inventory is.  This would end the muttering from people like H. Peter Anvin, but at the cost of requiring hundreds of thousands of bewildered end-users to hand-lunch GPSD and remember details like device names, rather than having things Just Work.</p>
<p>This would not, in my view, be an acceptable tradeoff.  This is one time I&#8217;m afraid I have to tell the hard core to live with the occasional glitch; greatest good for the greatest number and all that.  Even adding a GPS class to the USB standard wouldn&#8217;t solve the problem at this point &#8211; too many GPSes already fielded, and many of the vendors are such sketchy low-margin operations that it&#8217;s not clear they&#8217;d add the production step to do the right thing even if it were available.</p>
<p>UPDATE: Several commenters had the usual Unix-programmer reaction: just add a config switch! They&#8217;re not thinking the problem through; no config switch can solve enough cases to be worth the freight.  </p>
<p>One very common suggestion whenever this comes up is a blacklist option for particular VID/PID pairs, like &#8211;no-probe=067b:2303.   The trouble with this is that there are too many different devices using so few different USB-to-serial adapters, and this option would only be useful when you have multiple class 00/FF devices using <em>different</em> VID/PID pairs. In particular it&#8217;s quite likely that your GPS and your serial-port adapter dongle will <em>both</em> be using a PL2303, so blacklisting by VID/PID will make both invisible.</p>
<p>Another common but futile suggestion is blacklisting by device path.  USB device-path assignments aren&#8217;t stable in the presence of hotplugging, enough said.</p>
<p>Not only isn&#8217;t there enough information for autoconfiguration to work perfectly, the same missing information makes it (so far) impossible to specify a config option that I judge to be than a feel-good gesture or wishful thinking.</p>
<p>Also, people looking at this problem often jump to the conclusion that the failure cases are much more frequent and dangerous than they actually are. GPSD typically is <em>not</em> sending config strings to random devices it hasn&#8217;t identified as GPSes yet; it&#8217;s just sniffing data, and only immediately after a hotplug event.  The worst case is that another class 00/FF loses a second&#8217;s worth of data, not that it gets accidentally told to self-destruct or something.</p>
<p>UPDATE2: Another safeguard, which I had forgotten writing, is that under Linux GPSD uses a sadly non-portable hack which determines if a device has been opened by another process and if so ignores it.  So the only way gpsd even <em>reads</em> from an unknown device is when to other application has claimed it.</p>
