cleanup specfile for packaging
[profile/ivi/gpsd.git] / driver_garmin.c
1 /*
2  * This file contains two drivers for Garmin receivers and some code
3  * shared by both drivers.
4  *
5  * One driver "garmin_usb_binary" handles the Garmin binary packet
6  * format supported by the USB Garmins tested with the Garmin 18 and
7  * other models.  (There is also "garmin_usb_binary_old".)  These are ONLY
8  * for USB devices reporting as: 091e:0003.
9  *
10  * The other driver "garmin_ser_binary" is for Garmin receivers via a
11  * serial port, whether or not one uses a USB/serial adaptor or a real
12  * serial port.  These receivers provide adequate NMEA support, so it
13  * often makes sense to just put them into NMEA mode.
14  *
15  * On Linux, USB Garmins (091e:0003) need the Linux garmin_gps driver and
16  * will not function without it.  On other operating systems, it is clear
17  * garmin_usb_binary_old does not work since it requires the Linux
18  * garmin_gps module.
19  *
20  * This code has been tested and at least at one time is known to work on
21  * big- and little-endian CPUs and 32 and 64 bit cpu modes.
22  *
23  *
24  * Documentation for the Garmin protocols can be found via
25  *   http://www.garmin.com/support/commProtocol.html
26  * The file IOSDK.zip contains IntfSpec.pdf, which describes the
27  * protocol in terms of Application, Link, and Physical.  This
28  * identical file is also available at:
29  *   http://www.garmin.com/support/pdf/iop_spec.pdf
30  * An older version of iop_spec.pdf that describes only Serial Binary
31  * is available at:
32  *   http://vancouver-webpages.com/pub/peter/iop_spec.pdf
33  * Information about the GPS 18
34  *   http://www.garmin.com/manuals/425_TechnicalSpecification.pdf
35  *
36  * There is one physical link protocol for serial which uses DLE/ETX
37  * framing.  There is another physical protocol for USB which relies
38  * on the packetization intrinstic to USB bulk pipes.
39  *
40  * There are several link protocols; all devices implement L000.
41  * There are then product-specific protocols; most devices implement
42  * L001.  Link protocols are the same and carried over either Physical
43  * protocol.
44  *
45  * Application protocols are named A000 and then with different
46  * 3-digit numbres.  They are carried over Link protocols.
47  *
48  * Thus, much of the higher-level code dealing the data formats is
49  * shared between USB Binary and Serial Binary.
50  *
51  * This code is partly from the Garmin IOSDK and partly from the
52  * sample code in the Linux garmin_gps driver.
53  *
54  * bad code by: Gary E. Miller <gem@rellim.com>
55  *
56  * -D 3 = packet trace
57  * -D 4 = packet details
58  * -D 5 = more packet details
59  * -D 6 = very excessive details
60  *
61  * limitations:
62  *
63  * do not have from garmin:
64  *      pdop
65  *      hdop
66  *      vdop
67  *      magnetic variation
68  *
69  * known bugs:
70  *      hangs in the fread loop instead of keeping state and returning.
71  *
72  * TODO:
73  *
74  *      ?? Add probe function for Serial Binary to start PVT output.
75  *
76  * This file is Copyright (c) 2010 by the GPSD project
77  * BSD terms apply: see the file COPYING in the distribution root for details.
78  */
79
80 #define __USE_POSIX199309 1
81 #include <sys/types.h>
82 #include <time.h>               // for nanosleep()
83
84 #include <stdio.h>
85 #include <stdlib.h>
86 #include <math.h>
87
88 #include <string.h>
89 #ifndef S_SPLINT_S
90 #include <unistd.h>
91 #endif /* S_SPLINT_S */
92 #include <errno.h>
93 #include <inttypes.h>
94
95 #include "gpsd_config.h"
96 #if defined (HAVE_SYS_SELECT_H)
97 #include <sys/select.h>
98 #endif
99
100 #if defined(HAVE_STRINGS_H)
101 #include <strings.h>
102 #endif
103
104 #if defined(HAVE_LIBUSB)
105 #include <libusb.h>
106 #endif
107
108 #include "gpsd.h"
109 #include "gps.h"
110
111 #ifdef GARMIN_ENABLE
112
113 #define USE_RMD 0
114
115 /* Used in Serial Physical Layer */
116 #define ETX 0x03
117 #define ACK 0x06
118 #define DLE 0x10
119 #define NAK 0x15
120
121 #define GARMIN_LAYERID_TRANSPORT (uint8_t)  0
122 #define GARMIN_LAYERID_APPL      (uint32_t) 20
123 // Linux Garmin USB driver layer-id to use for some control mechanisms
124 #define GARMIN_LAYERID_PRIVATE  0x01106E4B
125
126 // packet ids used in private layer
127 #define PRIV_PKTID_SET_DEBUG    1
128 #define PRIV_PKTID_SET_MODE     2
129 #define PRIV_PKTID_INFO_REQ     3
130 #define PRIV_PKTID_INFO_RESP    4
131 #define PRIV_PKTID_RESET_REQ    5
132 #define PRIV_PKTID_SET_DEF_MODE 6
133
134 #define MODE_NATIVE       0
135 #define MODE_GARMIN_SERIAL   1
136
137 #define GARMIN_PKTID_TRANSPORT_START_SESSION_REQ 5
138 #define GARMIN_PKTID_TRANSPORT_START_SESSION_RESP 6
139
140 #define GARMIN_PKTID_PROTOCOL_ARRAY     253
141 #define GARMIN_PKTID_PRODUCT_RQST       254
142 #define GARMIN_PKTID_PRODUCT_DATA       255
143 /* 0x29 ')' */
144 #define GARMIN_PKTID_RMD41_DATA  41
145 /* 0x33 '3' */
146 #define GARMIN_PKTID_PVT_DATA      51
147 /* 0x33 '4' */
148 #define GARMIN_PKTID_RMD_DATA      52
149 /* 0x72 'r' */
150 #define GARMIN_PKTID_SAT_DATA      114
151
152 #define GARMIN_PKTID_L001_XFER_CMPLT     12
153 #define GARMIN_PKTID_L001_COMMAND_DATA   10
154 #define GARMIN_PKTID_L001_DATE_TIME_DATA 14
155 #define GARMIN_PKTID_L001_RECORDS       27
156 #define GARMIN_PKTID_L001_WPT_DATA       35
157
158 #define CMND_ABORT                       0
159 #define CMND_START_PVT_DATA              49
160 #define CMND_STOP_PVT_DATA               50
161 #define CMND_START_RM_DATA               110
162
163 #define MAX_BUFFER_SIZE 4096
164
165 #define GARMIN_CHANNELS 12
166
167 // something magic about 64, garmin driver will not return more than
168 // 64 at a time.  If you read less than 64 bytes the next read will
169 // just get the last of the 64 byte buffer.
170 #define ASYNC_DATA_SIZE 64
171
172
173 #pragma pack(1)
174 // This is the data format of the satellite data from the garmin USB
175 typedef struct
176 {
177     uint8_t svid;
178     int16_t snr;                // 0 - 0xffff
179     uint8_t elev;
180     uint16_t azmth;
181     uint8_t status;             // bit 0, has ephemeris, 1, has diff correction
182     // bit 2 used in solution
183     // bit 3??
184 } cpo_sat_data;
185
186 /* Garmin D800_Pvt_Datetype_Type */
187 /* packet type:  GARMIN_PKTID_PVT_DATA   52 */
188 /* This is the data format of the position data from the garmin USB */
189 typedef struct
190 {
191     float alt;                  /* altitude above WGS 84 (meters) */
192     float epe;                  /* estimated position error, 2 sigma (meters)  */
193     float eph;                  /* epe, but horizontal only (meters) */
194     float epv;                  /* epe but vertical only (meters ) */
195     int16_t fix;                /* 0 - failed integrity check
196                                  * 1 - invalid or unavailable fix
197                                  * 2 - 2D
198                                  * 3 - 3D
199                                  * 4 - 2D Diff
200                                  * 5 - 3D Diff
201                                  */
202     double gps_tow;             /* gps time of week (seconds) */
203     double lat;                 /* ->latitude (radians) */
204     double lon;                 /* ->longitude (radians) */
205     float lon_vel;              /* velocity east (meters/second) */
206     float lat_vel;              /* velocity north (meters/second) */
207     float alt_vel;              /* velocity up (meters/sec) */
208     // Garmin GPS25 uses pkt_id 0x28 and does not output the
209     // next 3 items
210     float msl_hght;             /* height of WGS 84 above MSL (meters) */
211     int16_t leap_sec;           /* diff between GPS and UTC (seconds) */
212     int32_t grmn_days;          /* days from UTC December 31st, 1989 to the
213                                  * beginning of the current week */
214 } cpo_pvt_data;
215
216 typedef struct
217 {
218     uint32_t cycles;
219     double pr;
220     uint16_t phase;
221     int8_t slp_dtct;
222     uint8_t snr_dbhz;
223     uint8_t svid;
224     int8_t valid;
225 } cpo_rcv_sv_data;
226
227 /* packet type:  GARMIN_PKTID_RMD_DATA   53 */
228 /* seems identical to the packet id 0x29 from the Garmin GPS 25 */
229 typedef struct
230 {
231     double rcvr_tow;
232     int16_t rcvr_wn;
233     cpo_rcv_sv_data sv[GARMIN_CHANNELS];
234 } cpo_rcv_data;
235
236 // This is the packet format to/from the Garmin USB
237 typedef struct
238 {
239     uint8_t mPacketType;
240     uint8_t mReserved1;
241     uint16_t mReserved2;
242     uint16_t mPacketId;
243     uint16_t mReserved3;
244     uint32_t mDataSize;
245     union
246     {
247         int8_t chars[MAX_BUFFER_SIZE];
248         uint8_t uchars[MAX_BUFFER_SIZE];
249         cpo_pvt_data pvt;
250         cpo_sat_data sats;
251     } mData;
252 } Packet_t;
253
254 // useful funcs to read/write ints
255 //  floats and doubles are Intel order only...
256 static inline void set_int16(uint8_t * buf, uint32_t value)
257 {
258     buf[0] = (uint8_t) (0x0FF & value);
259     buf[1] = (uint8_t) (0x0FF & (value >> 8));
260 }
261
262 static inline void set_int32(uint8_t * buf, uint32_t value)
263 {
264     buf[0] = (uint8_t) (0x0FF & value);
265     buf[1] = (uint8_t) (0x0FF & (value >> 8));
266     buf[2] = (uint8_t) (0x0FF & (value >> 16));
267     buf[3] = (uint8_t) (0x0FF & (value >> 24));
268 }
269
270 static inline uint16_t get_uint16(const uint8_t * buf)
271 {
272     return (uint16_t) (0xFF & buf[0])
273         | ((uint16_t) (0xFF & buf[1]) << 8);
274 }
275
276 static inline uint32_t get_int32(const uint8_t * buf)
277 {
278     return (uint32_t) (0xFF & buf[0])
279         | ((uint32_t) (0xFF & buf[1]) << 8)
280         | ((uint32_t) (0xFF & buf[2]) << 16)
281         | ((uint32_t) (0xFF & buf[3]) << 24);
282 }
283
284 // convert radians to degrees
285 static inline double radtodeg(double rad)
286 {
287     return (double)(rad * RAD_2_DEG);
288 }
289
290 static gps_mask_t PrintSERPacket(struct gps_device_t *session,
291                                  unsigned char pkt_id, int pkt_len,
292                                  unsigned char *buf);
293 static gps_mask_t PrintUSBPacket(struct gps_device_t *session,
294                                  Packet_t * pkt);
295
296 gps_mask_t PrintSERPacket(struct gps_device_t *session, unsigned char pkt_id,
297                           int pkt_len, unsigned char *buf)
298 {
299
300     gps_mask_t mask = 0;
301     int i = 0, j = 0;
302     uint16_t prod_id = 0;
303     uint16_t ver = 0;
304     int maj_ver;
305     int min_ver;
306     time_t time_l = 0;
307     double track;
308     char msg_buf[512] = "";
309     char *msg = NULL;
310     cpo_sat_data *sats = NULL;
311     cpo_pvt_data *pvt = NULL;
312     cpo_rcv_data *rmd = NULL;
313
314     gpsd_report(LOG_IO, "Garmin: PrintSERPacket(, %#02x, %#02x, )\n", pkt_id,
315                 pkt_len);
316
317     session->cycle_end_reliable = true;
318
319     switch (pkt_id) {
320     case ACK:
321         gpsd_report(LOG_PROG, "Garmin: ACK\n");
322         break;
323     case NAK:
324         gpsd_report(LOG_PROG, "Garmin: NAK\n");
325         break;
326     case GARMIN_PKTID_L001_COMMAND_DATA:
327         prod_id = get_uint16((uint8_t *) buf);
328         /*@ -branchstate @*/
329         switch (prod_id) {
330         case CMND_ABORT:
331             msg = "Abort current xfer";
332             break;
333         case CMND_START_PVT_DATA:
334             msg = "Start Xmit PVT data";
335             break;
336         case CMND_STOP_PVT_DATA:
337             msg = "Stop Xmit PVT data";
338             break;
339         case CMND_START_RM_DATA:
340             msg = "Start RMD data";
341             break;
342         default:
343             (void)snprintf(msg_buf, sizeof(msg_buf), "Unknown: %u",
344                            (unsigned int)prod_id);
345             msg = msg_buf;
346             break;
347         }
348         /*@ +branchstate @*/
349         gpsd_report(LOG_PROG, "Garmin: Appl, Command Data: %s\n", msg);
350         break;
351     case GARMIN_PKTID_PRODUCT_RQST:
352         gpsd_report(LOG_PROG, "Garmin: Appl, Product Data req\n");
353         break;
354     case GARMIN_PKTID_PRODUCT_DATA:
355         prod_id = get_uint16((uint8_t *) buf);
356         ver = get_uint16((uint8_t *) & buf[2]);
357         maj_ver = (int)(ver / 100);
358         min_ver = (int)(ver - (maj_ver * 100));
359         gpsd_report(LOG_PROG, "Garmin: Appl, Product Data, sz: %d\n",
360                     pkt_len);
361         (void)snprintf(session->subtype, sizeof(session->subtype),
362                        "%d: %d.%02d", (int)prod_id, maj_ver, min_ver);
363         gpsd_report(LOG_INF, "Garmin: Product ID: %d, SoftVer: %d.%02d\n",
364                     prod_id, maj_ver, min_ver);
365         gpsd_report(LOG_INF, "Garmin: Product Desc: %s\n", &buf[4]);
366         mask |= DEVICEID_IS;
367         gpsd_report(LOG_DATA, "Garmin: PRODUCT_DATA: subtype=%s mask=%s\n",
368                     session->subtype, gpsd_maskdump(mask));
369         break;
370     case GARMIN_PKTID_PVT_DATA:
371         gpsd_report(LOG_PROG, "Garmin: Appl, PVT Data Sz: %d\n", pkt_len);
372
373         pvt = (cpo_pvt_data *) buf;
374
375         // 631065600, unix seconds for 31 Dec 1989 Zulu
376         time_l = (time_t) (631065600 + (pvt->grmn_days * 86400));
377         // TODO, convert grmn_days to context->gps_week
378         time_l -= pvt->leap_sec;
379         session->context->leap_seconds = pvt->leap_sec;
380         session->context->valid = LEAP_SECOND_VALID;
381         // gps_tow is always like x.999 or x.998 so just round it
382         time_l += (time_t) round(pvt->gps_tow);
383         session->context->gps_tow = pvt->gps_tow;
384         session->newdata.time = (double)time_l;
385         gpsd_report(LOG_PROG, "Garmin: time_l: %ld\n", (long int)time_l);
386
387         session->newdata.latitude = radtodeg(pvt->lat);
388         /* sanity check the lat */
389         if (90.0 < session->newdata.latitude) {
390             session->newdata.latitude = 90.0;
391             gpsd_report(LOG_INF, "Garmin: ERROR: Latitude overrange\n");
392         } else if (-90.0 > session->newdata.latitude) {
393             session->newdata.latitude = -90.0;
394             gpsd_report(LOG_INF,
395                         "Garmin: ERROR: Latitude negative overrange\n");
396         }
397         session->newdata.longitude = radtodeg(pvt->lon);
398         /* sanity check the lon */
399         if (180.0 < session->newdata.longitude) {
400             session->newdata.longitude = 180.0;
401             gpsd_report(LOG_INF, "Garmin: ERROR: Longitude overrange\n");
402         } else if (-180.0 > session->newdata.longitude) {
403             session->newdata.longitude = -180.0;
404             gpsd_report(LOG_INF,
405                         "Garmin: ERROR: Longitude negative overrange\n");
406         }
407         // altitude over WGS84 converted to MSL
408         session->newdata.altitude = pvt->alt + pvt->msl_hght;
409
410         // geoid separation from WGS 84
411         // gpsd sign is opposite of garmin sign
412         session->gpsdata.separation = -pvt->msl_hght;
413
414         // Estimated position error in meters.
415         // We follow the advice at <http://gpsinformation.net/main/errors.htm>.
416         // If this assumption changes here, it should also change in
417         // nmea_parse.c where we analyze PGRME.
418         session->gpsdata.epe = pvt->epe * (GPSD_CONFIDENCE / CEP50_SIGMA);
419         /* eph is a circular error, sqrt(epx**2 + epy**2) */
420         session->newdata.epx = session->newdata.epy =
421             pvt->eph * (1 / sqrt(2)) * (GPSD_CONFIDENCE / CEP50_SIGMA);
422         session->newdata.epv = pvt->epv * (GPSD_CONFIDENCE / CEP50_SIGMA);
423
424         // convert lat/lon to directionless speed
425         session->newdata.speed = hypot(pvt->lon_vel, pvt->lat_vel);
426
427         // keep climb in meters/sec
428         session->newdata.climb = pvt->alt_vel;
429
430         track = atan2(pvt->lon_vel, pvt->lat_vel);
431         if (track < 0) {
432             track += 2 * GPS_PI;
433         }
434         session->newdata.track = radtodeg(track);
435
436         switch (pvt->fix) {
437         case 0:
438         case 1:
439         default:
440             // no fix
441             session->gpsdata.status = STATUS_NO_FIX;
442             session->newdata.mode = MODE_NO_FIX;
443             break;
444         case 2:
445             // 2D fix
446             session->gpsdata.status = STATUS_FIX;
447             session->newdata.mode = MODE_2D;
448             break;
449         case 3:
450             // 3D fix
451             session->gpsdata.status = STATUS_FIX;
452             session->newdata.mode = MODE_3D;
453             break;
454         case 4:
455             // 2D Differential fix
456             session->gpsdata.status = STATUS_DGPS_FIX;
457             session->newdata.mode = MODE_2D;
458             break;
459         case 5:
460             // 3D differential fix
461             session->gpsdata.status = STATUS_DGPS_FIX;
462             session->newdata.mode = MODE_3D;
463             break;
464         }
465
466         gpsd_report(LOG_PROG, "Garmin: Appl, mode %d, status %d\n",
467                     session->newdata.mode, session->gpsdata.status);
468
469         gpsd_report(LOG_INF, "Garmin: UTC Time: %lf\n",
470                     session->newdata.time);
471         gpsd_report(LOG_INF,
472                     "Garmin: Geoid Separation (MSL-WGS84): from garmin %lf, calculated %lf\n",
473                     -pvt->msl_hght,
474                     wgs84_separation(session->newdata.latitude,
475                                      session->newdata.longitude));
476
477         gpsd_report(LOG_INF,
478                     "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",
479                     pvt->alt, pvt->epe, pvt->eph, pvt->epv, pvt->fix,
480                     pvt->gps_tow, session->newdata.latitude,
481                     session->newdata.longitude, pvt->lon_vel, pvt->lat_vel,
482                     pvt->alt_vel, pvt->msl_hght, pvt->leap_sec,
483                     pvt->grmn_days);
484
485         if (session->newdata.mode > MODE_NO_FIX) {
486             /* data only valid with a fix */
487             mask |=
488                 TIME_IS | LATLON_IS | ALTITUDE_IS | STATUS_IS | MODE_IS |
489                 SPEED_IS | TRACK_IS | CLIMB_IS | HERR_IS | VERR_IS | PERR_IS |
490                 CLEAR_IS | REPORT_IS;
491         }
492         gpsd_report(LOG_DATA,
493                     "Garmin: PVT_DATA: time=%.2f, lat=%.2f lon=%.2f "
494                     "speed=%.2f track=%.2f climb=%.2f "
495                     "epx=%.2f epy=%.2f epv=%.2f "
496                     "mode=%d status=%d mask=%s\n",
497                     session->newdata.time,
498                     session->newdata.latitude,
499                     session->newdata.longitude,
500                     session->newdata.speed,
501                     session->newdata.track,
502                     session->newdata.climb,
503                     session->newdata.epx,
504                     session->newdata.epy,
505                     session->newdata.epv,
506                     session->newdata.mode,
507                     session->gpsdata.status, gpsd_maskdump(mask));
508         break;
509     case GARMIN_PKTID_RMD_DATA:
510     case GARMIN_PKTID_RMD41_DATA:
511         rmd = (cpo_rcv_data *) buf;
512         gpsd_report(LOG_IO, "Garmin: PVT RMD Data Sz: %d\n", pkt_len);
513         gpsd_report(LOG_PROG, "Garmin: PVT RMD rcvr_tow: %f, rcvr_wn: %d\n",
514                     rmd->rcvr_tow, rmd->rcvr_wn);
515         for (i = 0; i < GARMIN_CHANNELS; i++) {
516             gpsd_report(LOG_INF,
517                         "Garmin: PVT RMD Sat: %3u, cycles: %9u, pr: %16.6f, "
518                         "phase: %7.3f, slp_dtct: %3s, snr: %3u, Valid: %3s\n",
519                         rmd->sv[i].svid + 1, rmd->sv[i].cycles, rmd->sv[i].pr,
520                         (rmd->sv[i].phase * 360.0) / 2048.0,
521                         rmd->sv[i].slp_dtct != '\0' ? "Yes" : "No",
522                         rmd->sv[i].snr_dbhz,
523                         rmd->sv[i].valid != '\0' ? "Yes" : "No");
524         }
525         break;
526
527     case GARMIN_PKTID_SAT_DATA:
528         gpsd_report(LOG_PROG, "Garmin: SAT Data Sz: %d\n", pkt_len);
529         sats = (cpo_sat_data *) buf;
530
531         session->gpsdata.satellites_used = 0;
532         memset(session->gpsdata.used, 0, sizeof(session->gpsdata.used));
533         gpsd_zero_satellites(&session->gpsdata);
534         for (i = 0, j = 0; i < GARMIN_CHANNELS; i++, sats++) {
535             gpsd_report(LOG_INF,
536                         "Garmin:   Sat %3d, snr: %5d, elev: %2d, Azmth: %3d, Stat: %x\n",
537                         sats->svid, sats->snr, sats->elev, sats->azmth,
538                         sats->status);
539
540             if (255 == (int)sats->svid) {
541                 // Garmin uses 255 for empty
542                 // gpsd uses 0 for empty
543                 continue;
544             }
545
546             session->gpsdata.PRN[j] = (int)sats->svid;
547             session->gpsdata.azimuth[j] = (int)sats->azmth;
548             session->gpsdata.elevation[j] = (int)sats->elev;
549             // Garmin does not document this.  snr is in dB*100
550             // Known, but not seen satellites have a dB value of -1*100
551             session->gpsdata.ss[j] = (float)(sats->snr / 100.0);
552             if (session->gpsdata.ss[j] < 0.0) {
553                 session->gpsdata.ss[j] = 0.0;
554             }
555             // FIX-ME: Garmin documents this, but Daniel Dorau
556             // <daniel.dorau@gmx.de> says the behavior on his GPSMap60CSX
557             // doesn't match it.
558             if ((uint8_t) 0 != (sats->status & 4)) {
559                 // used in solution?
560                 session->gpsdata.used[session->gpsdata.satellites_used++]
561                     = (int)sats->svid;
562             }
563             session->gpsdata.satellites_visible++;
564             j++;
565
566         }
567         session->gpsdata.skyview_time = NAN;
568         mask |= SATELLITE_IS | USED_IS;
569         gpsd_report(LOG_DATA,
570                     "Garmin: SAT_DATA: visible=%d used=%d mask=%s\n",
571                     session->gpsdata.satellites_visible,
572                     session->gpsdata.satellites_used, gpsd_maskdump(mask));
573         break;
574     case GARMIN_PKTID_PROTOCOL_ARRAY:
575         // this packet is never requested, it just comes, in some case
576         // after a GARMIN_PKTID_PRODUCT_RQST
577         gpsd_report(LOG_INF, "Garmin: Appl, Product Capability, sz: %d\n",
578                     pkt_len);
579         for (i = 0; i < pkt_len; i += 3) {
580             gpsd_report(LOG_INF, "Garmin:   %c%03d\n", buf[i],
581                         get_uint16((uint8_t *) & buf[i + 1]));
582         }
583         break;
584     default:
585         gpsd_report(LOG_WARN,
586                     "Garmin: Unknown packet id: %#02x, Sz: %#02x, pkt:%s\n",
587                     pkt_id, pkt_len, gpsd_hexdump_wrapper(buf,
588                                                           (size_t) pkt_len,
589                                                           LOG_WARN));
590         break;
591     }
592     gpsd_report(LOG_IO, "Garmin: PrintSERPacket(, %#02x, %#02x, ) = %s\n",
593                 pkt_id, pkt_len, gpsd_maskdump(mask));
594     return mask;
595 }
596
597
598 /*@ -branchstate @*/
599 // For debugging, decodes and prints some known packets.
600 static gps_mask_t PrintUSBPacket(struct gps_device_t *session, Packet_t * pkt)
601 {
602     gps_mask_t mask = 0;
603     int maj_ver;
604     int min_ver;
605     uint32_t mode = 0;
606     uint16_t prod_id = 0;
607     uint32_t veri = 0;
608     uint32_t serial;
609     uint32_t mDataSize = get_int32((uint8_t *) & pkt->mDataSize);
610
611 //
612     uint8_t *buffer = (uint8_t *) pkt;
613
614     gpsd_report(LOG_PROG, "Garmin: PrintUSBPacket()\n");
615 // gem
616     if (DLE == pkt->mPacketType) {
617         gpsd_report(LOG_PROG, "Garmin: really a SER packet!\n");
618         return PrintSERPacket(session,
619                               (unsigned char)buffer[1],
620                               (int)buffer[2], (unsigned char *)(buffer + 3));
621     }
622 // gem
623     if (4096 < mDataSize) {
624         gpsd_report(LOG_WARN, "Garmin: bogus packet, size too large=%d\n",
625                     mDataSize);
626         return 0;
627     }
628
629     (void)snprintf(session->gpsdata.tag, sizeof(session->gpsdata.tag), "%u",
630                    (unsigned int)pkt->mPacketType);
631     switch (pkt->mPacketType) {
632     case GARMIN_LAYERID_TRANSPORT:
633         /* Garmin USB layer specific */
634         switch (pkt->mPacketId) {
635         case GARMIN_PKTID_TRANSPORT_START_SESSION_REQ:
636             gpsd_report(LOG_PROG, "Garmin: Transport, Start Session req\n");
637             break;
638         case GARMIN_PKTID_TRANSPORT_START_SESSION_RESP:
639             mode = get_int32(&pkt->mData.uchars[0]);
640             gpsd_report(LOG_PROG,
641                         "Garmin: Transport, Start Session resp, unit: 0x%x\n",
642                         mode);
643             break;
644         default:
645             gpsd_report(LOG_PROG,
646                         "Garmin: Transport, Packet: Type %d %d %d, ID: %d, Sz: %d\n",
647                         pkt->mPacketType, pkt->mReserved1, pkt->mReserved2,
648                         pkt->mPacketId, mDataSize);
649             break;
650         }
651         break;
652     case GARMIN_LAYERID_APPL:
653         /* raw data transport, shared with Garmin Serial Driver */
654
655         mask = PrintSERPacket(session,
656                               (unsigned char)pkt->mPacketId,
657                               (int)mDataSize,
658                               (unsigned char *)pkt->mData.uchars);
659         break;
660     case 75:
661         // private, garmin USB kernel driver specific
662         switch (pkt->mPacketId) {
663         case PRIV_PKTID_SET_MODE:
664             prod_id = get_uint16(&pkt->mData.uchars[0]);
665             gpsd_report(LOG_PROG, "Garmin: Private, Set Mode: %d\n", prod_id);
666             break;
667         case PRIV_PKTID_INFO_REQ:
668             gpsd_report(LOG_PROG, "Garmin: Private, ID: Info Req\n");
669             break;
670         case PRIV_PKTID_INFO_RESP:
671             veri = get_int32(pkt->mData.uchars);
672             maj_ver = (int)(veri >> 16);
673             min_ver = (int)(veri & 0xffff);
674             mode = get_int32(&pkt->mData.uchars[4]);
675             serial = get_int32(&pkt->mData.uchars[8]);
676             gpsd_report(LOG_PROG, "Garmin: Private, ID: Info Resp\n");
677             gpsd_report(LOG_INF,
678                         "Garmin: USB Driver found, Version %d.%d, Mode: %d, GPS Serial# %u\n",
679                         maj_ver, min_ver, mode, serial);
680             break;
681         default:
682             gpsd_report(LOG_PROG, "Garmin: Private, Packet: ID: %d, Sz: %d\n",
683                         pkt->mPacketId, mDataSize);
684             break;
685         }
686         break;
687     default:
688         gpsd_report(LOG_PROG,
689                     "Garmin: Packet: Type %d %d %d, ID: %d, Sz: %d\n",
690                     pkt->mPacketType, pkt->mReserved1, pkt->mReserved2,
691                     pkt->mPacketId, mDataSize);
692         break;
693     }
694
695     return mask;
696 }
697
698 /*@ +branchstate @*/
699
700
701 /* build and send a packet w/ USB protocol */
702 static void Build_Send_USB_Packet(struct gps_device_t *session,
703                                   uint32_t layer_id, uint32_t pkt_id,
704                                   uint32_t length, uint32_t data)
705 {
706     uint8_t *buffer = (uint8_t *) session->driver.garmin.Buffer;
707     Packet_t *thePacket = (Packet_t *) buffer;
708     ssize_t theBytesReturned = 0;
709     ssize_t theBytesToWrite = 12 + (ssize_t) length;
710
711     set_int32(buffer, layer_id);
712     set_int32(buffer + 4, pkt_id);
713     set_int32(buffer + 8, length);
714     if (2 == length) {
715         set_int16(buffer + 12, data);
716     } else if (4 == length) {
717         set_int32(buffer + 12, data);
718     }
719 #if 0
720     gpsd_report(LOG_IO, "Garmin: SendPacket(), writing %d bytes: %s\n",
721                 theBytesToWrite,
722                 gpsd_hexdump_wrapper(thePacket, theBytesToWrite, LOG_IO));
723 #endif
724     (void)PrintUSBPacket(session, thePacket);
725
726     theBytesReturned = gpsd_write(session, thePacket,
727                                   (size_t) theBytesToWrite);
728     gpsd_report(LOG_IO, "Garmin: SendPacket(), wrote %zd bytes\n",
729                 theBytesReturned);
730
731     // Garmin says:
732     // If the packet size was an exact multiple of the USB packet
733     // size, we must make a final write call with no data
734
735     // as a practical matter no known packets are 64 bytes long so
736     // this is untested
737
738     // So here goes just in case
739     if (0 == (theBytesToWrite % ASYNC_DATA_SIZE)) {
740         char *n = "";
741         theBytesReturned = gpsd_write(session, &n, 0);
742     }
743 }
744
745 /* build and send a packet in serial protocol */
746 /* layer_id unused */
747 // FIX-ME: This should go through the common message buffer someday
748 static void Build_Send_SER_Packet(struct gps_device_t *session,
749                                   uint32_t layer_id UNUSED, uint32_t pkt_id,
750                                   uint32_t length, uint32_t data)
751 {
752     uint8_t *buffer = (uint8_t *) session->driver.garmin.Buffer;
753     uint8_t *buffer0 = buffer;
754     Packet_t *thePacket = (Packet_t *) buffer;
755     ssize_t theBytesReturned = 0;
756     ssize_t theBytesToWrite = 6 + (ssize_t) length;
757     uint8_t chksum = 0;
758
759     *buffer++ = (uint8_t) DLE;
760     *buffer++ = (uint8_t) pkt_id;
761     chksum = pkt_id;
762     *buffer++ = (uint8_t) length;
763     chksum += length;
764     /* ??? What is this doing? */
765     if (2 == length) {
766         /* carefull!  no DLE stuffing here! */
767         set_int16(buffer, data);
768         chksum += buffer[0];
769         chksum += buffer[1];
770     } else if (4 == length) {
771         /* carefull!  no DLE stuffing here! */
772         set_int32(buffer, data);
773         chksum += buffer[0];
774         chksum += buffer[1];
775         chksum += buffer[2];
776         chksum += buffer[3];
777     }
778     /* ??? How is data copied to the buffer? */
779     buffer += length;
780
781     // Add checksum
782     *buffer++ = -chksum;
783     if (DLE == -chksum) {
784         /* stuff another DLE */
785         *buffer++ = (uint8_t) DLE;
786         theBytesToWrite++;
787     }
788     // Add DLE, ETX
789     *buffer++ = (uint8_t) DLE;
790     *buffer++ = (uint8_t) ETX;
791
792 #if 1
793     gpsd_report(LOG_IO, "Garmin: SendPacket(), writing %zd bytes: %s\n",
794                 theBytesToWrite,
795                 gpsd_hexdump_wrapper(thePacket, (size_t) theBytesToWrite,
796                                      LOG_IO));
797 #endif
798     (void)PrintSERPacket(session,
799                          (unsigned char)buffer0[1],
800                          (int)buffer0[2], (unsigned char *)(buffer0 + 3));
801
802     theBytesReturned = gpsd_write(session, thePacket,
803                                   (size_t) theBytesToWrite);
804     gpsd_report(LOG_IO, "Garmin: SendPacket(), wrote %zd bytes\n",
805                 theBytesReturned);
806
807 }
808
809 #if defined(HAVE_LIBUSB) || defined(S_SPLINT_S)
810 /*
811  * is_usb_device() - is a specified device USB matching given vendor/product?
812  *
813  * BUG: Doesn't actually match against path yet. Must finish this function
814  * by querying /sys/dev/char, either directly or using libudev. Greg KH
815  * assures this is possible, though he is vague about how.
816  *
817  * libudev: http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/
818  */
819 /*@-compdef -usedef@*/
820 static bool is_usb_device(const char *path UNUSED, int vendor, int product)
821 {
822     // discover devices
823     libusb_device **list;
824     ssize_t cnt;
825     ssize_t i = 0;
826     bool found = false;
827
828     gpsd_report(LOG_SHOUT, "attempting USB device enumeration.\n");
829     /*@i2@*/ libusb_init(NULL);
830
831     /*@-nullpass@*/
832     if ((cnt = libusb_get_device_list(NULL, &list)) < 0) {
833         gpsd_report(LOG_ERROR, "USB device list call failed.\n");
834         /*@i1@*/ libusb_exit(NULL);
835         return false;
836     }
837     /*@+nullpass@*/
838
839     for (i = 0; i < cnt; i++) {
840         struct libusb_device_descriptor desc;
841         libusb_device *dev = list[i];
842
843         int r = libusb_get_device_descriptor(dev, &desc);
844         if (r < 0) {
845             gpsd_report(LOG_ERROR,
846                         "USB descriptor fetch failed on device %zd.\n", i);
847             continue;
848         }
849
850         /* we can extract device descriptor data */
851         gpsd_report(LOG_SHOUT, "%04x:%04x (bus %d, device %d)\n",
852                     desc.idVendor, desc.idProduct,
853                     libusb_get_bus_number(dev),
854                     libusb_get_device_address(dev));
855
856         /* we match if vendor and product ID are right */
857         if (desc.idVendor == 0x91e && desc.idProduct == 3) {
858             found = true;
859             break;
860         }
861     }
862
863     gpsd_report(LOG_SHOUT, "vendor/product match with %04x:%04x %sfound\n",
864                 vendor, product, found ? "" : "not ");
865     libusb_free_device_list(list, 1);
866     /*@i1@*/ libusb_exit(NULL);
867     return found;
868 }
869
870 /*@-compdef -usedef@*/
871 #endif /* HAVE_LIBUSB || S_SPLINT_S */
872
873 /*
874  * garmin_usb_detect() - detect a Garmin USB device connected to ession fd.
875  *
876  * This is ONLY for USB devices reporting as: 091e:0003.
877  *
878  * This driver ONLY works in Linux and ONLY when the the garmin_gps kernel
879  * module is installed.
880  *
881  * This is only necessary because under Linux Garmin USB devices need a
882  * kernel module rather than being normal USB-serial devices.
883  *
884  * The actual wire protocol from the Garmin device is very strange. There
885  * are no delimiters.  End of packet is signaled by a zero-length read
886  * on the USB device, and start of packet is the next read.  You can't just
887  * ignore the zero reads and pass the data through - you'd never be able
888  * to tell where the packet boundaries are.
889  *
890  * The garmin_usb module's job is to grab the packet and frame it in
891  * DLEs (with DLE stuffing).  This makes the USB packets look as
892  * though they came from a regular Garmin *serial* device, which is how
893  * most of the processing for both types can be unified here.
894  *
895  * return 1 is device found
896  * return 0 if not
897  */
898 static bool garmin_usb_detect(struct gps_device_t *session)
899 {
900 #if defined(__linux__) || defined(S_SPLINT_S)
901     /*
902      * Only perform this check if we're looking at a USB-serial
903      * device.  This prevents drivers for attached serial GPSes
904      * fronm being rudely elbowed aside by this one if they happen
905      * to be trying to coexist with the Garmin.
906      */
907     if (session->sourcetype != source_usb)
908         return false;
909     else {
910 #ifdef HAVE_LIBUSB
911         if (!is_usb_device(session->gpsdata.dev.path, 0x091e, 0x0003))
912             return false;
913 #else
914         /*
915          * This is ONLY for USB devices reporting as: 091e:0003.
916          *
917          * Check that the garmin_gps driver is installed in the kernel
918          * and that an active USB device is using it.
919          *
920          * BUG: It does not yet check that the currect device is the one
921          * attached to the Garmin.  So if you have a Garmin and another
922          * USB gps this could be a problem.
923          *
924          * Return true if garmin_gps device found, false otherwise.
925          */
926         FILE *fp = NULL;
927         char buf[256];
928         bool ok = false;
929
930         /* check for garmin USB serial driver -- very Linux-specific */
931         if (access("/sys/module/garmin_gps", R_OK) != 0) {
932             gpsd_report(LOG_WARN,
933                         "Garmin: garmin_gps Linux USB module not active.\n");
934             return false;
935         }
936         /* check for a garmin_gps device in /proc
937          * if we can */
938         if (NULL != (fp = fopen("/proc/bus/usb/devices", "r"))) {
939
940             ok = false;
941             while (0 != fgets(buf, (int)sizeof(buf), fp)) {
942                 if (strstr(buf, "garmin_gps")) {
943                     ok = true;
944                     break;
945                 }
946             }
947             (void)fclose(fp);
948             if (!ok) {
949                 // no device using garmin_gps now
950                 gpsd_report(LOG_WARN,
951                             "Garmin: garmin_gps not in /proc/bus/usb/devices.\n");
952                 gpsd_report(LOG_WARN,
953                             "Garmin: garmin_gps driver present, but not in use\n");
954                 return false;
955             }
956         } else {
957             gpsd_report(LOG_WARN,
958                         "Garmin: Can't open /proc/bus/usb/devices, will try anyway\n");
959         }
960 #endif /* HAVE_LIBUSB */
961
962         if (!gpsd_set_raw(session)) {
963             gpsd_report(LOG_ERROR,
964                         "Garmin: garmin_usb_detect: error changing port attributes: %s\n",
965                         strerror(errno));
966             return false;
967         }
968 #ifdef __UNUSED
969         Packet_t *thePacket = NULL;
970         uint8_t *buffer = NULL;
971         /* reset the buffer and buffer length */
972         memset(session->driver.garmin.Buffer, 0,
973                sizeof(session->driver.garmin.Buffer));
974         session->driver.garmin.BufferLen = 0;
975
976         if (sizeof(session->driver.garmin.Buffer) < sizeof(Packet_t)) {
977             gpsd_report(LOG_ERROR,
978                         "Garmin: garmin_usb_detect: Compile error, garmin.Buffer too small.\n",
979                         strerror(errno));
980             return false;
981         }
982
983         buffer = (uint8_t *) session->driver.garmin.Buffer;
984         thePacket = (Packet_t *) buffer;
985 #endif /* __UNUSED__ */
986
987         // set Mode 1, mode 0 is broken somewhere past 2.6.14
988         // but how?
989         gpsd_report(LOG_PROG, "Garmin: Set garmin_gps driver mode = 0\n");
990         Build_Send_USB_Packet(session, GARMIN_LAYERID_PRIVATE,
991                               PRIV_PKTID_SET_MODE, 4, MODE_GARMIN_SERIAL);
992         // expect no return packet !?
993
994         return true;
995     }
996 #else
997     return false;
998 #endif /* __linux__ || S_SPLINT_S */
999 }
1000
1001 static void garmin_event_hook(struct gps_device_t *session, event_t event)
1002 {
1003     /*
1004      * FIX-ME: It might not be necessary to call this on reactivate.
1005      * Experiment to see if the holds its settings through a close.
1006      */
1007     if (event == event_identified || event == event_reactivate) {
1008         // Tell the device to send product data
1009         gpsd_report(LOG_PROG, "Garmin: Get Product Data\n");
1010         Build_Send_SER_Packet(session, GARMIN_LAYERID_APPL,
1011                               GARMIN_PKTID_PRODUCT_RQST, 0, 0);
1012
1013         // turn on PVT data 49
1014         gpsd_report(LOG_PROG, "Garmin: Set to send reports every 1 second\n");
1015
1016         Build_Send_SER_Packet(session, GARMIN_LAYERID_APPL,
1017                               GARMIN_PKTID_L001_COMMAND_DATA, 2,
1018                               CMND_START_PVT_DATA);
1019
1020 #if USE_RMD
1021         // turn on RMD data 110
1022         gpsd_report(LOG_PROG, "Garmin: Set to send Raw sat data\n");
1023         Build_Send_SER_Packet(session, GARMIN_LAYERID_APPL,
1024                               GARMIN_PKTID_L001_COMMAND_DATA, 2,
1025                               CMND_START_RM_DATA);
1026 #endif
1027     }
1028     if (event == event_deactivate)
1029         /* FIX-ME: is any action needed, or is closing the port sufficient? */
1030         gpsd_report(LOG_PROG, "Garmin: garmin_close()\n");
1031 }
1032
1033 #define Send_ACK()    Build_Send_SER_Packet(session, 0, ACK, 0, 0)
1034 #define Send_NAK()    Build_Send_SER_Packet(session, 0, NAK, 0, 0)
1035
1036 /*@ +charint @*/
1037 gps_mask_t garmin_ser_parse(struct gps_device_t *session)
1038 {
1039     unsigned char *buf = session->packet.outbuffer;
1040     size_t len = session->packet.outbuflen;
1041     unsigned char data_buf[MAX_BUFFER_SIZE];
1042     unsigned char c;
1043     int i = 0;
1044     size_t n = 0;
1045     int data_index = 0;
1046     int got_dle = 0;
1047     unsigned char pkt_id = 0;
1048     unsigned char pkt_len = 0;
1049     unsigned char chksum = 0;
1050     gps_mask_t mask = 0;
1051
1052     gpsd_report(LOG_RAW, "Garmin: garmin_ser_parse()\n");
1053     if (6 > len) {
1054         /* WTF? */
1055         /* minimum packet; <DLE> [pkt id] [length=0] [chksum] <DLE> <STX> */
1056         Send_NAK();
1057         gpsd_report(LOG_RAW + 1, "Garmin: serial too short: %zd\n", len);
1058         return 0;
1059     }
1060     /* debug */
1061     for (i = 0; i < (int)len; i++) {
1062         gpsd_report(LOG_RAW + 1, "Garmin: Char: %#02x\n", buf[i]);
1063     }
1064
1065     if ('\x10' != buf[0]) {
1066         Send_NAK();
1067         gpsd_report(LOG_RAW + 1, "Garmin: buf[0] not DLE\n");
1068         return 0;
1069     }
1070     n = 1;
1071     pkt_id = buf[n++];
1072     chksum = pkt_id;
1073     if ('\x10' == pkt_id) {
1074         if ('\x10' != buf[n++]) {
1075             Send_NAK();
1076             gpsd_report(LOG_RAW + 1, "Garmin: Bad pkt_id %#02x\n", pkt_id);
1077             return 0;
1078         }
1079     }
1080
1081     pkt_len = buf[n++];
1082     chksum += pkt_len;
1083     if ('\x10' == pkt_len) {
1084         if ('\x10' != buf[n++]) {
1085             gpsd_report(LOG_RAW + 1, "Garmin: Bad pkt_len %#02x\n", pkt_len);
1086             Send_NAK();
1087             return 0;
1088         }
1089     }
1090     data_index = 0;
1091     for (i = 0; i < 256; i++) {
1092
1093         if ((int)pkt_len == data_index) {
1094             // got it all
1095             break;
1096         }
1097         if (len < n + i) {
1098             gpsd_report(LOG_RAW + 1, "Garmin: Packet too short %zd < %zd\n",
1099                         len, n + i);
1100             Send_NAK();
1101             return 0;
1102         }
1103         c = buf[n + i];
1104         if (got_dle) {
1105             got_dle = 0;
1106             if ('\x10' != c) {
1107                 Send_NAK();
1108                 gpsd_report(LOG_RAW + 1, "Garmin: Bad DLE %#02x\n", c);
1109                 return 0;
1110             }
1111         } else {
1112             chksum += c;
1113             data_buf[data_index++] = c;
1114             if ('\x10' == c) {
1115                 got_dle = 1;
1116             }
1117         }
1118     }
1119     /* get checksum */
1120     if (len < n + i) {
1121         Send_NAK();
1122         gpsd_report(LOG_RAW + 1,
1123                     "Garmin: No checksum, Packet too short %zd < %zd\n", len,
1124                     n + i);
1125         return 0;
1126     }
1127     c = buf[n + i++];
1128     chksum += c;
1129     /* get final DLE */
1130     if (len < n + i) {
1131         Send_NAK();
1132         gpsd_report(LOG_RAW + 1,
1133                     "Garmin: No final DLE, Packet too short %zd < %zd\n", len,
1134                     n + i);
1135         return 0;
1136     }
1137     c = buf[n + i++];
1138     if ('\x10' != c) {
1139         Send_NAK();
1140         gpsd_report(LOG_RAW + 1, "Garmin: Final DLE not DLE\n");
1141         return 0;
1142     }
1143     /* get final ETX */
1144     if (len < n + i) {
1145         Send_NAK();
1146         gpsd_report(LOG_RAW + 1,
1147                     "Garmin: No final ETX, Packet too short %zd < %zd\n", len,
1148                     n + i);
1149         return 0;
1150     }
1151     c = buf[n + i++];
1152     if ('\x03' != c) {
1153         Send_NAK();
1154         gpsd_report(LOG_RAW + 1, "Garmin: Final ETX not ETX\n");
1155         return 0;
1156     }
1157
1158     /* debug */
1159     /*@ -usedef -compdef @*/
1160     for (i = 0; i < data_index; i++) {
1161         gpsd_report(LOG_RAW + 1, "Garmin: Char: %#02x\n", data_buf[i]);
1162     }
1163
1164
1165     gpsd_report(LOG_IO,
1166                 "Garmin: garmin_ser_parse() Type: %#02x, Len: %#02x, chksum: %#02x\n",
1167                 pkt_id, pkt_len, chksum);
1168     mask = PrintSERPacket(session, pkt_id, pkt_len, data_buf);
1169
1170     // sending ACK too soon might hang the session
1171     // so send ACK last, after a pause
1172     (void)usleep(300);
1173     Send_ACK();
1174     /*@ +usedef +compdef @*/
1175     gpsd_report(LOG_IO, "Garmin: garmin_ser_parse( ) = %s\n",
1176                 gpsd_maskdump(mask));
1177     return mask;
1178 }
1179
1180 /*@ -charint @*/
1181
1182 #ifdef ALLOW_RECONFIGURE
1183 static void settle(void)
1184 {
1185     struct timespec delay, rem;
1186     /*@ -type -unrecog @*/
1187     memset(&delay, 0, sizeof(delay));
1188     delay.tv_sec = 0;
1189     delay.tv_nsec = 333000000L;
1190     nanosleep(&delay, &rem);
1191     /*@ +type +unrecog @*/
1192 }
1193
1194 static void garmin_switcher(struct gps_device_t *session, int mode)
1195 {
1196     if (mode == MODE_NMEA) {
1197         /*@ +charint @*/
1198         const char switcher[] =
1199             { 0x10, 0x0A, 0x02, 0x26, 0x00, 0xCE, 0x10, 0x03 };
1200         // Note hard-coded string length in the next line...
1201         int status = (int)gpsd_write(session, switcher, sizeof(switcher));
1202         /*@ -charint @*/
1203         if (status == (int)sizeof(switcher)) {
1204             gpsd_report(LOG_IO,
1205                         "Garmin: => GPS: turn off binary %02x %02x %02x... \n",
1206                         switcher[0], switcher[1], switcher[2]);
1207         } else {
1208             gpsd_report(LOG_ERROR, "Garmin: => GPS: FAILED\n");
1209         }
1210         settle();               // wait 333mS, essential!
1211
1212         /* once a sec, no binary, no averaging, NMEA 2.3, WAAS */
1213         (void)nmea_send(session, "$PGRMC1,1,1");
1214         //(void)nmea_send(fd, "$PGRMC1,1,1,1,,,,2,W,N");
1215         (void)nmea_send(session, "$PGRMI,,,,,,,R");
1216         settle();               // wait 333mS, essential!
1217     } else {
1218         (void)nmea_send(session, "$PGRMC1,1,2,1,,,,2,W,N");
1219         (void)nmea_send(session, "$PGRMI,,,,,,,R");
1220         settle();               // wait 333mS, essential!
1221     }
1222 }
1223 #endif /* ALLOW_RECONFIGURE */
1224
1225 #ifdef ALLOW_CONTROLSEND
1226 static ssize_t garmin_control_send(struct gps_device_t *session,
1227                                    char *buf, size_t buflen)
1228 /* not used by the daemon, it's for gpsctl and friends */
1229 {
1230     /*@ -mayaliasunique @*/
1231     session->msgbuflen = buflen;
1232     (void)memcpy(session->msgbuf, buf, buflen);
1233     return gpsd_write(session, session->msgbuf, session->msgbuflen);
1234     /*@ +mayaliasunique @*/
1235 }
1236 #endif /* ALLOW_CONTROLSEND */
1237
1238 #ifdef NTPSHM_ENABLE
1239 static double garmin_ntp_offset(struct gps_device_t *session)
1240 {
1241     if (session->sourcetype == source_usb) {
1242         return 0.035;           /* Garmin USB, expect +/- 40mS jitter */
1243     }
1244     /* only two sentences ships time */
1245     /* but the PVT data is always first */
1246     switch (session->gpsdata.dev.baudrate) {
1247     case 4800:
1248         return 0.430;           /* TBD */
1249     case 9600:
1250         return 0.430;           /* tested 12Arp10 */
1251     case 19200:
1252         return 0.430;           /* TBD */
1253     case 38400:
1254         return 0.430;           /* TBD */
1255     }
1256     return 0.430;               /* WTF?  WAG */
1257 }
1258 #endif /* NTPSHM_ENABLE */
1259
1260 /* this is everything we export */
1261 #ifdef __UNUSED__
1262 static int GetPacket(struct gps_device_t *session);
1263 //-----------------------------------------------------------------------------
1264 // Gets a single packet.
1265 // this is odd, the garmin usb driver will only return 64 bytes, or less
1266 // at a time, no matter what you ask for.
1267 //
1268 // is you ask for less than 64 bytes then the next packet will include
1269 // just the remaining bytes of the last 64 byte packet.
1270 //
1271 // Reading a packet of length Zero, or less than 64, signals the end of
1272 // the entire packet.
1273 //
1274 // The Garmin sample WinXX code also assumes the same behavior, so
1275 // maybe it is something in the USB protocol.
1276 //
1277 // Return: 0 = got a good packet
1278 //       -1 = error
1279 //       1 = got partial packet
1280 static int GetPacket(struct gps_device_t *session)
1281 {
1282     struct timespec delay, rem;
1283     int cnt = 0;
1284     // int x = 0; // for debug dump
1285
1286     memset(session->driver.garmin.Buffer, 0, sizeof(Packet_t));
1287     memset(&delay, 0, sizeof(delay));
1288     session->driver.garmin.BufferLen = 0;
1289     session->packet.outbuflen = 0;
1290
1291     gpsd_report(LOG_IO, "Garmin: GetPacket()\n");
1292
1293     for (cnt = 0; cnt < 10; cnt++) {
1294         size_t pkt_size;
1295         // Read async data until the driver returns less than the
1296         // max async data size, which signifies the end of a packet
1297
1298         // not optimal, but given the speed and packet nature of
1299         // the USB not too bad for a start
1300         ssize_t theBytesReturned = 0;
1301         uint8_t *buf = (uint8_t *) session->driver.garmin.Buffer;
1302         Packet_t *thePacket = (Packet_t *) buf;
1303
1304         theBytesReturned =
1305             read(session->gpsdata.gps_fd,
1306                  buf + session->driver.garmin.BufferLen, ASYNC_DATA_SIZE);
1307         // zero byte returned is a legal value and denotes the end of a
1308         // binary packet.
1309         if (0 > theBytesReturned) {
1310             // read error...
1311             // or EAGAIN, but O_NONBLOCK is never set
1312             gpsd_report(LOG_ERROR,
1313                         "Garmin: GetPacket() read error=%d, errno=%d\n",
1314                         theBytesReturned, errno);
1315             continue;
1316         }
1317         gpsd_report(LOG_RAW, "Garmin: got %d bytes\n", theBytesReturned);
1318 #if 1
1319         gpsd_report(LOG_IO, "Garmin: getPacket(), got %d bytes: %s\n",
1320                     theBytesReturned,
1321                     gpsd_hexdump_wrapper(thePacket, theBytesReturned,
1322                                          LOG_IO));
1323 #endif
1324
1325         session->driver.garmin.BufferLen += theBytesReturned;
1326         if (256 <= session->driver.garmin.BufferLen) {
1327             // really bad read error...
1328             gpsd_report(LOG_ERROR,
1329                         "Garmin: GetPacket() packet too long, %ld > 255 !\n",
1330                         session->driver.garmin.BufferLen);
1331             session->driver.garmin.BufferLen = 0;
1332             break;
1333         }
1334         pkt_size = 12 + get_int32((uint8_t *) & thePacket->mDataSize);
1335         if (12 <= session->driver.garmin.BufferLen) {
1336             // have enough data to check packet size
1337             if (session->driver.garmin.BufferLen > pkt_size) {
1338                 // wrong amount of data in buffer
1339                 gpsd_report(LOG_ERROR,
1340                             "Garmin: GetPacket() packet size wrong! Packet: %ld, s/b %ld\n",
1341                             session->driver.garmin.BufferLen, pkt_size);
1342                 session->driver.garmin.BufferLen = 0;
1343                 break;
1344             }
1345         }
1346         if (64 > theBytesReturned) {
1347             // zero length, or short, read is a flag for got the whole packet
1348             break;
1349         }
1350
1351
1352         /*@ ignore @*/
1353         delay.tv_sec = 0;
1354         delay.tv_nsec = 3330000L;
1355         while (nanosleep(&delay, &rem) == -1)
1356             continue;
1357         /*@ end @*/
1358     }
1359     // dump the individual bytes, debug only
1360     // for ( x = 0; x < session->driver.garmin.BufferLen; x++ ) {
1361     // gpsd_report(LOG_RAW+1, "Garmin: p[%d] = %x\n", x, session->driver.garmin.Buffer[x]);
1362     // }
1363     if (10 <= cnt) {
1364         gpsd_report(LOG_ERROR,
1365                     "Garmin: GetPacket() packet too long or too slow!\n");
1366         return -1;
1367     }
1368
1369     gpsd_report(LOG_RAW, "Garmin: GotPacket() sz=%d \n",
1370                 session->driver.garmin.BufferLen);
1371     session->packet.outbuflen = session->driver.garmin.BufferLen;
1372     return 0;
1373 }
1374
1375 static gps_mask_t garmin_usb_parse(struct gps_device_t *session)
1376 {
1377     gpsd_report(LOG_PROG, "Garmin: garmin_usb_parse()\n");
1378     return PrintUSBPacket(session,
1379                           (Packet_t *) session->driver.garmin.Buffer);
1380 }
1381
1382 static ssize_t garmin_get_packet(struct gps_device_t *session)
1383 {
1384     return (ssize_t) (0 == GetPacket(session) ? 1 : 0);
1385 }
1386
1387 /* *INDENT-OFF* */
1388 const struct gps_type_t garmin_usb_binary_old =
1389 {
1390     .type_name      = "Garmin USB binary",      /* full name of type */
1391     .packet_type    = GARMIN_PACKET;    /* associated lexer packet type */
1392     .trigger        = NULL,             /* no trigger, it has a probe */
1393     .channels       = GARMIN_CHANNELS,  /* consumer-grade GPS */
1394     .probe_detect   = garmin_usb_detect,/* how to detect at startup time */
1395     .get_packet     = garmin_get_packet,/* how to grab a packet */
1396     .parse_packet   = garmin_usb_parse, /* parse message packets */
1397     .rtcm_writer    = NULL,             /* don't send DGPS corrections */
1398     .event_hook     = garmin_event_hook,/* lifetime event handler */
1399 #ifdef ALLOW_RECONFIGURE
1400     .speed_switcher = NULL,             /* no speed switcher */
1401     .mode_switcher  = NULL,             /* no mode switcher */
1402     .rate_switcher  = NULL,             /* no sample-rate switcher */
1403     .min_cycle      = 1,                /* not relevant, no rate switch */
1404 #endif /* ALLOW_RECONFIGURE */
1405 #ifdef ALLOW_CONTROLSEND
1406     .control_send   = garmin_control_send,      /* send raw bytes */
1407 #endif /* ALLOW_CONTROLSEND */
1408 #ifdef NTPSHM_ENABLE
1409     .ntp_offset     = garmin_ntp_offset,
1410 #endif /* NTPSHM_ ENABLE */
1411 };
1412 /* *INDENT-ON* */
1413 #endif /* __UNUSED__ */
1414
1415 /* *INDENT-OFF* */
1416 const struct gps_type_t garmin_usb_binary =
1417 {
1418     .type_name      = "Garmin USB binary",      /* full name of type */
1419     .packet_type    = GARMIN_PACKET,    /* associated lexer packet type */
1420     .trigger        = NULL,             /* no trigger, it has a probe */
1421     .channels       = GARMIN_CHANNELS,  /* consumer-grade GPS */
1422     .probe_detect   = garmin_usb_detect,/* how to detect at startup time */
1423     .get_packet     = generic_get,      /* how to grab a packet */
1424     .parse_packet   = garmin_ser_parse, /* parse message packets */
1425     .rtcm_writer    = NULL,             /* don't send DGPS corrections */
1426     .event_hook     = garmin_event_hook,/* lifetime ebent handler */
1427 #ifdef ALLOW_RECONFIGURE
1428     .speed_switcher = NULL,             /* no speed switcher */
1429     .mode_switcher  = NULL,             /* Garmin USB Binary has no NMEA */
1430     .rate_switcher  = NULL,             /* no sample-rate switcher */
1431     .min_cycle      = 1,                /* not relevant, no rate switch */
1432 #endif /* ALLOW_RECONFIGURE */
1433 #ifdef ALLOW_CONTROLSEND
1434     .control_send   = garmin_control_send,      /* send raw bytes */
1435 #endif /* ALLOW_CONTROLSEND */
1436 #ifdef NTPSHM_ENABLE
1437     .ntp_offset     = garmin_ntp_offset,
1438 #endif /* NTPSHM_ ENABLE */
1439 };
1440 /* *INDENT-ON* */
1441
1442 /* *INDENT-OFF* */
1443 const struct gps_type_t garmin_ser_binary =
1444 {
1445     .type_name      = "Garmin Serial binary",   /* full name of type */
1446     .packet_type    = GARMIN_PACKET,    /* associated lexer packet type */
1447     .trigger        = NULL,             /* no trigger, it has a probe */
1448     .channels       = GARMIN_CHANNELS,  /* consumer-grade GPS */
1449     .probe_detect   = NULL,             /* how to detect at startup time */
1450     .get_packet     = generic_get,       /* how to grab a packet */
1451     .parse_packet   = garmin_ser_parse, /* parse message packets */
1452     .rtcm_writer    = NULL,             /* don't send DGPS corrections */
1453     .event_hook     = NULL,             /* lifetime event handler */
1454 #ifdef ALLOW_RECONFIGURE
1455     .speed_switcher = NULL,             /* no speed switcher */
1456     .mode_switcher  = garmin_switcher,  /* how to change modes */
1457     .rate_switcher  = NULL,             /* no sample-rate switcher */
1458     .min_cycle      = 1,                /* not relevant, no rate switch */
1459 #endif /* ALLOW_RECONFIGURE */
1460 #ifdef ALLOW_CONTROLSEND
1461     .control_send   = garmin_control_send,      /* send raw bytes */
1462 #endif /* ALLOW_CONTROLSEND */
1463 #ifdef NTPSHM_ENABLE
1464     .ntp_offset     = garmin_ntp_offset,
1465 #endif /* NTPSHM_ ENABLE */
1466 };
1467 /* *INDENT-ON* */
1468
1469 #endif /* GARMIN_ENABLE */