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
100typedef struct json_ctx {
101	char        * buf;
102	int           ntok;
103	jsmntok_t     tok[JSMN_MAXTOK];
104} json_ctx;
105
106typedef 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
112typedef signed   long long int json_int;
113typedef unsigned long long int json_uint;
114#define JSON_INT_MAX LLONG_MAX
115#define JSON_INT_MIN LLONG_MIN
116#else
117typedef signed   long int json_int;
118typedef 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 */
238typedef struct peer         peerT;
239typedef struct refclockproc clockprocT;
240typedef 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 */
246static const char * s_dev_stem = "/dev/gps";
247
248/* =====================================================================
249 * forward declarations for transfer vector and the vector itself
250 */
251
252static	void	gpsd_init	(void);
253static	int	gpsd_start	(int, peerT *);
254static	void	gpsd_shutdown	(int, peerT *);
255static	void	gpsd_receive	(struct recvbuf *);
256static	void	gpsd_poll	(int, peerT *);
257static	void	gpsd_control	(int, const struct refclockstat *,
258				 struct refclockstat *, peerT *);
259static	void	gpsd_timer	(int, peerT *);
260
261static  int     myasprintf(char**, char const*, ...) NTP_PRINTF(2, 3);
262
263static void     enter_opmode(peerT *peer, int mode);
264static void	leave_opmode(peerT *peer, int mode);
265
266struct 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 */
279struct gpsd_unit;
280typedef struct gpsd_unit gpsd_unitT;
281
282struct 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 */
363static void gpsd_init_socket(peerT * const peer);
364static void gpsd_test_socket(peerT * const peer);
365static void gpsd_stop_socket(peerT * const peer);
366
367static void gpsd_parse(peerT * const peer,
368		       const l_fp  * const rtime);
369static BOOL convert_ascii_time(l_fp * fp, const char * gps_time);
370static void save_ltc(clockprocT * const pp, const char * const tc);
371static int  syslogok(clockprocT * const pp, gpsd_unitT * const up);
372static void log_data(peerT *peer, const char *what,
373		     const char *buf, size_t len);
374static int16_t clamped_precision(int rawprec);
375
376/* =====================================================================
377 * local / static stuff
378 */
379
380static 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 */
394static addrinfoT  *s_gpsd_addr;
395static gpsd_unitT *s_clock_units;
396
397/* list of service/socket names we want to resolve against */
398static 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 */
408static int s_svcerr[sizeof(s_svctab)/sizeof(s_svctab[0])];
409static int s_svcidx;
410
411/* =====================================================================
412 * log throttling
413 */
414static int/*BOOL*/
415syslogok(
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 */
434static void
435gpsd_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 */
460static int/*BOOL*/
461gpsd_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 */
497static int
498gpsd_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
586dev_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
602static void
603gpsd_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
647static void
648gpsd_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
700static void
701poll_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
744static void
745poll_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
762static void
763gpsd_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
779static void
780gpsd_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
808static void
809timer_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
861static void
862timer_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
880static void
881gpsd_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
898static void
899enter_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
919static void
920leave_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
942static void
943add_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, 0.0);
953}
954
955/* ------------------------------------------------------------------ */
956
957static void
958eval_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 */
980static void
981eval_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
1003static void
1004eval_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/* ------------------------------------------------------------------ */
1019static void
1020eval_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 */
1072static json_int
1073strtojint(
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
1134static tok_ref
1135json_token_skip(
1136	const json_ctx * ctx,
1137	tok_ref          tid)
1138{
1139	if (tid >= 0 && 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 || tid > ctx->ntok)
1168			tid = ctx->ntok;
1169	}
1170	return tid;
1171}
1172
1173/* ------------------------------------------------------------------ */
1174
1175static int
1176json_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
1209static const char*
1210json_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 */
1225static int
1226json_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
1242static const char*
1243json_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
1254static const char*
1255json_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
1269static json_int
1270json_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
1290static json_int
1291json_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 */
1312static double
1313json_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
1334static double
1335json_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
1356static BOOL
1357json_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 */
1389static BOOL
1390get_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 */
1417static void
1418process_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
1443static void
1444process_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
1531static void
1532process_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
1612static void
1613process_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
1693static void
1694process_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
1737static void
1738gpsd_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
1819static void
1820gpsd_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
1847static void
1848gpsd_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
1953static void
1954gpsd_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 */
2053static int16_t
2054clamped_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 */
2067static BOOL
2068convert_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 */
2110static void
2111save_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 */
2130static int
2131myasprintf(
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
2161static char *
2162add_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
2172static void
2173log_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
2209NONEMPTY_TRANSLATION_UNIT
2210#endif /* REFCLOCK && CLOCK_GPSDJSON */
2211