]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - contrib/ntp/ntpd/refclock_gpsdjson.c
Fix multiple vulnerabilities in ntp. [SA-18:02.ntp]
[FreeBSD/releng/10.3.git] / contrib / ntp / ntpd / refclock_gpsdjson.c
1 /*
2  * refclock_gpsdjson.c - clock driver as GPSD JSON client
3  *      Juergen Perlinger (perlinger@ntp.org)
4  *      Feb 11, 2014 for the NTP project.
5  *      The contents of 'html/copyright.html' apply.
6  *
7  *      Heavily inspired by refclock_nmea.c
8  *
9  * Special thanks to Gary Miller and Hal Murray for their comments and
10  * ideas.
11  *
12  * Note: This will currently NOT work with Windows due to some
13  * limitations:
14  *
15  *  - There is no GPSD for Windows. (There is an unofficial port to
16  *    cygwin, but Windows is not officially supported.)
17  *
18  *  - To work properly, this driver needs PPS and TPV/TOFF sentences
19  *    from GPSD. I don't see how the cygwin port should deal with the
20  *    PPS signal.
21  *
22  *  - The device name matching must be done in a different way for
23  *    Windows. (Can be done with COMxx matching, as done for NMEA.)
24  *
25  * Apart from those minor hickups, once GPSD has been fully ported to
26  * Windows, there's no reason why this should not work there ;-) If this
27  * is ever to happen at all is a different question.
28  *
29  * ---------------------------------------------------------------------
30  *
31  * This driver works slightly different from most others, as the PPS
32  * information (if available) is also coming from GPSD via the data
33  * connection. This makes using both the PPS data and the serial data
34  * easier, but OTOH it's not possible to use the ATOM driver to feed a
35  * raw PPS stream to the core of NTPD.
36  *
37  * To go around this, the driver can use a secondary clock unit
38  * (units>=128) that operate in tandem with the primary clock unit
39  * (unit%128). The primary clock unit does all the IO stuff and data
40  * decoding; if a a secondary unit is attached to a primary unit, this
41  * secondary unit is feed with the PPS samples only and can act as a PPS
42  * source to the clock selection.
43  *
44  * The drawback is that the primary unit must be present for the
45  * secondary unit to work.
46  *
47  * This design is a compromise to reduce the IO load for both NTPD and
48  * GPSD; it also ensures that data is transmitted and evaluated only
49  * once on the side of NTPD.
50  *
51  * ---------------------------------------------------------------------
52  *
53  * trouble shooting hints:
54  *
55  *   Enable and check the clock stats. Check if there are bad replies;
56  *   there should be none. If there are actually bad replies, then the
57  *   driver cannot parse all JSON records from GPSD, and some record
58  *   types are vital for the operation of the driver. This indicates a
59  *   problem on the protocol level.
60  *
61  *   When started on the command line with a debug level >= 2, the
62  *   driver dumps the raw received data and the parser input to
63  *   stdout. Since the debug level is global, NTPD starts to create a
64  *   *lot* of output. It makes sense to pipe it through '(f)grep
65  *   GPSD_JSON' before writing the result to disk.
66  *
67  *   A bit less intrusive is using netcat or telnet to connect to GPSD
68  *   and snoop what NTPD would get. If you try this, you have to send a
69  *   WATCH command to GPSD:
70  *
71  * ?WATCH={"device":"/dev/gps0","enable":true,"json":true,"pps":true};<CRLF>
72  *
73  *   should show you what GPSD has to say to NTPD. Replace "/dev/gps0"
74  *   with the device link used by GPSD, if necessary.
75  */
76
77
78 #ifdef HAVE_CONFIG_H
79 #include <config.h>
80 #endif
81
82 #include "ntp_types.h"
83
84 #if defined(REFCLOCK) && defined(CLOCK_GPSDJSON) && !defined(SYS_WINNT)
85
86 /* =====================================================================
87  * Get the little JSMN library directly into our guts. Use the 'parent
88  * link' feature for maximum speed.
89  */
90 #define JSMN_PARENT_LINKS
91 #include "../libjsmn/jsmn.c"
92
93 /* =====================================================================
94  * JSON parsing stuff
95  */
96
97 #define JSMN_MAXTOK     350
98 #define INVALID_TOKEN (-1)
99
100 typedef struct json_ctx {
101         char        * buf;
102         int           ntok;
103         jsmntok_t     tok[JSMN_MAXTOK];
104 } json_ctx;
105
106 typedef int tok_ref;
107
108 /* Not all targets have 'long long', and not all of them have 'strtoll'.
109  * Sigh. We roll our own integer number parser.
110  */
111 #ifdef HAVE_LONG_LONG
112 typedef signed   long long int json_int;
113 typedef unsigned long long int json_uint;
114 #define JSON_INT_MAX LLONG_MAX
115 #define JSON_INT_MIN LLONG_MIN
116 #else
117 typedef signed   long int json_int;
118 typedef unsigned long int json_uint;
119 #define JSON_INT_MAX LONG_MAX
120 #define JSON_INT_MIN LONG_MIN
121 #endif
122
123 /* =====================================================================
124  * header stuff we need
125  */
126
127 #include <netdb.h>
128 #include <unistd.h>
129 #include <fcntl.h>
130 #include <string.h>
131 #include <ctype.h>
132 #include <math.h>
133
134 #include <sys/types.h>
135 #include <sys/socket.h>
136 #include <sys/stat.h>
137 #include <netinet/tcp.h>
138
139 #if defined(HAVE_SYS_POLL_H)
140 # include <sys/poll.h>
141 #elif defined(HAVE_SYS_SELECT_H)
142 # include <sys/select.h>
143 #else
144 # error need poll() or select()
145 #endif
146
147 #include "ntpd.h"
148 #include "ntp_io.h"
149 #include "ntp_unixtime.h"
150 #include "ntp_refclock.h"
151 #include "ntp_stdlib.h"
152 #include "ntp_calendar.h"
153 #include "timespecops.h"
154
155 /* get operation modes from mode word.
156
157  * + SERIAL (default) evaluates only serial time information ('STI') as
158  *   provided by TPV and TOFF records. TPV evaluation suffers from a
159  *   bigger jitter than TOFF, sine it does not contain the receive time
160  *   from GPSD and therefore the receive time of NTPD must be
161  *   substituted for it. The network latency makes this a second rate
162  *   guess.
163  *
164  *   If TOFF records are detected in the data stream, the timing
165  *   information is gleaned from this record -- it contains the local
166  *   receive time stamp from GPSD and therefore eliminates the
167  *   transmission latency between GPSD and NTPD. The timing information
168  *   from TPV is ignored once a TOFF is detected or expected.
169  *
170  *   TPV is still used to check the fix status, so the driver can stop
171  *   feeding samples when GPSD says that the time information is
172  *   effectively unreliable.
173  *
174  * + STRICT means only feed clock samples when a valid STI/PPS pair is
175  *   available. Combines the reference time from STI with the pulse time
176  *   from PPS. Masks the serial data jitter as long PPS is available,
177  *   but can rapidly deteriorate once PPS drops out.
178  *
179  * + AUTO tries to use STI/PPS pairs if available for some time, and if
180  *   this fails for too long switches back to STI only until the PPS
181  *   signal becomes available again. See the HTML docs for this driver
182  *   about the gotchas and why this is not the default.
183  */
184 #define MODE_OP_MASK   0x03
185 #define MODE_OP_STI    0
186 #define MODE_OP_STRICT 1
187 #define MODE_OP_AUTO   2
188 #define MODE_OP_MAXVAL 2
189 #define MODE_OP_MODE(x)         ((x) & MODE_OP_MASK)
190
191 #define PRECISION       (-9)    /* precision assumed (about 2 ms) */
192 #define PPS_PRECISION   (-20)   /* precision assumed (about 1 us) */
193 #define REFID           "GPSD"  /* reference id */
194 #define DESCRIPTION     "GPSD JSON client clock" /* who we are */
195
196 #define MAX_PDU_LEN     1600
197 #define TICKOVER_LOW    10
198 #define TICKOVER_HIGH   120
199 #define LOGTHROTTLE     3600
200
201 /* Primary channel PPS avilability dance:
202  * Every good PPS sample gets us a credit of PPS_INCCOUNT points, every
203  * bad/missing PPS sample costs us a debit of PPS_DECCOUNT points. When
204  * the account reaches the upper limit we change to a mode where only
205  * PPS-augmented samples are fed to the core; when the account drops to
206  * zero we switch to a mode where TPV-only timestamps are fed to the
207  * core.
208  * This reduces the chance of rapid alternation between raw and
209  * PPS-augmented time stamps.
210  */
211 #define PPS_MAXCOUNT    60      /* upper limit of account  */
212 #define PPS_INCCOUNT     3      /* credit for good samples */
213 #define PPS_DECCOUNT     1      /* debit for bad samples   */
214
215 /* The secondary (PPS) channel uses a different strategy to avoid old
216  * PPS samples in the median filter.
217  */
218 #define PPS2_MAXCOUNT 10
219
220 #ifndef BOOL
221 # define BOOL int
222 #endif
223 #ifndef TRUE
224 # define TRUE 1
225 #endif
226 #ifndef FALSE
227 # define FALSE 0
228 #endif
229
230 #define PROTO_VERSION(hi,lo) \
231             ((((uint32_t)(hi) << 16) & 0xFFFF0000u) | \
232              ((uint32_t)(lo) & 0x0FFFFu))
233
234 /* some local typedefs: The NTPD formatting style cries for short type
235  * names, and we provide them locally. Note:the suffix '_t' is reserved
236  * for the standard; I use a capital T instead.
237  */
238 typedef struct peer         peerT;
239 typedef struct refclockproc clockprocT;
240 typedef struct addrinfo     addrinfoT;
241
242 /* =====================================================================
243  * We use the same device name scheme as does the NMEA driver; since
244  * GPSD supports the same links, we can select devices by a fixed name.
245  */
246 static const char * s_dev_stem = "/dev/gps";
247
248 /* =====================================================================
249  * forward declarations for transfer vector and the vector itself
250  */
251
252 static  void    gpsd_init       (void);
253 static  int     gpsd_start      (int, peerT *);
254 static  void    gpsd_shutdown   (int, peerT *);
255 static  void    gpsd_receive    (struct recvbuf *);
256 static  void    gpsd_poll       (int, peerT *);
257 static  void    gpsd_control    (int, const struct refclockstat *,
258                                  struct refclockstat *, peerT *);
259 static  void    gpsd_timer      (int, peerT *);
260
261 static  int     myasprintf(char**, char const*, ...) NTP_PRINTF(2, 3);
262
263 static void     enter_opmode(peerT *peer, int mode);
264 static void     leave_opmode(peerT *peer, int mode);
265
266 struct refclock refclock_gpsdjson = {
267         gpsd_start,             /* start up driver */
268         gpsd_shutdown,          /* shut down driver */
269         gpsd_poll,              /* transmit poll message */
270         gpsd_control,           /* fudge control */
271         gpsd_init,              /* initialize driver */
272         noentry,                /* buginfo */
273         gpsd_timer              /* called once per second */
274 };
275
276 /* =====================================================================
277  * our local clock unit and data
278  */
279 struct gpsd_unit;
280 typedef struct gpsd_unit gpsd_unitT;
281
282 struct gpsd_unit {
283         /* links for sharing between master/slave units */
284         gpsd_unitT *next_unit;
285         size_t      refcount;
286
287         /* data for the secondary PPS channel */
288         peerT      *pps_peer;
289
290         /* unit and operation modes */
291         int      unit;
292         int      mode;
293         char    *logname;       /* cached name for log/print */
294         char    * device;       /* device name of unit */
295
296         /* current line protocol version */
297         uint32_t proto_version;
298
299         /* PPS time stamps primary + secondary channel */
300         l_fp pps_local; /* when we received the PPS message */
301         l_fp pps_stamp; /* related reference time */
302         l_fp pps_recvt; /* when GPSD detected the pulse */
303         l_fp pps_stamp2;/* related reference time (secondary) */
304         l_fp pps_recvt2;/* when GPSD detected the pulse (secondary)*/
305         int  ppscount;  /* PPS counter (primary unit) */
306         int  ppscount2; /* PPS counter (secondary unit) */
307
308         /* TPV or TOFF serial time information */
309         l_fp sti_local; /* when we received the TPV/TOFF message */
310         l_fp sti_stamp; /* effective GPS time stamp */
311         l_fp sti_recvt; /* when GPSD got the fix */
312
313         /* precision estimates */
314         int16_t     sti_prec;   /* serial precision based on EPT */
315         int16_t     pps_prec;   /* PPS precision from GPSD or above */
316
317         /* fudge values for correction, mirrored as 'l_fp' */
318         l_fp pps_fudge;         /* PPS fudge primary channel */
319         l_fp pps_fudge2;        /* PPS fudge secondary channel */
320         l_fp sti_fudge;         /* TPV/TOFF serial data fudge */
321
322         /* Flags to indicate available data */
323         int fl_nosync: 1;       /* GPSD signals bad quality */
324         int fl_sti   : 1;       /* valid TPV/TOFF seen (have time) */
325         int fl_pps   : 1;       /* valid pulse seen */
326         int fl_pps2  : 1;       /* valid pulse seen for PPS channel */
327         int fl_rawsti: 1;       /* permit raw TPV/TOFF time stamps */
328         int fl_vers  : 1;       /* have protocol version */
329         int fl_watch : 1;       /* watch reply seen */
330         /* protocol flags */
331         int pf_nsec  : 1;       /* have nanosec PPS info */
332         int pf_toff  : 1;       /* have TOFF record for timing */
333
334         /* admin stuff for sockets and device selection */
335         int         fdt;        /* current connecting socket */
336         addrinfoT * addr;       /* next address to try */
337         u_int       tickover;   /* timeout countdown */
338         u_int       tickpres;   /* timeout preset */
339
340         /* tallies for the various events */
341         u_int       tc_recv;    /* received known records */
342         u_int       tc_breply;  /* bad replies / parsing errors */
343         u_int       tc_nosync;  /* TPV / sample cycles w/o fix */
344         u_int       tc_sti_recv;/* received serial time info records */
345         u_int       tc_sti_used;/* used        --^-- */
346         u_int       tc_pps_recv;/* received PPS timing info records */
347         u_int       tc_pps_used;/* used        --^-- */
348
349         /* log bloat throttle */
350         u_int       logthrottle;/* seconds to next log slot */
351
352         /* The parse context for the current record */
353         json_ctx    json_parse;
354
355         /* record assemby buffer and saved length */
356         int  buflen;
357         char buffer[MAX_PDU_LEN];
358 };
359
360 /* =====================================================================
361  * static local helpers forward decls
362  */
363 static void gpsd_init_socket(peerT * const peer);
364 static void gpsd_test_socket(peerT * const peer);
365 static void gpsd_stop_socket(peerT * const peer);
366
367 static void gpsd_parse(peerT * const peer,
368                        const l_fp  * const rtime);
369 static BOOL convert_ascii_time(l_fp * fp, const char * gps_time);
370 static void save_ltc(clockprocT * const pp, const char * const tc);
371 static int  syslogok(clockprocT * const pp, gpsd_unitT * const up);
372 static void log_data(peerT *peer, const char *what,
373                      const char *buf, size_t len);
374 static int16_t clamped_precision(int rawprec);
375
376 /* =====================================================================
377  * local / static stuff
378  */
379
380 static const char * const s_req_version =
381     "?VERSION;\r\n";
382
383 /* We keep a static list of network addresses for 'localhost:gpsd' or a
384  * fallback alias of it, and we try to connect to them in round-robin
385  * fashion. The service lookup is done during the driver init
386  * function to minmise the impact of 'getaddrinfo()'.
387  *
388  * Alas, the init function is called even if there are no clocks
389  * configured for this driver. So it makes sense to defer the logging of
390  * any errors or other notifications until the first clock unit is
391  * started -- otherwise there might be syslog entries from a driver that
392  * is not used at all.
393  */
394 static addrinfoT  *s_gpsd_addr;
395 static gpsd_unitT *s_clock_units;
396
397 /* list of service/socket names we want to resolve against */
398 static const char * const s_svctab[][2] = {
399         { "localhost", "gpsd" },
400         { "localhost", "2947" },
401         { "127.0.0.1", "2947" },
402         { NULL, NULL }
403 };
404
405 /* list of address resolution errors and index of service entry that
406  * finally worked.
407  */
408 static int s_svcerr[sizeof(s_svctab)/sizeof(s_svctab[0])];
409 static int s_svcidx;
410
411 /* =====================================================================
412  * log throttling
413  */
414 static int/*BOOL*/
415 syslogok(
416         clockprocT * const pp,
417         gpsd_unitT * const up)
418 {
419         int res = (0 != (pp->sloppyclockflag & CLK_FLAG3))
420                || (0           == up->logthrottle )
421                || (LOGTHROTTLE == up->logthrottle );
422         if (res)
423                 up->logthrottle = LOGTHROTTLE;
424         return res;
425 }
426
427 /* =====================================================================
428  * the clock functions
429  */
430
431 /* ---------------------------------------------------------------------
432  * Init: This currently just gets the socket address for the GPS daemon
433  */
434 static void
435 gpsd_init(void)
436 {
437         addrinfoT   hints;
438         int         rc, idx;
439
440         memset(s_svcerr, 0, sizeof(s_svcerr));
441         memset(&hints, 0, sizeof(hints));
442         hints.ai_family   = AF_UNSPEC;
443         hints.ai_protocol = IPPROTO_TCP;
444         hints.ai_socktype = SOCK_STREAM;
445
446         for (idx = 0; s_svctab[idx][0] && !s_gpsd_addr; idx++) {
447                 rc = getaddrinfo(s_svctab[idx][0], s_svctab[idx][1],
448                                  &hints, &s_gpsd_addr);
449                 s_svcerr[idx] = rc;
450                 if (0 == rc)
451                         break;
452                 s_gpsd_addr = NULL;
453         }
454         s_svcidx = idx;
455 }
456
457 /* ---------------------------------------------------------------------
458  * Init Check: flush pending log messages and check if we can proceed
459  */
460 static int/*BOOL*/
461 gpsd_init_check(void)
462 {
463         int idx;
464
465         /* Check if there is something to log */
466         if (s_svcidx == 0)
467                 return (s_gpsd_addr != NULL);
468
469         /* spool out the resolver errors */
470         for (idx = 0; idx < s_svcidx; ++idx) {
471                 msyslog(LOG_WARNING,
472                         "GPSD_JSON: failed to resolve '%s:%s', rc=%d (%s)",
473                         s_svctab[idx][0], s_svctab[idx][1],
474                         s_svcerr[idx], gai_strerror(s_svcerr[idx]));
475         }
476
477         /* check if it was fatal, or if we can proceed */
478         if (s_gpsd_addr == NULL)
479                 msyslog(LOG_ERR, "%s",
480                         "GPSD_JSON: failed to get socket address, giving up.");
481         else if (idx != 0)
482                 msyslog(LOG_WARNING,
483                         "GPSD_JSON: using '%s:%s' instead of '%s:%s'",
484                         s_svctab[idx][0], s_svctab[idx][1],
485                         s_svctab[0][0], s_svctab[0][1]);
486
487         /* make sure this gets logged only once and tell if we can
488          * proceed or not
489          */
490         s_svcidx = 0;
491         return (s_gpsd_addr != NULL);
492 }
493
494 /* ---------------------------------------------------------------------
495  * Start: allocate a unit pointer and set up the runtime data
496  */
497 static int
498 gpsd_start(
499         int     unit,
500         peerT * peer)
501 {
502         clockprocT  * const pp = peer->procptr;
503         gpsd_unitT  * up;
504         gpsd_unitT ** uscan    = &s_clock_units;
505
506         struct stat sb;
507
508         /* check if we can proceed at all or if init failed */
509         if ( ! gpsd_init_check())
510                 return FALSE;
511
512         /* search for matching unit */
513         while ((up = *uscan) != NULL && up->unit != (unit & 0x7F))
514                 uscan = &up->next_unit;
515         if (up == NULL) {
516                 /* alloc unit, add to list and increment use count ASAP. */
517                 up = emalloc_zero(sizeof(*up));
518                 *uscan = up;
519                 ++up->refcount;
520
521                 /* initialize the unit structure */
522                 up->logname  = estrdup(refnumtoa(&peer->srcadr));
523                 up->unit     = unit & 0x7F;
524                 up->fdt      = -1;
525                 up->addr     = s_gpsd_addr;
526                 up->tickpres = TICKOVER_LOW;
527
528                 /* Create the device name and check for a Character
529                  * Device. It's assumed that GPSD was started with the
530                  * same link, so the names match. (If this is not
531                  * practicable, we will have to read the symlink, if
532                  * any, so we can get the true device file.)
533                  */
534                 if (-1 == myasprintf(&up->device, "%s%u",
535                                      s_dev_stem, up->unit)) {
536                         msyslog(LOG_ERR, "%s: clock device name too long",
537                                 up->logname);
538                         goto dev_fail;
539                 }
540                 if (-1 == stat(up->device, &sb) || !S_ISCHR(sb.st_mode)) {
541                         msyslog(LOG_ERR, "%s: '%s' is not a character device",
542                                 up->logname, up->device);
543                         goto dev_fail;
544                 }
545         } else {
546                 /* All set up, just increment use count. */
547                 ++up->refcount;
548         }
549         
550         /* setup refclock processing */
551         pp->unitptr = (caddr_t)up;
552         pp->io.fd         = -1;
553         pp->io.clock_recv = gpsd_receive;
554         pp->io.srcclock   = peer;
555         pp->io.datalen    = 0;
556         pp->a_lastcode[0] = '\0';
557         pp->lencode       = 0;
558         pp->clockdesc     = DESCRIPTION;
559         memcpy(&pp->refid, REFID, 4);
560
561         /* Initialize miscellaneous variables */
562         if (unit >= 128)
563                 peer->precision = PPS_PRECISION;
564         else
565                 peer->precision = PRECISION;
566
567         /* If the daemon name lookup failed, just give up now. */
568         if (NULL == up->addr) {
569                 msyslog(LOG_ERR, "%s: no GPSD socket address, giving up",
570                         up->logname);
571                 goto dev_fail;
572         }
573
574         LOGIF(CLOCKINFO,
575               (LOG_NOTICE, "%s: startup, device is '%s'",
576                refnumtoa(&peer->srcadr), up->device));
577         up->mode = MODE_OP_MODE(peer->ttl);
578         if (up->mode > MODE_OP_MAXVAL)
579                 up->mode = 0;
580         if (unit >= 128)
581                 up->pps_peer = peer;
582         else
583                 enter_opmode(peer, up->mode);
584         return TRUE;
585
586 dev_fail:
587         /* On failure, remove all UNIT ressources and declare defeat. */
588
589         INSIST (up);
590         if (!--up->refcount) {
591                 *uscan = up->next_unit;
592                 free(up->device);
593                 free(up);
594         }
595
596         pp->unitptr = (caddr_t)NULL;
597         return FALSE;
598 }
599
600 /* ------------------------------------------------------------------ */
601
602 static void
603 gpsd_shutdown(
604         int     unit,
605         peerT * peer)
606 {
607         clockprocT * const pp = peer->procptr;
608         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
609         gpsd_unitT ** uscan   = &s_clock_units;
610
611         UNUSED_ARG(unit);
612
613         /* The unit pointer might have been removed already. */
614         if (up == NULL)
615                 return;
616
617         /* now check if we must close IO resources */
618         if (peer != up->pps_peer) {
619                 if (-1 != pp->io.fd) {
620                         DPRINTF(1, ("%s: closing clock, fd=%d\n",
621                                     up->logname, pp->io.fd));
622                         io_closeclock(&pp->io);
623                         pp->io.fd = -1;
624                 }
625                 if (up->fdt != -1)
626                         close(up->fdt);
627         }
628         /* decrement use count and eventually remove this unit. */
629         if (!--up->refcount) {
630                 /* unlink this unit */
631                 while (*uscan != NULL)
632                         if (*uscan == up)
633                                 *uscan = up->next_unit;
634                         else
635                                 uscan = &(*uscan)->next_unit;
636                 free(up->logname);
637                 free(up->device);
638                 free(up);
639         }
640         pp->unitptr = (caddr_t)NULL;
641         LOGIF(CLOCKINFO,
642               (LOG_NOTICE, "%s: shutdown", refnumtoa(&peer->srcadr)));
643 }
644
645 /* ------------------------------------------------------------------ */
646
647 static void
648 gpsd_receive(
649         struct recvbuf * rbufp)
650 {
651         /* declare & init control structure ptrs */
652         peerT      * const peer = rbufp->recv_peer;
653         clockprocT * const pp   = peer->procptr;
654         gpsd_unitT * const up   = (gpsd_unitT *)pp->unitptr;
655
656         const char *psrc, *esrc;
657         char       *pdst, *edst, ch;
658
659         /* log the data stream, if this is enabled */
660         log_data(peer, "recv", (const char*)rbufp->recv_buffer,
661                  (size_t)rbufp->recv_length);
662
663
664         /* Since we're getting a raw stream data, we must assemble lines
665          * in our receive buffer. We can't use neither 'refclock_gtraw'
666          * not 'refclock_gtlin' here...  We process chars until we reach
667          * an EoL (that is, line feed) but we truncate the message if it
668          * does not fit the buffer.  GPSD might truncate messages, too,
669          * so dealing with truncated buffers is necessary anyway.
670          */
671         psrc = (const char*)rbufp->recv_buffer;
672         esrc = psrc + rbufp->recv_length;
673
674         pdst = up->buffer + up->buflen;
675         edst = pdst + sizeof(up->buffer) - 1; /* for trailing NUL */
676
677         while (psrc != esrc) {
678                 ch = *psrc++;
679                 if (ch == '\n') {
680                         /* trim trailing whitespace & terminate buffer */
681                         while (pdst != up->buffer && pdst[-1] <= ' ')
682                                 --pdst;
683                         *pdst = '\0';
684                         /* process data and reset buffer */
685                         up->buflen = pdst - up->buffer;
686                         gpsd_parse(peer, &rbufp->recv_time);
687                         pdst = up->buffer;
688                 } else if (pdst != edst) {
689                         /* add next char, ignoring leading whitespace */
690                         if (ch > ' ' || pdst != up->buffer)
691                                 *pdst++ = ch;
692                 }
693         }
694         up->buflen   = pdst - up->buffer;
695         up->tickover = TICKOVER_LOW;
696 }
697
698 /* ------------------------------------------------------------------ */
699
700 static void
701 poll_primary(
702         peerT      * const peer ,
703         clockprocT * const pp   ,
704         gpsd_unitT * const up   )
705 {
706         if (pp->coderecv != pp->codeproc) {
707                 /* all is well */
708                 pp->lastref = pp->lastrec;
709                 refclock_report(peer, CEVNT_NOMINAL);
710                 refclock_receive(peer);
711         } else {
712                 /* Not working properly, admit to it. If we have no
713                  * connection to GPSD, declare the clock as faulty. If
714                  * there were bad replies, this is handled as the major
715                  * cause, and everything else is just a timeout.
716                  */
717                 peer->precision = PRECISION;
718                 if (-1 == pp->io.fd)
719                         refclock_report(peer, CEVNT_FAULT);
720                 else if (0 != up->tc_breply)
721                         refclock_report(peer, CEVNT_BADREPLY);
722                 else
723                         refclock_report(peer, CEVNT_TIMEOUT);
724         }
725
726         if (pp->sloppyclockflag & CLK_FLAG4)
727                 mprintf_clock_stats(
728                         &peer->srcadr,"%u %u %u %u %u %u %u",
729                         up->tc_recv,
730                         up->tc_breply, up->tc_nosync,
731                         up->tc_sti_recv, up->tc_sti_used,
732                         up->tc_pps_recv, up->tc_pps_used);
733
734         /* clear tallies for next round */
735         up->tc_breply   = 0;
736         up->tc_recv     = 0;
737         up->tc_nosync   = 0;
738         up->tc_sti_recv = 0;
739         up->tc_sti_used = 0;
740         up->tc_pps_recv = 0;
741         up->tc_pps_used = 0;
742 }
743
744 static void
745 poll_secondary(
746         peerT      * const peer ,
747         clockprocT * const pp   ,
748         gpsd_unitT * const up   )
749 {
750         if (pp->coderecv != pp->codeproc) {
751                 /* all is well */
752                 pp->lastref = pp->lastrec;
753                 refclock_report(peer, CEVNT_NOMINAL);
754                 refclock_receive(peer);
755         } else {
756                 peer->precision = PPS_PRECISION;
757                 peer->flags &= ~FLAG_PPS;
758                 refclock_report(peer, CEVNT_TIMEOUT);
759         }
760 }
761
762 static void
763 gpsd_poll(
764         int     unit,
765         peerT * peer)
766 {
767         clockprocT * const pp = peer->procptr;
768         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
769
770         ++pp->polls;
771         if (peer == up->pps_peer)
772                 poll_secondary(peer, pp, up);
773         else
774                 poll_primary(peer, pp, up);
775 }
776
777 /* ------------------------------------------------------------------ */
778
779 static void
780 gpsd_control(
781         int                         unit,
782         const struct refclockstat * in_st,
783         struct refclockstat       * out_st,
784         peerT                     * peer  )
785 {
786         clockprocT * const pp = peer->procptr;
787         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
788
789         if (peer == up->pps_peer) {
790                 DTOLFP(pp->fudgetime1, &up->pps_fudge2);
791                 if ( ! (pp->sloppyclockflag & CLK_FLAG1))
792                         peer->flags &= ~FLAG_PPS;
793         } else {
794                 /* save preprocessed fudge times */
795                 DTOLFP(pp->fudgetime1, &up->pps_fudge);
796                 DTOLFP(pp->fudgetime2, &up->sti_fudge);
797
798                 if (MODE_OP_MODE(up->mode ^ peer->ttl)) {
799                         leave_opmode(peer, up->mode);
800                         up->mode = MODE_OP_MODE(peer->ttl);
801                         enter_opmode(peer, up->mode);
802                 }
803         }
804  }
805
806 /* ------------------------------------------------------------------ */
807
808 static void
809 timer_primary(
810         peerT      * const peer ,
811         clockprocT * const pp   ,
812         gpsd_unitT * const up   )
813 {
814         int rc;
815
816         /* This is used for timeout handling. Nothing that needs
817          * sub-second precison happens here, so receive/connect/retry
818          * timeouts are simply handled by a count down, and then we
819          * decide what to do by the socket values.
820          *
821          * Note that the timer stays at zero here, unless some of the
822          * functions set it to another value.
823          */
824         if (up->logthrottle)
825                 --up->logthrottle;
826         if (up->tickover)
827                 --up->tickover;
828         switch (up->tickover) {
829         case 4:
830                 /* If we are connected to GPSD, try to get a live signal
831                  * by querying the version. Otherwise just check the
832                  * socket to become ready.
833                  */
834                 if (-1 != pp->io.fd) {
835                         size_t rlen = strlen(s_req_version);
836                         DPRINTF(2, ("%s: timer livecheck: '%s'\n",
837                                     up->logname, s_req_version));
838                         log_data(peer, "send", s_req_version, rlen);
839                         rc = write(pp->io.fd, s_req_version, rlen);
840                         (void)rc;
841                 } else if (-1 != up->fdt) {
842                         gpsd_test_socket(peer);
843                 }
844                 break;
845
846         case 0:
847                 if (-1 != pp->io.fd)
848                         gpsd_stop_socket(peer);
849                 else if (-1 != up->fdt)
850                         gpsd_test_socket(peer);
851                 else if (NULL != s_gpsd_addr)
852                         gpsd_init_socket(peer);
853                 break;
854
855         default:
856                 if (-1 == pp->io.fd && -1 != up->fdt)
857                         gpsd_test_socket(peer);
858         }
859 }
860
861 static void
862 timer_secondary(
863         peerT      * const peer ,
864         clockprocT * const pp   ,
865         gpsd_unitT * const up   )
866 {
867         /* Reduce the count by one. Flush sample buffer and clear PPS
868          * flag when this happens.
869          */
870         up->ppscount2 = max(0, (up->ppscount2 - 1));
871         if (0 == up->ppscount2) {
872                 if (pp->coderecv != pp->codeproc) {
873                         refclock_report(peer, CEVNT_TIMEOUT);
874                         pp->coderecv = pp->codeproc;
875                 }
876                 peer->flags &= ~FLAG_PPS;
877         }
878 }
879
880 static void
881 gpsd_timer(
882         int     unit,
883         peerT * peer)
884 {
885         clockprocT * const pp = peer->procptr;
886         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
887
888         if (peer == up->pps_peer)
889                 timer_secondary(peer, pp, up);
890         else
891                 timer_primary(peer, pp, up);
892 }
893
894 /* =====================================================================
895  * handle opmode switches
896  */
897
898 static void
899 enter_opmode(
900         peerT *peer,
901         int    mode)
902 {
903         clockprocT * const pp = peer->procptr;
904         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
905
906         DPRINTF(1, ("%s: enter operation mode %d\n",
907                     up->logname, MODE_OP_MODE(mode)));
908
909         if (MODE_OP_MODE(mode) == MODE_OP_AUTO) {
910                 up->fl_rawsti = 0;
911                 up->ppscount  = PPS_MAXCOUNT / 2;
912         }
913         up->fl_pps = 0;
914         up->fl_sti = 0;
915 }
916
917 /* ------------------------------------------------------------------ */
918
919 static void
920 leave_opmode(
921         peerT *peer,
922         int    mode)
923 {
924         clockprocT * const pp = peer->procptr;
925         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
926
927         DPRINTF(1, ("%s: leaving operation mode %d\n",
928                     up->logname, MODE_OP_MODE(mode)));
929
930         if (MODE_OP_MODE(mode) == MODE_OP_AUTO) {
931                 up->fl_rawsti = 0;
932                 up->ppscount  = 0;
933         }
934         up->fl_pps = 0;
935         up->fl_sti = 0;
936 }
937
938 /* =====================================================================
939  * operation mode specific evaluation
940  */
941
942 static void
943 add_clock_sample(
944         peerT      * const peer ,
945         clockprocT * const pp   ,
946         l_fp               stamp,
947         l_fp               recvt)
948 {
949         pp->lastref = stamp;
950         if (pp->coderecv == pp->codeproc)
951                 refclock_report(peer, CEVNT_NOMINAL);
952         refclock_process_offset(pp, stamp, recvt, pp->fudgetime1);
953 }
954
955 /* ------------------------------------------------------------------ */
956
957 static void
958 eval_strict(
959         peerT      * const peer ,
960         clockprocT * const pp   ,
961         gpsd_unitT * const up   )
962 {
963         if (up->fl_sti && up->fl_pps) {
964                 /* use TPV reference time + PPS receive time */
965                 add_clock_sample(peer, pp, up->sti_stamp, up->pps_recvt);
966                 peer->precision = up->pps_prec;
967                 /* both packets consumed now... */
968                 up->fl_pps = 0;
969                 up->fl_sti = 0;
970                 ++up->tc_sti_used;
971         }
972 }
973
974 /* ------------------------------------------------------------------ */
975 /* PPS processing for the secondary channel. GPSD provides us with full
976  * timing information, so there's no danger of PLL-locking to the wrong
977  * second. The belts and suspenders needed for the raw ATOM clock are
978  * unnecessary here.
979  */
980 static void
981 eval_pps_secondary(
982         peerT      * const peer ,
983         clockprocT * const pp   ,
984         gpsd_unitT * const up   )
985 {
986         if (up->fl_pps2) {
987                 /* feed data */
988                 add_clock_sample(peer, pp, up->pps_stamp2, up->pps_recvt2);
989                 peer->precision = up->pps_prec;
990                 /* PPS peer flag logic */
991                 up->ppscount2 = min(PPS2_MAXCOUNT, (up->ppscount2 + 2));
992                 if ((PPS2_MAXCOUNT == up->ppscount2) &&
993                     (pp->sloppyclockflag & CLK_FLAG1) )
994                         peer->flags |= FLAG_PPS;
995                 /* mark time stamp as burned... */
996                 up->fl_pps2 = 0;
997                 ++up->tc_pps_used;
998         }
999 }
1000
1001 /* ------------------------------------------------------------------ */
1002
1003 static void
1004 eval_serial(
1005         peerT      * const peer ,
1006         clockprocT * const pp   ,
1007         gpsd_unitT * const up   )
1008 {
1009         if (up->fl_sti) {
1010                 add_clock_sample(peer, pp, up->sti_stamp, up->sti_recvt);
1011                 peer->precision = up->sti_prec;
1012                 /* mark time stamp as burned... */
1013                 up->fl_sti = 0;
1014                 ++up->tc_sti_used;
1015         }
1016 }
1017
1018 /* ------------------------------------------------------------------ */
1019 static void
1020 eval_auto(
1021         peerT      * const peer ,
1022         clockprocT * const pp   ,
1023         gpsd_unitT * const up   )
1024 {
1025         /* If there's no TPV available, stop working here... */
1026         if (!up->fl_sti)
1027                 return;
1028
1029         /* check how to handle STI+PPS: Can PPS be used to augment STI
1030          * (or vice versae), do we drop the sample because there is a
1031          * temporary missing PPS signal, or do we feed on STI time
1032          * stamps alone?
1033          *
1034          * Do a counter/threshold dance to decide how to proceed.
1035          */
1036         if (up->fl_pps) {
1037                 up->ppscount = min(PPS_MAXCOUNT,
1038                                    (up->ppscount + PPS_INCCOUNT));
1039                 if ((PPS_MAXCOUNT == up->ppscount) && up->fl_rawsti) {
1040                         up->fl_rawsti = 0;
1041                         msyslog(LOG_INFO,
1042                                 "%s: expect valid PPS from now",
1043                                 up->logname);
1044                 }
1045         } else {
1046                 up->ppscount = max(0, (up->ppscount - PPS_DECCOUNT));
1047                 if ((0 == up->ppscount) && !up->fl_rawsti) {
1048                         up->fl_rawsti = -1;
1049                         msyslog(LOG_WARNING,
1050                                 "%s: use TPV alone from now",
1051                                 up->logname);
1052                 }
1053         }
1054
1055         /* now eventually feed the sample */
1056         if (up->fl_rawsti)
1057                 eval_serial(peer, pp, up);
1058         else
1059                 eval_strict(peer, pp, up);
1060 }
1061
1062 /* =====================================================================
1063  * JSON parsing stuff
1064  */
1065
1066 /* ------------------------------------------------------------------ */
1067 /* Parse a decimal integer with a possible sign. Works like 'strtoll()'
1068  * or 'strtol()', but with a fixed base of 10 and without eating away
1069  * leading whitespace. For the error codes, the handling of the end
1070  * pointer and the return values see 'strtol()'.
1071  */
1072 static json_int
1073 strtojint(
1074         const char *cp, char **ep)
1075 {
1076         json_uint     accu, limit_lo, limit_hi;
1077         int           flags; /* bit 0: overflow; bit 1: sign */
1078         const char  * hold;
1079
1080         /* pointer union to circumvent a tricky/sticky const issue */
1081         union { const char * c; char * v; } vep;
1082
1083         /* store initial value of 'cp' -- see 'strtol()' */
1084         vep.c = cp;
1085
1086         /* Eat away an optional sign and set the limits accordingly: The
1087          * high limit is the maximum absolute value that can be returned,
1088          * and the low limit is the biggest value that does not cause an
1089          * overflow when multiplied with 10. Avoid negation overflows.
1090          */
1091         if (*cp == '-') {
1092                 cp += 1;
1093                 flags    = 2;
1094                 limit_hi = (json_uint)-(JSON_INT_MIN + 1) + 1;
1095         } else {
1096                 cp += (*cp == '+');
1097                 flags    = 0;
1098                 limit_hi = (json_uint)JSON_INT_MAX;
1099         }
1100         limit_lo = limit_hi / 10;
1101
1102         /* Now try to convert a sequence of digits. */
1103         hold = cp;
1104         accu = 0;
1105         while (isdigit(*(const u_char*)cp)) {
1106                 flags |= (accu > limit_lo);
1107                 accu = accu * 10 + (*(const u_char*)cp++ - '0');
1108                 flags |= (accu > limit_hi);
1109         }
1110         /* Check for empty conversion (no digits seen). */
1111         if (hold != cp)
1112                 vep.c = cp;
1113         else
1114                 errno = EINVAL; /* accu is still zero */
1115         /* Check for range overflow */
1116         if (flags & 1) {
1117                 errno = ERANGE;
1118                 accu  = limit_hi;
1119         }
1120         /* If possible, store back the end-of-conversion pointer */
1121         if (ep)
1122                 *ep = vep.v;
1123         /* If negative, return the negated result if the accu is not
1124          * zero. Avoid negation overflows.
1125          */
1126         if ((flags & 2) && accu)
1127                 return -(json_int)(accu - 1) - 1;
1128         else
1129                 return (json_int)accu;
1130 }
1131
1132 /* ------------------------------------------------------------------ */
1133
1134 static tok_ref
1135 json_token_skip(
1136         const json_ctx * ctx,
1137         tok_ref          tid)
1138 {
1139         if (tid >= 0 && (u_int)tid < ctx->ntok) {
1140                 int len = ctx->tok[tid].size;
1141                 /* For arrays and objects, the size is the number of
1142                  * ITEMS in the compound. Thats the number of objects in
1143                  * the array, and the number of key/value pairs for
1144                  * objects. In theory, the key must be a string, and we
1145                  * could simply skip one token before skipping the
1146                  * value, which can be anything. We're a bit paranoid
1147                  * and lazy at the same time: We simply double the
1148                  * number of tokens to skip and fall through into the
1149                  * array processing when encountering an object.
1150                  */
1151                 switch (ctx->tok[tid].type) {
1152                 case JSMN_OBJECT:
1153                         len *= 2;
1154                         /* FALLTHROUGH */
1155                 case JSMN_ARRAY:
1156                         for (++tid; len; --len)
1157                                 tid = json_token_skip(ctx, tid);
1158                         break;
1159                         
1160                 default:
1161                         ++tid;
1162                         break;
1163                 }
1164                 /* The next condition should never be true, but paranoia
1165                  * prevails...
1166                  */
1167                 if (tid < 0 || (u_int)tid > ctx->ntok)
1168                         tid = ctx->ntok;
1169         }
1170         return tid;
1171 }
1172
1173 /* ------------------------------------------------------------------ */
1174
1175 static int
1176 json_object_lookup(
1177         const json_ctx * ctx ,
1178         tok_ref          tid ,
1179         const char     * key ,
1180         int              what)
1181 {
1182         int len;
1183
1184         if (tid < 0 || tid >= ctx->ntok ||
1185             ctx->tok[tid].type != JSMN_OBJECT)
1186                 return INVALID_TOKEN;
1187         
1188         len = ctx->tok[tid].size;
1189         for (++tid; len && tid+1 < ctx->ntok; --len) {
1190                 if (ctx->tok[tid].type != JSMN_STRING) { /* Blooper! */
1191                         tid = json_token_skip(ctx, tid); /* skip key */
1192                         tid = json_token_skip(ctx, tid); /* skip val */
1193                 } else if (strcmp(key, ctx->buf + ctx->tok[tid].start)) {
1194                         tid = json_token_skip(ctx, tid+1); /* skip key+val */
1195                 } else if (what < 0 || (u_int)what == ctx->tok[tid+1].type) {
1196                         return tid + 1;
1197                 } else {
1198                         break;
1199                 }
1200                 /* if skipping ahead returned an error, bail out here. */
1201                 if (tid < 0)
1202                         break;
1203         }
1204         return INVALID_TOKEN;
1205 }
1206
1207 /* ------------------------------------------------------------------ */
1208
1209 static const char*
1210 json_object_lookup_primitive(
1211         const json_ctx * ctx,
1212         tok_ref          tid,
1213         const char     * key)
1214 {
1215         tid = json_object_lookup(ctx, tid, key, JSMN_PRIMITIVE);
1216         if (INVALID_TOKEN  != tid)
1217                 return ctx->buf + ctx->tok[tid].start;
1218         else
1219                 return NULL;
1220 }
1221 /* ------------------------------------------------------------------ */
1222 /* look up a boolean value. This essentially returns a tribool:
1223  * 0->false, 1->true, (-1)->error/undefined
1224  */
1225 static int
1226 json_object_lookup_bool(
1227         const json_ctx * ctx,
1228         tok_ref          tid,
1229         const char     * key)
1230 {
1231         const char *cp;
1232         cp  = json_object_lookup_primitive(ctx, tid, key);
1233         switch ( cp ? *cp : '\0') {
1234         case 't': return  1;
1235         case 'f': return  0;
1236         default : return -1;
1237         }
1238 }
1239
1240 /* ------------------------------------------------------------------ */
1241
1242 static const char*
1243 json_object_lookup_string(
1244         const json_ctx * ctx,
1245         tok_ref          tid,
1246         const char     * key)
1247 {
1248         tid = json_object_lookup(ctx, tid, key, JSMN_STRING);
1249         if (INVALID_TOKEN != tid)
1250                 return ctx->buf + ctx->tok[tid].start;
1251         return NULL;
1252 }
1253
1254 static const char*
1255 json_object_lookup_string_default(
1256         const json_ctx * ctx,
1257         tok_ref          tid,
1258         const char     * key,
1259         const char     * def)
1260 {
1261         tid = json_object_lookup(ctx, tid, key, JSMN_STRING);
1262         if (INVALID_TOKEN != tid)
1263                 return ctx->buf + ctx->tok[tid].start;
1264         return def;
1265 }
1266
1267 /* ------------------------------------------------------------------ */
1268
1269 static json_int
1270 json_object_lookup_int(
1271         const json_ctx * ctx,
1272         tok_ref          tid,
1273         const char     * key)
1274 {
1275         json_int     ret;
1276         const char * cp;
1277         char       * ep;
1278
1279         cp = json_object_lookup_primitive(ctx, tid, key);
1280         if (NULL != cp) {
1281                 ret = strtojint(cp, &ep);
1282                 if (cp != ep && '\0' == *ep)
1283                         return ret;
1284         } else {
1285                 errno = EINVAL;
1286         }
1287         return 0;
1288 }
1289
1290 static json_int
1291 json_object_lookup_int_default(
1292         const json_ctx * ctx,
1293         tok_ref          tid,
1294         const char     * key,
1295         json_int         def)
1296 {
1297         json_int     ret;
1298         const char * cp;
1299         char       * ep;
1300
1301         cp = json_object_lookup_primitive(ctx, tid, key);
1302         if (NULL != cp) {
1303                 ret = strtojint(cp, &ep);
1304                 if (cp != ep && '\0' == *ep)
1305                         return ret;
1306         }
1307         return def;
1308 }
1309
1310 /* ------------------------------------------------------------------ */
1311 #if 0 /* currently unused */
1312 static double
1313 json_object_lookup_float(
1314         const json_ctx * ctx,
1315         tok_ref          tid,
1316         const char     * key)
1317 {
1318         double       ret;
1319         const char * cp;
1320         char       * ep;
1321
1322         cp = json_object_lookup_primitive(ctx, tid, key);
1323         if (NULL != cp) {
1324                 ret = strtod(cp, &ep);
1325                 if (cp != ep && '\0' == *ep)
1326                         return ret;
1327         } else {
1328                 errno = EINVAL;
1329         }
1330         return 0.0;
1331 }
1332 #endif
1333
1334 static double
1335 json_object_lookup_float_default(
1336         const json_ctx * ctx,
1337         tok_ref          tid,
1338         const char     * key,
1339         double           def)
1340 {
1341         double       ret;
1342         const char * cp;
1343         char       * ep;
1344
1345         cp = json_object_lookup_primitive(ctx, tid, key);
1346         if (NULL != cp) {
1347                 ret = strtod(cp, &ep);
1348                 if (cp != ep && '\0' == *ep)
1349                         return ret;
1350         }
1351         return def;
1352 }
1353
1354 /* ------------------------------------------------------------------ */
1355
1356 static BOOL
1357 json_parse_record(
1358         json_ctx * ctx,
1359         char     * buf,
1360         size_t     len)
1361 {
1362         jsmn_parser jsm;
1363         int         idx, rc;
1364
1365         jsmn_init(&jsm);
1366         rc = jsmn_parse(&jsm, buf, len, ctx->tok, JSMN_MAXTOK);
1367         if (rc <= 0)
1368                 return FALSE;
1369         ctx->buf  = buf;
1370         ctx->ntok = rc;
1371
1372         if (JSMN_OBJECT != ctx->tok[0].type)
1373                 return FALSE; /* not object!?! */
1374
1375         /* Make all tokens NUL terminated by overwriting the
1376          * terminator symbol. Makes string compares and number parsing a
1377          * lot easier!
1378          */
1379         for (idx = 0; idx < ctx->ntok; ++idx)
1380                 if (ctx->tok[idx].end > ctx->tok[idx].start)
1381                         ctx->buf[ctx->tok[idx].end] = '\0';
1382         return TRUE;
1383 }
1384
1385
1386 /* =====================================================================
1387  * static local helpers
1388  */
1389 static BOOL
1390 get_binary_time(
1391         l_fp       * const dest     ,
1392         json_ctx   * const jctx     ,
1393         const char * const time_name,
1394         const char * const frac_name,
1395         long               fscale   )
1396 {
1397         BOOL            retv = FALSE;
1398         struct timespec ts;
1399
1400         errno = 0;
1401         ts.tv_sec  = (time_t)json_object_lookup_int(jctx, 0, time_name);
1402         ts.tv_nsec = (long  )json_object_lookup_int(jctx, 0, frac_name);
1403         if (0 == errno) {
1404                 ts.tv_nsec *= fscale;
1405                 *dest = tspec_stamp_to_lfp(ts);
1406                 retv  = TRUE;
1407         }
1408         return retv;
1409 }
1410
1411 /* ------------------------------------------------------------------ */
1412 /* Process a WATCH record
1413  *
1414  * Currently this is only used to recognise that the device is present
1415  * and that we're listed subscribers.
1416  */
1417 static void
1418 process_watch(
1419         peerT      * const peer ,
1420         json_ctx   * const jctx ,
1421         const l_fp * const rtime)
1422 {
1423         clockprocT * const pp = peer->procptr;
1424         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1425
1426         const char * path;
1427
1428         path = json_object_lookup_string(jctx, 0, "device");
1429         if (NULL == path || strcmp(path, up->device))
1430                 return;
1431
1432         if (json_object_lookup_bool(jctx, 0, "enable") > 0 &&
1433             json_object_lookup_bool(jctx, 0, "json"  ) > 0  )
1434                 up->fl_watch = -1;
1435         else
1436                 up->fl_watch = 0;
1437         DPRINTF(2, ("%s: process_watch, enabled=%d\n",
1438                     up->logname, (up->fl_watch & 1)));
1439 }
1440
1441 /* ------------------------------------------------------------------ */
1442
1443 static void
1444 process_version(
1445         peerT      * const peer ,
1446         json_ctx   * const jctx ,
1447         const l_fp * const rtime)
1448 {
1449         clockprocT * const pp = peer->procptr;
1450         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1451
1452         int    len;
1453         char * buf;
1454         const char *revision;
1455         const char *release;
1456         uint16_t    pvhi, pvlo;
1457
1458         /* get protocol version number */
1459         revision = json_object_lookup_string_default(
1460                 jctx, 0, "rev", "(unknown)");
1461         release  = json_object_lookup_string_default(
1462                 jctx, 0, "release", "(unknown)");
1463         errno = 0;
1464         pvhi = (uint16_t)json_object_lookup_int(jctx, 0, "proto_major");
1465         pvlo = (uint16_t)json_object_lookup_int(jctx, 0, "proto_minor");
1466
1467         if (0 == errno) {
1468                 if ( ! up->fl_vers)
1469                         msyslog(LOG_INFO,
1470                                 "%s: GPSD revision=%s release=%s protocol=%u.%u",
1471                                 up->logname, revision, release,
1472                                 pvhi, pvlo);
1473                 up->proto_version = PROTO_VERSION(pvhi, pvlo);
1474                 up->fl_vers = -1;
1475         } else {
1476                 if (syslogok(pp, up))
1477                         msyslog(LOG_INFO,
1478                                 "%s: could not evaluate version data",
1479                                 up->logname);
1480                 return;
1481         }
1482         /* With the 3.9 GPSD protocol, '*_musec' vanished from the PPS
1483          * record and was replace by '*_nsec'.
1484          */
1485         up->pf_nsec = -(up->proto_version >= PROTO_VERSION(3,9));
1486
1487         /* With the 3.10 protocol we can get TOFF records for better
1488          * timing information.
1489          */
1490         up->pf_toff = -(up->proto_version >= PROTO_VERSION(3,10));
1491
1492         /* request watch for our GPS device if not yet watched.
1493          *
1494          * The version string is also sent as a life signal, if we have
1495          * seen useable data. So if we're already watching the device,
1496          * skip the request.
1497          *
1498          * Reuse the input buffer, which is no longer needed in the
1499          * current cycle. Also assume that we can write the watch
1500          * request in one sweep into the socket; since we do not do
1501          * output otherwise, this should always work.  (Unless the
1502          * TCP/IP window size gets lower than the length of the
1503          * request. We handle that when it happens.)
1504          */
1505         if (up->fl_watch)
1506                 return;
1507
1508         /* The logon string is actually the ?WATCH command of GPSD,
1509          * using JSON data and selecting the GPS device name we created
1510          * from our unit number. We have an old a newer version that
1511          * request PPS (and TOFF) transmission.
1512          */
1513         snprintf(up->buffer, sizeof(up->buffer),
1514                  "?WATCH={\"device\":\"%s\",\"enable\":true,\"json\":true%s};\r\n",
1515                  up->device, (up->pf_toff ? ",\"pps\":true" : ""));
1516         buf = up->buffer;
1517         len = strlen(buf);
1518         log_data(peer, "send", buf, len);
1519         if (len != write(pp->io.fd, buf, len) && (syslogok(pp, up))) {
1520                 /* Note: if the server fails to read our request, the
1521                  * resulting data timeout will take care of the
1522                  * connection!
1523                  */
1524                 msyslog(LOG_ERR, "%s: failed to write watch request (%m)",
1525                         up->logname);
1526         }
1527 }
1528
1529 /* ------------------------------------------------------------------ */
1530
1531 static void
1532 process_tpv(
1533         peerT      * const peer ,
1534         json_ctx   * const jctx ,
1535         const l_fp * const rtime)
1536 {
1537         clockprocT * const pp = peer->procptr;
1538         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1539
1540         const char * gps_time;
1541         int          gps_mode;
1542         double       ept;
1543         int          xlog2;
1544
1545         gps_mode = (int)json_object_lookup_int_default(
1546                 jctx, 0, "mode", 0);
1547
1548         gps_time = json_object_lookup_string(
1549                 jctx, 0, "time");
1550
1551         /* accept time stamps only in 2d or 3d fix */
1552         if (gps_mode < 2 || NULL == gps_time) {
1553                 /* receiver has no fix; tell about and avoid stale data */
1554                 if ( ! up->pf_toff)
1555                         ++up->tc_sti_recv;
1556                 ++up->tc_nosync;
1557                 up->fl_sti    = 0;
1558                 up->fl_pps    = 0;
1559                 up->fl_nosync = -1;
1560                 return;
1561         }
1562         up->fl_nosync = 0;
1563
1564         /* convert clock and set resulting ref time, but only if the
1565          * TOFF sentence is *not* available
1566          */
1567         if ( ! up->pf_toff) {
1568                 ++up->tc_sti_recv;
1569                 /* save last time code to clock data */
1570                 save_ltc(pp, gps_time);
1571                 /* now parse the time string */
1572                 if (convert_ascii_time(&up->sti_stamp, gps_time)) {
1573                         DPRINTF(2, ("%s: process_tpv, stamp='%s',"
1574                                     " recvt='%s' mode=%u\n",
1575                                     up->logname,
1576                                     gmprettydate(&up->sti_stamp),
1577                                     gmprettydate(&up->sti_recvt),
1578                                     gps_mode));
1579
1580                         /* have to use local receive time as substitute
1581                          * for the real receive time: TPV does not tell
1582                          * us.
1583                          */
1584                         up->sti_local = *rtime;
1585                         up->sti_recvt = *rtime;
1586                         L_SUB(&up->sti_recvt, &up->sti_fudge);
1587                         up->fl_sti = -1;
1588                 } else {
1589                         ++up->tc_breply;
1590                         up->fl_sti = 0;
1591                 }
1592         }
1593
1594         /* Set the precision from the GPSD data
1595          * Use the ETP field for an estimation of the precision of the
1596          * serial data. If ETP is not available, use the default serial
1597          * data presion instead. (Note: The PPS branch has a different
1598          * precision estimation, since it gets the proper value directly
1599          * from GPSD!)
1600          */
1601         ept = json_object_lookup_float_default(jctx, 0, "ept", 2.0e-3);
1602         ept = frexp(fabs(ept)*0.70710678, &xlog2); /* ~ sqrt(0.5) */
1603         if (ept < 0.25)
1604                 xlog2 = INT_MIN;
1605         if (ept > 2.0)
1606                 xlog2 = INT_MAX;
1607         up->sti_prec = clamped_precision(xlog2);
1608 }
1609
1610 /* ------------------------------------------------------------------ */
1611
1612 static void
1613 process_pps(
1614         peerT      * const peer ,
1615         json_ctx   * const jctx ,
1616         const l_fp * const rtime)
1617 {
1618         clockprocT * const pp = peer->procptr;
1619         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1620
1621         int xlog2;
1622
1623         ++up->tc_pps_recv;
1624
1625         /* Bail out if there's indication that time sync is bad or
1626          * if we're explicitely requested to ignore PPS data.
1627          */
1628         if (up->fl_nosync)
1629                 return;
1630
1631         up->pps_local = *rtime;
1632         /* Now grab the time values. 'clock_*' is the event time of the
1633          * pulse measured on the local system clock; 'real_*' is the GPS
1634          * reference time GPSD associated with the pulse.
1635          */
1636         if (up->pf_nsec) {
1637                 if ( ! get_binary_time(&up->pps_recvt2, jctx,
1638                                        "clock_sec", "clock_nsec", 1))
1639                         goto fail;
1640                 if ( ! get_binary_time(&up->pps_stamp2, jctx,
1641                                        "real_sec", "real_nsec", 1))
1642                         goto fail;
1643         } else {
1644                 if ( ! get_binary_time(&up->pps_recvt2, jctx,
1645                                        "clock_sec", "clock_musec", 1000))
1646                         goto fail;
1647                 if ( ! get_binary_time(&up->pps_stamp2, jctx,
1648                                        "real_sec", "real_musec", 1000))
1649                         goto fail;
1650         }
1651
1652         /* Try to read the precision field from the PPS record. If it's
1653          * not there, take the precision from the serial data.
1654          */
1655         xlog2 = json_object_lookup_int_default(
1656                         jctx, 0, "precision", up->sti_prec);
1657         up->pps_prec = clamped_precision(xlog2);
1658         
1659         /* Get fudged receive times for primary & secondary unit */
1660         up->pps_recvt = up->pps_recvt2;
1661         L_SUB(&up->pps_recvt , &up->pps_fudge );
1662         L_SUB(&up->pps_recvt2, &up->pps_fudge2);
1663         pp->lastrec = up->pps_recvt;
1664
1665         /* Map to nearest full second as reference time stamp for the
1666          * primary channel. Sanity checks are done in evaluation step.
1667          */
1668         up->pps_stamp = up->pps_recvt;
1669         L_ADDUF(&up->pps_stamp, 0x80000000u);
1670         up->pps_stamp.l_uf = 0;
1671
1672         if (NULL != up->pps_peer)
1673                 save_ltc(up->pps_peer->procptr,
1674                          gmprettydate(&up->pps_stamp2));
1675         DPRINTF(2, ("%s: PPS record processed,"
1676                     " stamp='%s', recvt='%s'\n",
1677                     up->logname,
1678                     gmprettydate(&up->pps_stamp2),
1679                     gmprettydate(&up->pps_recvt2)));
1680         
1681         up->fl_pps  = (0 != (pp->sloppyclockflag & CLK_FLAG2)) - 1;
1682         up->fl_pps2 = -1;
1683         return;
1684
1685   fail:
1686         DPRINTF(1, ("%s: PPS record processing FAILED\n",
1687                     up->logname));
1688         ++up->tc_breply;
1689 }
1690
1691 /* ------------------------------------------------------------------ */
1692
1693 static void
1694 process_toff(
1695         peerT      * const peer ,
1696         json_ctx   * const jctx ,
1697         const l_fp * const rtime)
1698 {
1699         clockprocT * const pp = peer->procptr;
1700         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1701
1702         ++up->tc_sti_recv;
1703
1704         /* remember this! */
1705         up->pf_toff = -1;
1706
1707         /* bail out if there's indication that time sync is bad */
1708         if (up->fl_nosync)
1709                 return;
1710
1711         if ( ! get_binary_time(&up->sti_recvt, jctx,
1712                                "clock_sec", "clock_nsec", 1))
1713                         goto fail;
1714         if ( ! get_binary_time(&up->sti_stamp, jctx,
1715                                "real_sec", "real_nsec", 1))
1716                         goto fail;
1717         L_SUB(&up->sti_recvt, &up->sti_fudge);
1718         up->sti_local = *rtime;
1719         up->fl_sti    = -1;
1720
1721         save_ltc(pp, gmprettydate(&up->sti_stamp));
1722         DPRINTF(2, ("%s: TOFF record processed,"
1723                     " stamp='%s', recvt='%s'\n",
1724                     up->logname,
1725                     gmprettydate(&up->sti_stamp),
1726                     gmprettydate(&up->sti_recvt)));
1727         return;
1728
1729   fail:
1730         DPRINTF(1, ("%s: TOFF record processing FAILED\n",
1731                     up->logname));
1732         ++up->tc_breply;
1733 }
1734
1735 /* ------------------------------------------------------------------ */
1736
1737 static void
1738 gpsd_parse(
1739         peerT      * const peer ,
1740         const l_fp * const rtime)
1741 {
1742         clockprocT * const pp = peer->procptr;
1743         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1744
1745         const char * clsid;
1746
1747         DPRINTF(2, ("%s: gpsd_parse: time %s '%.*s'\n",
1748                     up->logname, ulfptoa(rtime, 6),
1749                     up->buflen, up->buffer));
1750
1751         /* See if we can grab anything potentially useful. JSMN does not
1752          * need a trailing NUL, but it needs the number of bytes to
1753          * process. */
1754         if (!json_parse_record(&up->json_parse, up->buffer, up->buflen)) {
1755                 ++up->tc_breply;
1756                 return;
1757         }
1758         
1759         /* Now dispatch over the objects we know */
1760         clsid = json_object_lookup_string(&up->json_parse, 0, "class");
1761         if (NULL == clsid) {
1762                 ++up->tc_breply;
1763                 return;
1764         }
1765
1766         if      (!strcmp("TPV", clsid))
1767                 process_tpv(peer, &up->json_parse, rtime);
1768         else if (!strcmp("PPS", clsid))
1769                 process_pps(peer, &up->json_parse, rtime);
1770         else if (!strcmp("TOFF", clsid))
1771                 process_toff(peer, &up->json_parse, rtime);
1772         else if (!strcmp("VERSION", clsid))
1773                 process_version(peer, &up->json_parse, rtime);
1774         else if (!strcmp("WATCH", clsid))
1775                 process_watch(peer, &up->json_parse, rtime);
1776         else
1777                 return; /* nothing we know about... */
1778         ++up->tc_recv;
1779
1780         /* if possible, feed the PPS side channel */
1781         if (up->pps_peer)
1782                 eval_pps_secondary(
1783                         up->pps_peer, up->pps_peer->procptr, up);
1784
1785         /* check PPS vs. STI receive times:
1786          * If STI is before PPS, then clearly the STI is too old. If PPS
1787          * is before STI by more than one second, then PPS is too old.
1788          * Weed out stale time stamps & flags.
1789          */
1790         if (up->fl_pps && up->fl_sti) {
1791                 l_fp diff;
1792                 diff = up->sti_local;
1793                 L_SUB(&diff, &up->pps_local);
1794                 if (diff.l_i > 0)
1795                         up->fl_pps = 0; /* pps too old */
1796                 else if (diff.l_i < 0)
1797                         up->fl_sti = 0; /* serial data too old */
1798         }
1799
1800         /* dispatch to the mode-dependent processing functions */
1801         switch (up->mode) {
1802         default:
1803         case MODE_OP_STI:
1804                 eval_serial(peer, pp, up);
1805                 break;
1806
1807         case MODE_OP_STRICT:
1808                 eval_strict(peer, pp, up);
1809                 break;
1810
1811         case MODE_OP_AUTO:
1812                 eval_auto(peer, pp, up);
1813                 break;
1814         }
1815 }
1816
1817 /* ------------------------------------------------------------------ */
1818
1819 static void
1820 gpsd_stop_socket(
1821         peerT * const peer)
1822 {
1823         clockprocT * const pp = peer->procptr;
1824         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1825
1826         if (-1 != pp->io.fd) {
1827                 if (syslogok(pp, up))
1828                         msyslog(LOG_INFO,
1829                                 "%s: closing socket to GPSD, fd=%d",
1830                                 up->logname, pp->io.fd);
1831                 else
1832                         DPRINTF(1, ("%s: closing socket to GPSD, fd=%d\n",
1833                                     up->logname, pp->io.fd));
1834                 io_closeclock(&pp->io);
1835                 pp->io.fd = -1;
1836         }
1837         up->tickover = up->tickpres;
1838         up->tickpres = min(up->tickpres + 5, TICKOVER_HIGH);
1839         up->fl_vers  = 0;
1840         up->fl_sti   = 0;
1841         up->fl_pps   = 0;
1842         up->fl_watch = 0;
1843 }
1844
1845 /* ------------------------------------------------------------------ */
1846
1847 static void
1848 gpsd_init_socket(
1849         peerT * const peer)
1850 {
1851         clockprocT * const pp = peer->procptr;
1852         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1853         addrinfoT  * ai;
1854         int          rc;
1855         int          ov;
1856
1857         /* draw next address to try */
1858         if (NULL == up->addr)
1859                 up->addr = s_gpsd_addr;
1860         ai = up->addr;
1861         up->addr = ai->ai_next;
1862
1863         /* try to create a matching socket */
1864         up->fdt = socket(
1865                 ai->ai_family, ai->ai_socktype, ai->ai_protocol);
1866         if (-1 == up->fdt) {
1867                 if (syslogok(pp, up))
1868                         msyslog(LOG_ERR,
1869                                 "%s: cannot create GPSD socket: %m",
1870                                 up->logname);
1871                 goto no_socket;
1872         }
1873
1874         /* Make sure the socket is non-blocking. Connect/reconnect and
1875          * IO happen in an event-driven environment, and synchronous
1876          * operations wreak havoc on that.
1877          */
1878         rc = fcntl(up->fdt, F_SETFL, O_NONBLOCK, 1);
1879         if (-1 == rc) {
1880                 if (syslogok(pp, up))
1881                         msyslog(LOG_ERR,
1882                                 "%s: cannot set GPSD socket to non-blocking: %m",
1883                                 up->logname);
1884                 goto no_socket;
1885         }
1886         /* Disable nagling. The way both GPSD and NTPD handle the
1887          * protocol makes it record-oriented, and in most cases
1888          * complete records (JSON serialised objects) will be sent in
1889          * one sweep. Nagling gives not much advantage but adds another
1890          * delay, which can worsen the situation for some packets.
1891          */
1892         ov = 1;
1893         rc = setsockopt(up->fdt, IPPROTO_TCP, TCP_NODELAY,
1894                         (void *)&ov, sizeof(ov));
1895         if (-1 == rc) {
1896                 if (syslogok(pp, up))
1897                         msyslog(LOG_INFO,
1898                                 "%s: cannot disable TCP nagle: %m",
1899                                 up->logname);
1900         }
1901
1902         /* Start a non-blocking connect. There might be a synchronous
1903          * connection result we have to handle.
1904          */
1905         rc = connect(up->fdt, ai->ai_addr, ai->ai_addrlen);
1906         if (-1 == rc) {
1907                 if (errno == EINPROGRESS) {
1908                         DPRINTF(1, ("%s: async connect pending, fd=%d\n",
1909                                     up->logname, up->fdt));
1910                         return;
1911                 }
1912
1913                 if (syslogok(pp, up))
1914                         msyslog(LOG_ERR,
1915                                 "%s: cannot connect GPSD socket: %m",
1916                                 up->logname);
1917                 goto no_socket;
1918         }
1919
1920         /* We had a successful synchronous connect, so we add the
1921          * refclock processing ASAP. We still have to wait for the
1922          * version string and apply the watch command later on, but we
1923          * might as well get the show on the road now.
1924          */
1925         DPRINTF(1, ("%s: new socket connection, fd=%d\n",
1926                     up->logname, up->fdt));
1927
1928         pp->io.fd = up->fdt;
1929         up->fdt   = -1;
1930         if (0 == io_addclock(&pp->io)) {
1931                 if (syslogok(pp, up))
1932                         msyslog(LOG_ERR,
1933                                 "%s: failed to register with I/O engine",
1934                                 up->logname);
1935                 goto no_socket;
1936         }
1937
1938         return;
1939
1940   no_socket:
1941         if (-1 != pp->io.fd)
1942                 close(pp->io.fd);
1943         if (-1 != up->fdt)
1944                 close(up->fdt);
1945         pp->io.fd    = -1;
1946         up->fdt      = -1;
1947         up->tickover = up->tickpres;
1948         up->tickpres = min(up->tickpres + 5, TICKOVER_HIGH);
1949 }
1950
1951 /* ------------------------------------------------------------------ */
1952
1953 static void
1954 gpsd_test_socket(
1955         peerT * const peer)
1956 {
1957         clockprocT * const pp = peer->procptr;
1958         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
1959
1960         int       ec, rc;
1961         socklen_t lc;
1962
1963         /* Check if the non-blocking connect was finished by testing the
1964          * socket for writeability. Use the 'poll()' API if available
1965          * and 'select()' otherwise.
1966          */
1967         DPRINTF(2, ("%s: check connect, fd=%d\n",
1968                     up->logname, up->fdt));
1969
1970 #if defined(HAVE_SYS_POLL_H)
1971         {
1972                 struct pollfd pfd;
1973
1974                 pfd.events = POLLOUT;
1975                 pfd.fd     = up->fdt;
1976                 rc = poll(&pfd, 1, 0);
1977                 if (1 != rc || !(pfd.revents & POLLOUT))
1978                         return;
1979         }
1980 #elif defined(HAVE_SYS_SELECT_H)
1981         {
1982                 struct timeval tout;
1983                 fd_set         wset;
1984
1985                 memset(&tout, 0, sizeof(tout));
1986                 FD_ZERO(&wset);
1987                 FD_SET(up->fdt, &wset);
1988                 rc = select(up->fdt+1, NULL, &wset, NULL, &tout);
1989                 if (0 == rc || !(FD_ISSET(up->fdt, &wset)))
1990                         return;
1991         }
1992 #else
1993 # error Blooper! That should have been found earlier!
1994 #endif
1995
1996         /* next timeout is a full one... */
1997         up->tickover = TICKOVER_LOW;
1998
1999         /* check for socket error */
2000         ec = 0;
2001         lc = sizeof(ec);
2002         rc = getsockopt(up->fdt, SOL_SOCKET, SO_ERROR, (void *)&ec, &lc);
2003         if (-1 == rc || 0 != ec) {
2004                 const char *errtxt;
2005                 if (0 == ec)
2006                         ec = errno;
2007                 errtxt = strerror(ec);
2008                 if (syslogok(pp, up))
2009                         msyslog(LOG_ERR,
2010                                 "%s: async connect to GPSD failed,"
2011                                 " fd=%d, ec=%d(%s)",
2012                                 up->logname, up->fdt, ec, errtxt);
2013                 else
2014                         DPRINTF(1, ("%s: async connect to GPSD failed,"
2015                                 " fd=%d, ec=%d(%s)\n",
2016                                     up->logname, up->fdt, ec, errtxt));
2017                 goto no_socket;
2018         } else {
2019                 DPRINTF(1, ("%s: async connect to GPSD succeeded, fd=%d\n",
2020                             up->logname, up->fdt));
2021         }
2022
2023         /* swap socket FDs, and make sure the clock was added */
2024         pp->io.fd = up->fdt;
2025         up->fdt   = -1;
2026         if (0 == io_addclock(&pp->io)) {
2027                 if (syslogok(pp, up))
2028                         msyslog(LOG_ERR,
2029                                 "%s: failed to register with I/O engine",
2030                                 up->logname);
2031                 goto no_socket;
2032         }
2033         return;
2034
2035   no_socket:
2036         if (-1 != up->fdt) {
2037                 DPRINTF(1, ("%s: closing socket, fd=%d\n",
2038                             up->logname, up->fdt));
2039                 close(up->fdt);
2040         }
2041         up->fdt      = -1;
2042         up->tickover = up->tickpres;
2043         up->tickpres = min(up->tickpres + 5, TICKOVER_HIGH);
2044 }
2045
2046 /* =====================================================================
2047  * helper stuff
2048  */
2049
2050 /* -------------------------------------------------------------------
2051  * store a properly clamped precision value
2052  */
2053 static int16_t
2054 clamped_precision(
2055         int rawprec)
2056 {
2057         if (rawprec > 0)
2058                 rawprec = 0;
2059         if (rawprec < -32)
2060                 rawprec = -32;
2061         return (int16_t)rawprec;
2062 }
2063
2064 /* -------------------------------------------------------------------
2065  * Convert a GPSD timestamp (ISO8601 Format) to an l_fp
2066  */
2067 static BOOL
2068 convert_ascii_time(
2069         l_fp       * fp      ,
2070         const char * gps_time)
2071 {
2072         char           *ep;
2073         struct tm       gd;
2074         struct timespec ts;
2075         uint32_t        dw;
2076
2077         /* Use 'strptime' to take the brunt of the work, then parse
2078          * the fractional part manually, starting with a digit weight of
2079          * 10^8 nanoseconds.
2080          */
2081         ts.tv_nsec = 0;
2082         ep = strptime(gps_time, "%Y-%m-%dT%H:%M:%S", &gd);
2083         if (NULL == ep)
2084                 return FALSE; /* could not parse the mandatory stuff! */
2085         if (*ep == '.') {
2086                 dw = 100000000u;
2087                 while (isdigit(*(u_char*)++ep)) {
2088                         ts.tv_nsec += (*(u_char*)ep - '0') * dw;
2089                         dw /= 10u;
2090                 }
2091         }
2092         if (ep[0] != 'Z' || ep[1] != '\0')
2093                 return FALSE; /* trailing garbage */
2094
2095         /* Now convert the whole thing into a 'l_fp'. We do not use
2096          * 'mkgmtime()' since its not standard and going through the
2097          * calendar routines is not much effort, either.
2098          */
2099         ts.tv_sec = (ntpcal_tm_to_rd(&gd) - DAY_NTP_STARTS) * SECSPERDAY
2100                   + ntpcal_tm_to_daysec(&gd);
2101         *fp = tspec_intv_to_lfp(ts);
2102
2103         return TRUE;
2104 }
2105
2106 /* -------------------------------------------------------------------
2107  * Save the last timecode string, making sure it's properly truncated
2108  * if necessary and NUL terminated in any case.
2109  */
2110 static void
2111 save_ltc(
2112         clockprocT * const pp,
2113         const char * const tc)
2114 {
2115         size_t len = 0;
2116         
2117         if (tc) {
2118                 len = strlen(tc);
2119                 if (len >= sizeof(pp->a_lastcode))
2120                         len = sizeof(pp->a_lastcode) - 1;
2121                 memcpy(pp->a_lastcode, tc, len);
2122         }
2123         pp->lencode = (u_short)len;
2124         pp->a_lastcode[len] = '\0';
2125 }
2126
2127 /* -------------------------------------------------------------------
2128  * asprintf replacement... it's not available everywhere...
2129  */
2130 static int
2131 myasprintf(
2132         char      ** spp,
2133         char const * fmt,
2134         ...             )
2135 {
2136         size_t alen, plen;
2137
2138         alen = 32;
2139         *spp = NULL;
2140         do {
2141                 va_list va;
2142
2143                 alen += alen;
2144                 free(*spp);
2145                 *spp = (char*)malloc(alen);
2146                 if (NULL == *spp)
2147                         return -1;
2148
2149                 va_start(va, fmt);
2150                 plen = (size_t)vsnprintf(*spp, alen, fmt, va);
2151                 va_end(va);
2152         } while (plen >= alen);
2153
2154         return (int)plen;
2155 }
2156
2157 /* -------------------------------------------------------------------
2158  * dump a raw data buffer
2159  */
2160
2161 static char *
2162 add_string(
2163         char *dp,
2164         char *ep,
2165         const char *sp)
2166 {
2167         while (dp != ep && *sp)
2168                 *dp++ = *sp++;
2169         return dp;
2170 }
2171
2172 static void
2173 log_data(
2174         peerT      *peer,
2175         const char *what,
2176         const char *buf ,
2177         size_t      len )
2178 {
2179         /* we're running single threaded with regards to the clocks. */
2180         static char s_lbuf[2048];
2181
2182         clockprocT * const pp = peer->procptr;
2183         gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr;
2184
2185         if (debug > 1) {
2186                 const char *sptr = buf;
2187                 const char *stop = buf + len;
2188                 char       *dptr = s_lbuf;
2189                 char       *dtop = s_lbuf + sizeof(s_lbuf) - 1; /* for NUL */
2190
2191                 while (sptr != stop && dptr != dtop) {
2192                         u_char uch = (u_char)*sptr++;
2193                         if (uch == '\\') {
2194                                 dptr = add_string(dptr, dtop, "\\\\");
2195                         } else if (isprint(uch)) {
2196                                 *dptr++ = (char)uch;
2197                         } else {
2198                                 char fbuf[6];
2199                                 snprintf(fbuf, sizeof(fbuf), "\\%03o", uch);
2200                                 dptr = add_string(dptr, dtop, fbuf);
2201                         }
2202                 }
2203                 *dptr = '\0';
2204                 mprintf("%s[%s]: '%s'\n", up->logname, what, s_lbuf);
2205         }
2206 }
2207
2208 #else
2209 NONEMPTY_TRANSLATION_UNIT
2210 #endif /* REFCLOCK && CLOCK_GPSDJSON */